summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTae-Young Chung <ty83.chung@samsung.com>2020-06-22 11:16:33 +0900
committerTae-Young Chung <ty83.chung@samsung.com>2020-06-22 13:32:26 +0900
commit0428f8a17e78dae97a8774a0ec42f48f85abcb88 (patch)
tree100c5b5a6d1d6f996294ead7474f31703a456339
parentf18ddd9e3e6afc1edf5d030dd32647b3eac5462b (diff)
downloadlibzint-0428f8a17e78dae97a8774a0ec42f48f85abcb88.tar.gz
libzint-0428f8a17e78dae97a8774a0ec42f48f85abcb88.tar.bz2
libzint-0428f8a17e78dae97a8774a0ec42f48f85abcb88.zip
zint is originally GPL v3 for an whole package but backend can be used as BSD-3 as The backed part of zint-code is updated to version 2.7.1 https://sourceforge.net/p/zint/code/ci/master/tree/ Change-Id: I779a9f70f93f0202affe41a7644d9e4bfb810123 Signed-off-by: Tae-Young Chung <ty83.chung@samsung.com>
-rw-r--r--backend/2of5.c377
-rw-r--r--backend/CMakeLists.txt12
-rw-r--r--backend/DEVELOPER88
-rw-r--r--backend/Makefile54
-rw-r--r--backend/Makefile.mingw40
-rw-r--r--backend/auspost.c250
-rw-r--r--backend/aztec.c1686
-rw-r--r--backend/aztec.h146
-rw-r--r--backend/bmp.c181
-rw-r--r--backend/bmp.h77
-rw-r--r--backend/channel_precalcs.h106
-rw-r--r--backend/codablock.c988
-rw-r--r--backend/code.c907
-rw-r--r--backend/code1.c1770
-rw-r--r--backend/code1.h102
-rw-r--r--backend/code128.c1926
-rw-r--r--backend/code128.h57
-rw-r--r--backend/code16k.c504
-rw-r--r--backend/code49.c361
-rw-r--r--backend/code49.h558
-rw-r--r--backend/common.c726
-rw-r--r--backend/common.h89
-rw-r--r--backend/composite.c1668
-rw-r--r--backend/composite.h67
-rw-r--r--backend/dllversion.c10
-rw-r--r--backend/dmatrix.c1342
-rw-r--r--backend/dmatrix.h248
-rw-r--r--backend/dotcode.c1569
-rw-r--r--backend/eci.c273
-rw-r--r--backend/eci.h254
-rw-r--r--backend/emf.c655
-rw-r--r--backend/emf.h223
-rw-r--r--backend/font.h2055
-rw-r--r--backend/gb18030.c2968
-rw-r--r--backend/gb18030.h49
-rw-r--r--backend/gb2312.c1624
-rw-r--r--backend/gb2312.h7471
-rw-r--r--backend/general_field.c187
-rw-r--r--backend/general_field.h47
-rw-r--r--backend/gif.c584
-rw-r--r--backend/gridmtx.c1123
-rw-r--r--backend/gridmtx.h178
-rw-r--r--backend/gs1.c924
-rw-r--r--backend/gs1.h10
-rw-r--r--backend/hanxin.c1665
-rw-r--r--backend/hanxin.h460
-rw-r--r--backend/imail.c442
-rw-r--r--backend/large.c459
-rw-r--r--backend/large.h45
-rw-r--r--backend/library.c2120
-rw-r--r--backend/libzint.rc14
-rw-r--r--backend/mailmark.c498
-rw-r--r--backend/maxicode.c736
-rw-r--r--backend/maxicode.h104
-rw-r--r--backend/maxipng.h149
-rw-r--r--backend/medical.c334
-rw-r--r--backend/ms_stdint.h235
-rw-r--r--backend/output.c114
-rw-r--r--backend/output.h47
-rw-r--r--backend/pcx.c222
-rw-r--r--backend/pcx.h77
-rw-r--r--backend/pdf417.c1327
-rw-r--r--backend/pdf417.h514
-rw-r--r--backend/plessey.c494
-rw-r--r--backend/png.c1235
-rw-r--r--backend/postal.c596
-rw-r--r--backend/ps.c1030
-rw-r--r--backend/qr.c5195
-rw-r--r--backend/qr.h392
-rw-r--r--backend/raster.c1170
-rw-r--r--backend/reedsol.c183
-rw-r--r--backend/reedsol.h16
-rw-r--r--backend/render.c792
-rw-r--r--backend/rss.c1765
-rw-r--r--backend/rss.h293
-rw-r--r--backend/sjis.c1591
-rw-r--r--backend/sjis.h6877
-rw-r--r--backend/stdint_msvc.h54
-rw-r--r--backend/svg.c248
-rw-r--r--backend/telepen.c168
-rw-r--r--backend/tif.c346
-rw-r--r--backend/tif.h88
-rw-r--r--backend/ultra.c1115
-rw-r--r--backend/upcean.c1587
-rw-r--r--backend/vector.c823
-rw-r--r--backend/zint.def27
-rw-r--r--backend/zint.h497
-rw-r--r--packaging/zint.spec6
88 files changed, 45824 insertions, 24860 deletions
diff --git a/backend/2of5.c b/backend/2of5.c
index df07f46..c3c795d 100644
--- a/backend/2of5.c
+++ b/backend/2of5.c
@@ -2,7 +2,7 @@
/*
libzint - the open source barcode library
- Copyright (C) 2008 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -28,90 +28,329 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
-#include <string.h>
#include <stdio.h>
-#include <stdlib.h>
#include "common.h"
#ifdef _MSC_VER
#include <malloc.h>
+#define inline _inline
#endif
-static const char *C25MatrixTable[10] = {"113311", "311131", "131131", "331111", "113131", "313111",
- "133111", "111331", "311311", "131311"};
+static const char *C25MatrixTable[10] = {
+ "113311", "311131", "131131", "331111", "113131", "313111",
+ "133111", "111331", "311311", "131311"
+};
-static const char *C25IndustTable[10] = {"1111313111", "3111111131", "1131111131", "3131111111", "1111311131",
- "3111311111", "1131311111", "1111113131", "3111113111", "1131113111"};
+static const char *C25IndustTable[10] = {
+ "1111313111", "3111111131", "1131111131", "3131111111", "1111311131",
+ "3111311111", "1131311111", "1111113131", "3111113111", "1131113111"
+};
-static const char *C25InterTable[10] = {"11331", "31113", "13113", "33111", "11313", "31311", "13311", "11133",
- "31131", "13131"};
+static const char *C25InterTable[10] = {
+ "11331", "31113", "13113", "33111", "11313", "31311", "13311", "11133",
+ "31131", "13131"
+};
-static inline char check_digit(unsigned int count)
-{
- return itoc((10 - (count % 10)) % 10);
+static inline char check_digit(unsigned int count) {
+ return itoc((10 - (count % 10)) % 10);
}
-int interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length)
-{ /* Code 2 of 5 Interleaved */
+/* Code 2 of 5 Standard (Code 2 of 5 Matrix) */
+INTERNAL int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) {
- int i, j, k, error_number;
- char bars[7], spaces[7], mixed[14], dest[1000];
+ int i, error_number;
+ char dest[512]; /* 6 + 80 * 6 + 6 + 1 ~ 512*/
+
+ if (length > 80) {
+ strcpy(symbol->errtxt, "301: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "302: 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 */
+ strcat(dest, "41111");
+
+ expand(symbol, dest);
+ ustrcpy(symbol->text, source);
+ return error_number;
+}
+
+/* Code 2 of 5 Industrial */
+INTERNAL int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) {
+
+ int i, error_number;
+ char dest[512]; /* 6 + 40 * 10 + 6 + 1 */
+
+ if (length > 45) {
+ strcpy(symbol->errtxt, "303: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "304: 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 */
+ strcat(dest, "31113");
+
+ expand(symbol, dest);
+ ustrcpy(symbol->text, source);
+ return error_number;
+}
+
+/* Code 2 of 5 IATA */
+INTERNAL int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) {
+ int i, error_number;
+ char dest[512]; /* 4 + 45 * 10 + 3 + 1 */
+
+ if (length > 45) {
+ strcpy(symbol->errtxt, "305: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "306: Invalid characters in data");
+ return error_number;
+ }
+
+ /* start */
+ strcpy(dest, "1111");
+
+ for (i = 0; i < length; i++) {
+ lookup(NEON, C25IndustTable, source[i], dest);
+ }
+
+ /* stop */
+ strcat(dest, "311");
+
+ expand(symbol, dest);
+ ustrcpy(symbol->text, source);
+ return error_number;
+}
+
+/* Code 2 of 5 Data Logic */
+INTERNAL int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length) {
+
+ int i, error_number;
+ char dest[512]; /* 4 + 80 * 6 + 3 + 1 */
+
+ if (length > 80) {
+ strcpy(symbol->errtxt, "307: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "308: 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 */
+ strcat(dest, "311");
+
+ expand(symbol, dest);
+ ustrcpy(symbol->text, source);
+ return error_number;
+}
+
+/* Code 2 of 5 Interleaved */
+INTERNAL int interleaved_two_of_five(struct zint_symbol *symbol, const unsigned char source[], size_t length) {
+
+ int i, j, error_number;
+ char bars[7], spaces[7], mixed[14], dest[1000];
#ifndef _MSC_VER
- unsigned char temp[length + 2];
+ unsigned char temp[length + 2];
#else
- unsigned char* temp = (unsigned char *)_alloca((length + 2) * sizeof(unsigned char));
+ 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 & 1)
- {
- 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;
+ if (length > 89) {
+ strcpy(symbol->errtxt, "309: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "310: Invalid characters in data");
+ return error_number;
+ }
+
+ ustrcpy(temp, "");
+ /* 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 & 1) {
+ ustrcpy(temp, "0");
+ length++;
+ }
+ ustrcat(temp, source);
+
+ /* start character */
+ strcpy(dest, "1111");
+
+ for (i = 0; i < (int) length; i += 2) {
+ int k = 0;
+ /* 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 */
+ for (j = 0; j <= 4; j++) {
+ mixed[k] = bars[j];
+ k++;
+ mixed[k] = spaces[j];
+ k++;
+ }
+ mixed[k] = '\0';
+ strcat(dest, mixed);
+ }
+
+ /* Stop character */
+ strcat(dest, "311");
+
+ expand(symbol, dest);
+ ustrcpy(symbol->text, temp);
+ return error_number;
+
+}
+
+/* Interleaved 2-of-5 (ITF) */
+INTERNAL int itf14(struct zint_symbol *symbol, unsigned char source[], int length) {
+ int i, error_number, zeroes;
+ unsigned int count;
+ char localstr[16];
+
+ count = 0;
+
+ if (length > 13) {
+ strcpy(symbol->errtxt, "311: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "312: Invalid character in data");
+ return error_number;
+ }
+
+ /* Add leading zeros as required */
+ zeroes = 13 - length;
+ for (i = 0; i < zeroes; i++) {
+ localstr[i] = '0';
+ }
+ ustrcpy(localstr + zeroes, source);
+
+ /* Calculate the check digit - the same method used for EAN-13 */
+ for (i = 12; i >= 0; i--) {
+ count += ctoi(localstr[i]);
+
+ if (!(i & 1)) {
+ count += 2 * ctoi(localstr[i]);
+ }
+ }
+ localstr[13] = check_digit(count);
+ localstr[14] = '\0';
+ error_number = interleaved_two_of_five(symbol, (unsigned char *) localstr, strlen(localstr));
+ ustrcpy(symbol->text, localstr);
+ return error_number;
+}
+
+/* Deutshe Post Leitcode */
+INTERNAL int dpleit(struct zint_symbol *symbol, unsigned char source[], int length) {
+ int i, error_number;
+ unsigned int count;
+ char localstr[16];
+ int zeroes;
+
+ count = 0;
+ if (length > 13) {
+ strcpy(symbol->errtxt, "313: Input wrong length");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "314: Invalid characters in data");
+ return error_number;
+ }
+
+ zeroes = 13 - length;
+ for (i = 0; i < zeroes; i++)
+ localstr[i] = '0';
+ ustrcpy(localstr + zeroes, source);
+
+ for (i = 12; i >= 0; i--) {
+ count += 4 * ctoi(localstr[i]);
+
+ if (i & 1) {
+ count += 5 * ctoi(localstr[i]);
+ }
+ }
+ localstr[13] = check_digit(count);
+ localstr[14] = '\0';
+ error_number = interleaved_two_of_five(symbol, (unsigned char *) localstr, strlen(localstr));
+ ustrcpy(symbol->text, localstr);
+ return error_number;
+}
+
+/* Deutsche Post Identcode */
+INTERNAL int dpident(struct zint_symbol *symbol, unsigned char source[], int length) {
+ int i, error_number, zeroes;
+ unsigned int count;
+ char localstr[16];
+
+ count = 0;
+ if (length > 11) {
+ strcpy(symbol->errtxt, "315: Input wrong length");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "316: Invalid characters in data");
+ return error_number;
+ }
+
+ zeroes = 11 - length;
+ for (i = 0; i < zeroes; i++)
+ localstr[i] = '0';
+ ustrcpy(localstr + zeroes, source);
+
+ for (i = 10; i >= 0; i--) {
+ count += 4 * ctoi(localstr[i]);
+ if (i & 1) {
+ count += 5 * ctoi(localstr[i]);
+ }
+ }
+ localstr[11] = check_digit(count);
+ localstr[12] = '\0';
+ error_number = interleaved_two_of_five(symbol, (unsigned char *) localstr, strlen(localstr));
+ ustrcpy(symbol->text, localstr);
+ return error_number;
}
diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt
index 64d88f1..e7baa0b 100644
--- a/backend/CMakeLists.txt
+++ b/backend/CMakeLists.txt
@@ -2,12 +2,12 @@
project(zint)
-set(zint_COMMON_SRCS common.c library.c render.c ps.c large.c reedsol.c gs1.c png.c)
-set(zint_ONEDIM_SRCS code.c code128.c 2of5.c upcean.c)
-set(zint_TWODIM_SRCS qr.c)
-set(zint_SRCS ${zint_COMMON_SRCS} ${zint_ONEDIM_SRCS} ${zint_TWODIM_SRCS} )
-
-add_definitions (-DNO_PNG)
+set(zint_COMMON_SRCS common.c library.c large.c reedsol.c gs1.c eci.c general_field.c sjis.c gb2312.c gb18030.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 mailmark.c)
+set(zint_TWODIM_SRCS code16k.c codablock.c dmatrix.c pdf417.c qr.c maxicode.c composite.c aztec.c code49.c code1.c gridmtx.c hanxin.c dotcode.c ultra.c)
+set(zint_OUTPUT_SRCS vector.c ps.c svg.c emf.c bmp.c pcx.c gif.c png.c tif.c raster.c output.c)
+set(zint_SRCS ${zint_OUTPUT_SRCS} ${zint_COMMON_SRCS} ${zint_ONEDIM_SRCS} ${zint_POSTAL_SRCS} ${zint_TWODIM_SRCS})
add_library(zint SHARED ${zint_SRCS})
diff --git a/backend/DEVELOPER b/backend/DEVELOPER
index 7db3a77..8f50755 100644
--- a/backend/DEVELOPER
+++ b/backend/DEVELOPER
@@ -13,6 +13,22 @@ Here is a guide to which bit of source code does what.
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
@@ -20,6 +36,9 @@ code128.c:
GS1-128 (UCC/EAN-128)
EAN-14
+code16k.c:
+ Code 16k
+
code.c:
Code 11
Code 39
@@ -29,9 +48,78 @@ code.c:
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
+
+dotcode.c:
+ Dot Code
+
+dm200.c:
+ Data Matrix ECC 200
+
+gridmtx.c:
+ Grid Matrix
+
+hanxin.c:
+ Han Xin Code
+
+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
+ UPNQR
+
+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
diff --git a/backend/Makefile b/backend/Makefile
deleted file mode 100644
index 2f339dd..0000000
--- a/backend/Makefile
+++ /dev/null
@@ -1,54 +0,0 @@
-# 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.4.3.0\"
-
-
-CC := gcc
-INCLUDE := -I/usr/include
-CFLAGS := -g
-
-prefix := /usr
-includedir := $(prefix)/include
-libdir := $(prefix)/lib
-DESTDIR :=
-
-COMMON:= common.c render.c png.c library.c ps.c large.c reedsol.c gs1.c svg.c
-COMMON_OBJ:= common.o render.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 pdf417.c qr.c maxicode.c composite.c aztec.c code49.c code1.c gridmtx.c
-TWODIM_OBJ:= code16k.o dmatrix.o pdf417.o qr.o maxicode.o composite.o aztec.o code49.o code1.o gridmtx.o
-LIBS:= `libpng15-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 reedsol.c pdf417.c maxicode.c rss.c common.c render.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.4.3 $(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
index 87fc946..e79a912 100644
--- a/backend/Makefile.mingw
+++ b/backend/Makefile.mingw
@@ -6,18 +6,14 @@
# make clean cleans up a previous compilation and any object or editor files
#
-ZINT_VERSION:=-DZINT_VERSION=\"2.4.3.0\"
+ZINT_VERSION:=-DZINT_VERSION=\"2.3.2\"
-CC:= gcc -m32
-LD:= ld
+CC:= gcc
AR:= ar rc
RANLIB:= ranlib
INCLUDE:= -I/mingw/include
-CFLAGS:= -O2 -fms-extensions -mms-bitfields -fno-exceptions -fomit-frame-pointer -Wall
-LDFLAGS = -Wl,--major-image-version=2 -Wl,--minor-image-version=43
-RC:= windres
-RCFLAGS:= -v -F pe-i386 --define GCC_WINDRES
+CFLAGS:= -D_WIN32 -O2 -fms-extensions -mms-bitfields -fno-exceptions -fomit-frame-pointer -Wall
prefix := /mingw
includedir := $(prefix)/include
@@ -26,11 +22,11 @@ bindir := $(prefix)/bin
DESTDIR :=
APP:=zint
DLL:=$(APP).dll
-DLLIMP:=lib$(DLL).a
STATLIB:=lib$(APP).a
-TOOLLIB:=lib$(APP).la
-COMMON_OBJ:= common.o render.o png.o library.o ps.o large.o reedsol.o gs1.o svg.o
+COMMON_OBJ:= common.o render.o png.o library.o ps.o large.o reedsol.o gs1.o svg.o \
+ hanxin.o mailmark.o dotcode.o codablock.o emf.o eci.o \
+ raster.o tif.o gif.o pcx.o bmp.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 pdf417.o qr.o maxicode.o composite.o aztec.o code49.o code1.o gridmtx.o
@@ -38,6 +34,7 @@ TWODIM_OBJ:= code16k.o dmatrix.o pdf417.o qr.o maxicode.o composite.o aztec.o co
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
@@ -48,8 +45,6 @@ endif
LIBS+= -lm
all: $(DLL) $(STATLIB)
-DLL: $(DLL)
-static: $(STATLIB)
%.lo:%.c
@echo Compiling $< ...
@@ -59,12 +54,9 @@ static: $(STATLIB)
@echo Compiling $< ...
$(CC) $(CFLAGS) $(DEFINES) $(ZINT_VERSION) -c -o $@ $<
-libzint.o: libzint.rc
- $(RC) $(RCFLAGS) -o $@ $<
-
-$(DLL):$(DLL_OBJ) libzint.o
+$(DLL):$(DLL_OBJ)
@echo Linking $@...
- $(CC) -shared -Wl,--out-implib,$(DLLIMP) $(LDFLAGS) -o $@ zint.def $(DLL_OBJ) libzint.o $(LIBS)
+ o2dll.sh -o $@ $(DLL_OBJ) $(LIBS)
$(STATLIB): $(LIB_OBJ)
@echo Linking $@...
@@ -74,20 +66,16 @@ $(STATLIB): $(LIB_OBJ)
.PHONY: install uninstall clean dist
install:
- cp -fp $(DLLIMP) $(DESTDIR)$(libdir)
- cp -fp $(STATLIB) $(DESTDIR)$(libdir)
- cp -fp $(TOOLLIB) $(DESTDIR)$(libdir)
+ cp -fp libzint.* $(DESTDIR)$(libdir)
cp -fp zint.h $(DESTDIR)$(includedir)/zint.h
- cp -fp $(DLL) $(DESTDIR)$(bindir)
+ cp -fp zint.dll $(DESTDIR)$(bindir)
uninstall:
- rm $(DESTDIR)$(libdir)/$(DLLIMP)
- rm $(DESTDIR)$(libdir)/$(STATLIB)
- rm $(DESTDIR)$(libdir)/$(TOOLLIB)
+ rm $(DESTDIR)$(libdir)/libzint.*
rm $(DESTDIR)$(includedir)/zint.h
- rm $(DESTDIR)$(bindir)/$(DLL)
+ rm $(DESTDIR)$(bindir)/zint.dll
clean:
- rm -f *.lib *.dll *.o *.a *~ *.res *.exe *.lo *.bak
+ 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 0000000..39d3414
--- /dev/null
+++ b/backend/auspost.c
@@ -0,0 +1,250 @@
+/* auspost.c - Handles Australia Post 4-State Barcode */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#define GDSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz #"
+
+static const char *AusNTable[10] = {
+ "00", "01", "02", "10", "11", "12", "20", "21", "22", "30"
+};
+
+static const 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 const 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 <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "common.h"
+#include "reedsol.h"
+#ifdef _MSC_VER
+#define inline _inline
+#endif
+
+static inline char convert_pattern(char data, int shift) {
+ return (data - '0') << shift;
+}
+
+/* Adds Reed-Solomon error correction to auspost */
+static void rs_error(char data_pattern[]) {
+ size_t reader, triple_writer = 0;
+ char triple[31];
+ unsigned char result[5];
+
+ for (reader = 2; reader < strlen(data_pattern); reader += 3, triple_writer++) {
+ triple[triple_writer] = convert_pattern(data_pattern[reader], 4)
+ + convert_pattern(data_pattern[reader + 1], 2)
+ + convert_pattern(data_pattern[reader + 2], 0);
+ }
+
+ rs_init_gf(0x43);
+ rs_init_code(4, 1);
+ rs_encode(triple_writer, (unsigned char*) triple, result);
+
+ for (reader = 4; reader > 0; reader--) {
+ strcat(data_pattern, AusBarTable[(int) result[reader - 1]]);
+ }
+ rs_free();
+}
+
+/* Handles Australia Posts's 4 State Codes */
+INTERNAL int australia_post(struct zint_symbol *symbol, unsigned char source[], int length) {
+ /* 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;
+ int writer;
+ unsigned int loopey, reader;
+ size_t h;
+
+ char data_pattern[200];
+ char fcc[3] = {0, 0, 0}, dpid[10];
+ char localstr[30];
+
+ /* Check input immediately to catch nuls */
+ error_number = is_sane(GDSET, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "404: Invalid characters in data");
+ return error_number;
+ }
+ 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, "401: Auspost input is wrong length");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "402: Invalid characters in data");
+ return error_number;
+ }
+ } else {
+ int zeroes;
+ if (length > 8) {
+ strcpy(symbol->errtxt, "403: Auspost input is too long");
+ return ZINT_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[zeroes] = '\0';
+ }
+
+ strcat(localstr, (char*) source);
+ h = strlen(localstr);
+ /* 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 == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "405: 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);
+ }
+ } else if ((h == 16) || (h == 23)) {
+ for (reader = 8; reader < h; reader++) {
+ lookup(NEON, AusNTable, localstr[reader], data_pattern);
+ }
+ }
+ }
+
+ /* Filler bar */
+ h = strlen(data_pattern);
+ switch (h) {
+ case 22:
+ case 37:
+ case 52:
+ strcat(data_pattern, "3");
+ break;
+ default:
+ break;
+ }
+
+ /* Reed Solomon error correction */
+ rs_error(data_pattern);
+
+ /* Stop character */
+ strcat(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] = 3;
+ symbol->row_height[1] = 2;
+ symbol->row_height[2] = 3;
+
+ 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 0000000..f5e88bd
--- /dev/null
+++ b/backend/aztec.c
@@ -0,0 +1,1686 @@
+/* aztec.c - Handles Aztec 2D Symbols */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2009-2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <stdio.h>
+#include <string.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+#include "common.h"
+#include "aztec.h"
+#include "reedsol.h"
+
+#define AZTEC_MAX_CAPACITY 19968 /* ISO/IEC 24778:2008 5.3 Table 1 Maximum Symbol Bit Capacity */
+#define AZTEC_BIN_CAPACITY 17940 /* Above less 169 * 12 = 2028 bits (169 = 10% of 1664 + 3) */
+
+static int AztecMap[22801];
+
+static int count_doubles(const unsigned char source[], const int posn, const size_t src_len) {
+ int c = 0;
+ int i = posn;
+ int cond = 1;
+
+ do {
+ if (((source[i] == '.') || (source[i] == ',')) && (source[i + 1] == ' ')) {
+ c++;
+ } else {
+ cond = 0;
+ }
+ i += 2;
+ } while ((i < (int) src_len) && cond);
+
+ return c;
+}
+
+static int count_cr(unsigned char source[], int posn, int length) {
+ int c = 0;
+ int i = posn;
+ int cond = 1;
+
+ do {
+ if (source[i] == 13) {
+ c++;
+ } else {
+ cond = 0;
+ }
+ i++;
+ } while ((i < length) && cond);
+
+ return c;
+}
+
+static int count_dotcomma(unsigned char source[], int posn, int length) {
+ int c = 0;
+ int i = posn;
+ int cond = 1;
+
+ do {
+ if ((source[i] == '.') || (source[i] == ',')) {
+ c++;
+ } else {
+ cond = 0;
+ }
+ i++;
+ } while ((i < length) && cond);
+
+ return c;
+}
+
+static int count_spaces(unsigned char source[], int posn, int length) {
+ int c = 0;
+ int i = posn;
+ int cond = 1;
+
+ do {
+ if (source[i] == ' ') {
+ c++;
+ } else {
+ cond = 0;
+ }
+ i++;
+ } while ((i < length) && cond);
+
+ return c;
+}
+
+static char get_next_mode(char encode_mode[], const size_t src_len, const int posn) {
+ int i = posn;
+
+ do {
+ i++;
+ } while ((i < (int) src_len) && (encode_mode[i] == encode_mode[posn]));
+ if (i >= (int) src_len) {
+ return 'E';
+ } else {
+ return encode_mode[i];
+ }
+}
+
+static int az_bin_append(const int arg, const int length, char *binary) {
+ size_t posn = strlen(binary);
+
+ if (posn + length > AZTEC_BIN_CAPACITY) {
+ return 0; /* Fail */
+ }
+ bin_append_posn(arg, length, binary, posn);
+
+ binary[posn + length] = '\0';
+
+ return 1; /* Success */
+}
+
+static int aztec_text_process(const unsigned char source[], const size_t src_len, char binary_string[], const int gs1, const int eci, const int debug) {
+
+ int i, j;
+ char current_mode;
+ int count;
+ char next_mode;
+ int reduced_length;
+ int byte_mode = 0;
+
+#ifndef _MSC_VER
+ char encode_mode[src_len + 1];
+ unsigned char reduced_source[src_len + 1];
+ char reduced_encode_mode[src_len + 1];
+#else
+ char *encode_mode = (char *) _alloca(src_len + 1);
+ unsigned char *reduced_source = (unsigned char *) _alloca(src_len + 1);
+ char *reduced_encode_mode = (char *) _alloca(src_len + 1);
+#endif
+
+ for (i = 0; i < (int) src_len; i++) {
+ if (source[i] >= 128) {
+ encode_mode[i] = 'B';
+ } else {
+ encode_mode[i] = AztecModes[(int) source[i]];
+ }
+ }
+
+ // Deal first with letter combinations which can be combined to one codeword
+ // Combinations are (CR LF) (. SP) (, SP) (: SP) in Punct mode
+ current_mode = 'U';
+ for (i = 0; i < (int) src_len - 1; i++) {
+ // Combination (CR LF) should always be in Punct mode
+ if ((source[i] == 13) && (source[i + 1] == 10)) {
+ encode_mode[i] = 'P';
+ encode_mode[i + 1] = 'P';
+ }
+
+ // Combination (: SP) should always be in Punct mode
+ if ((source[i] == ':') && (source[i + 1] == ' ')) {
+ encode_mode[i + 1] = 'P';
+ }
+
+ // Combinations (. SP) and (, SP) sometimes use fewer bits in Digit mode
+ if (((source[i] == '.') || (source[i] == ',')) && (source[i + 1] == ' ') && (encode_mode[i] == 'X')) {
+ count = count_doubles(source, i, src_len);
+ next_mode = get_next_mode(encode_mode, src_len, i);
+
+ if (current_mode == 'U') {
+ if ((next_mode == 'D') && (count <= 5)) {
+ for (j = 0; j < (2 * count); j++) {
+ encode_mode[i + j] = 'D';
+ }
+ }
+ }
+
+ if (current_mode == 'L') {
+ if ((next_mode == 'U') && (count == 1)) {
+ encode_mode[i] = 'D';
+ encode_mode[i + 1] = 'D';
+ }
+ if ((next_mode == 'D') && (count <= 4)) {
+ for (j = 0; j < (2 * count); j++) {
+ encode_mode[i + j] = 'D';
+ }
+ }
+ }
+
+ if (current_mode == 'M') {
+ if ((next_mode == 'D') && (count == 1)) {
+ encode_mode[i] = 'D';
+ encode_mode[i + 1] = 'D';
+ }
+ }
+
+ if (current_mode == 'D') {
+ if ((next_mode != 'D') && (count <= 4)) {
+ for (j = 0; j < (2 * count); j++) {
+ encode_mode[i + j] = 'D';
+ }
+ }
+ if ((next_mode == 'D') && (count <= 7)) {
+ for (j = 0; j < (2 * count); j++) {
+ encode_mode[i + j] = 'D';
+ }
+ }
+ }
+
+ // Default is Punct mode
+ if (encode_mode[i] == 'X') {
+ encode_mode[i] = 'P';
+ encode_mode[i + 1] = 'P';
+ }
+ }
+
+ if ((encode_mode[i] != 'X') && (encode_mode[i] != 'B')) {
+ current_mode = encode_mode[i];
+ }
+ }
+
+ if (debug) {
+ printf("First Pass:\n");
+ for (i = 0; i < (int) src_len; i++) {
+ printf("%c", encode_mode[i]);
+ }
+ printf("\n");
+ }
+
+ // Reduce two letter combinations to one codeword marked as [abcd] in Punct mode
+ i = 0;
+ j = 0;
+ while (i < (int) src_len) {
+ if ((source[i] == 13) && (source[i + 1] == 10)) { // CR LF
+ reduced_source[j] = 'a';
+ reduced_encode_mode[j] = encode_mode[i];
+ i += 2;
+ } else if (((source[i] == '.') && (source[i + 1] == ' ')) && (encode_mode[i] == 'P')) {
+ reduced_source[j] = 'b';
+ reduced_encode_mode[j] = encode_mode[i];
+ i += 2;
+ } else if (((source[i] == ',') && (source[i + 1] == ' ')) && (encode_mode[i] == 'P')) {
+ reduced_source[j] = 'c';
+ reduced_encode_mode[j] = encode_mode[i];
+ i += 2;
+ } else if ((source[i] == ':') && (source[i + 1] == ' ')) {
+ reduced_source[j] = 'd';
+ reduced_encode_mode[j] = encode_mode[i];
+ i += 2;
+ } else {
+ reduced_source[j] = source[i];
+ reduced_encode_mode[j] = encode_mode[i];
+ i++;
+ }
+ j++;
+ }
+
+ reduced_length = j;
+
+ current_mode = 'U';
+ for(i = 0; i < reduced_length; i++) {
+ // Resolve Carriage Return (CR) which can be Punct or Mixed mode
+ if (reduced_source[i] == 13) {
+ count = count_cr(reduced_source, i, reduced_length);
+ next_mode = get_next_mode(reduced_encode_mode, reduced_length, i);
+
+ if ((current_mode == 'U') && ((next_mode == 'U') || (next_mode == 'B')) && (count == 1)) {
+ reduced_encode_mode[i] = 'P';
+ }
+
+ if ((current_mode == 'L') && ((next_mode == 'L') || (next_mode == 'B')) && (count == 1)) {
+ reduced_encode_mode[i] = 'P';
+ }
+
+ if ((current_mode == 'P') || (next_mode == 'P')) {
+ reduced_encode_mode[i] = 'P';
+ }
+
+ if (current_mode == 'D') {
+ if (((next_mode == 'E') || (next_mode == 'U') || (next_mode == 'D') || (next_mode == 'B')) && (count <= 2)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'P';
+ }
+ }
+ if ((next_mode == 'L') && (count == 1)) {
+ reduced_encode_mode[i] = 'P';
+ }
+ }
+
+ // Default is Mixed mode
+ if (reduced_encode_mode[i] == 'X') {
+ reduced_encode_mode[i] = 'M';
+ }
+ }
+
+ // Resolve full stop and comma which can be in Punct or Digit mode
+ if ((reduced_source[i] == '.') || (reduced_source[i] == ',')) {
+ count = count_dotcomma(reduced_source, i, reduced_length);
+ next_mode = get_next_mode(reduced_encode_mode, reduced_length, i);
+
+ if (current_mode == 'U') {
+ if (((next_mode == 'U') || (next_mode == 'L') || (next_mode == 'M') || (next_mode == 'B')) && (count == 1)) {
+ reduced_encode_mode[i] = 'P';
+ }
+ }
+
+ if (current_mode == 'L') {
+ if ((next_mode == 'L') && (count <= 2)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'P';
+ }
+ }
+ if (((next_mode == 'M') || (next_mode == 'B')) && (count == 1)) {
+ reduced_encode_mode[i] = 'P';
+ }
+ }
+
+ if (current_mode == 'M') {
+ if (((next_mode == 'E') || (next_mode == 'U') || (next_mode == 'L') || (next_mode == 'M')) && (count <= 4)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'P';
+ }
+ }
+ if ((next_mode == 'B') && (count <= 2)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'P';
+ }
+ }
+ }
+
+ if ((current_mode == 'P') && (next_mode != 'D') && (count <= 9)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'P';
+ }
+ }
+
+ // Default is Digit mode
+ if (reduced_encode_mode[i] == 'X') {
+ reduced_encode_mode[i] = 'D';
+ }
+ }
+
+ // Resolve Space (SP) which can be any mode except Punct
+ if (reduced_source[i] == ' ') {
+ count = count_spaces(reduced_source, i, reduced_length);
+ next_mode = get_next_mode(reduced_encode_mode, reduced_length, i);
+
+ if (current_mode == 'U') {
+ if ((next_mode == 'E') && (count <= 5)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'U';
+ }
+ }
+ if (((next_mode == 'U') || (next_mode == 'L') || (next_mode == 'M') || (next_mode == 'P') || (next_mode == 'B')) && (count <= 9)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'U';
+ }
+ }
+ }
+
+ if (current_mode == 'L') {
+ if ((next_mode == 'E') && (count <= 5)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'L';
+ }
+ }
+ if ((next_mode == 'U') && (count == 1)) {
+ reduced_encode_mode[i] = 'L';
+ }
+ if ((next_mode == 'L') && (count <= 14)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'L';
+ }
+ }
+ if (((next_mode == 'M') || (next_mode == 'P') || (next_mode == 'B')) && (count <= 9)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'L';
+ }
+ }
+ }
+
+ if (current_mode == 'M') {
+ if (((next_mode == 'E') || (next_mode == 'U')) && (count <= 9)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'M';
+ }
+ }
+
+ if (((next_mode == 'L') || (next_mode == 'B')) && (count <= 14)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'M';
+ }
+ }
+
+ if (((next_mode == 'M') || (next_mode == 'P')) && (count <= 19)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'M';
+ }
+ }
+ }
+
+ if (current_mode == 'P') {
+ if ((next_mode == 'E') && (count <= 5)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'U';
+ }
+ }
+
+ if (((next_mode == 'U') || (next_mode == 'L') || (next_mode == 'M') || (next_mode == 'P') || (next_mode == 'B')) && (count <= 9)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'U';
+ }
+ }
+ }
+
+ // Default is Digit mode
+ if (reduced_encode_mode[i] == 'X') {
+ reduced_encode_mode[i] = 'D';
+ }
+ }
+
+ if (reduced_encode_mode[i] != 'B') {
+ current_mode = reduced_encode_mode[i];
+ }
+ }
+
+ // Decide when to use P/S instead of P/L and U/S instead of U/L
+ current_mode = 'U';
+ for(i = 0; i < reduced_length; i++) {
+
+ if (reduced_encode_mode[i] != current_mode) {
+
+ for (count = 0; ((i + count) < reduced_length) && (reduced_encode_mode[i + count] == reduced_encode_mode[i]); count++);
+ next_mode = get_next_mode(reduced_encode_mode, reduced_length, i);
+
+ if (reduced_encode_mode[i] == 'P') {
+ if ((current_mode == 'U') && (count <= 2)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'p';
+ }
+ }
+
+ if ((current_mode == 'L') && (next_mode != 'U') && (count <= 2)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'p';
+ }
+ }
+
+ if ((current_mode == 'L') && (next_mode == 'U') && (count == 1)) {
+ reduced_encode_mode[i] = 'p';
+ }
+
+ if ((current_mode == 'M') && (next_mode != 'M') && (count == 1)) {
+ reduced_encode_mode[i] = 'p';
+ }
+
+ if ((current_mode == 'M') && (next_mode == 'M') && (count <= 2)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'p';
+ }
+ }
+
+ if ((current_mode == 'D') && (next_mode != 'D') && (count <= 3)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'p';
+ }
+ }
+
+ if ((current_mode == 'D') && (next_mode == 'D') && (count <= 6)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'p';
+ }
+ }
+ }
+
+ if (reduced_encode_mode[i] == 'U') {
+ if ((current_mode == 'L') && ((next_mode == 'L') || (next_mode == 'M')) && (count <= 2)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'u';
+ }
+ }
+
+ if ((current_mode == 'L') && ((next_mode == 'E') || (next_mode == 'D') || (next_mode == 'B') || (next_mode == 'P')) && (count == 1)) {
+ reduced_encode_mode[i] = 'u';
+ }
+
+ if ((current_mode == 'D') && (next_mode == 'D') && (count == 1)) {
+ reduced_encode_mode[i] = 'u';
+ }
+
+ if ((current_mode == 'D') && (next_mode == 'P') && (count <= 2)) {
+ for (j = 0; j < count; j++) {
+ reduced_encode_mode[i + j] = 'u';
+ }
+ }
+ }
+ }
+
+ if ((reduced_encode_mode[i] != 'p') && (reduced_encode_mode[i] != 'u') && (reduced_encode_mode[i] != 'B')) {
+ current_mode = reduced_encode_mode[i];
+ }
+ }
+
+ if (debug) {
+ for (i = 0; i < reduced_length; i++) {
+ printf("%c", reduced_source[i]);
+ }
+ printf("\n");
+ for (i = 0; i < reduced_length; i++) {
+ printf("%c", reduced_encode_mode[i]);
+ }
+ printf("\n");
+ }
+
+ strcpy(binary_string, "");
+
+ if (gs1) {
+ bin_append(0, 5, binary_string); // P/S
+ bin_append(0, 5, binary_string); // FLG(n)
+ bin_append(0, 3, binary_string); // FLG(0)
+ }
+
+ if (eci != 0) {
+ bin_append(0, 5, binary_string); // P/S
+ bin_append(0, 5, binary_string); // FLG(n)
+ if (eci < 10) {
+ bin_append(1, 3, binary_string); // FLG(1)
+ bin_append(2 + eci, 4, binary_string);
+ }
+ if ((eci >= 10) && (eci <= 99)) {
+ bin_append(2, 3, binary_string); // FLG(2)
+ bin_append(2 + (eci / 10), 4, binary_string);
+ bin_append(2 + (eci % 10), 4, binary_string);
+ }
+ if ((eci >= 100) && (eci <= 999)) {
+ bin_append(3, 3, binary_string); // FLG(3)
+ bin_append(2 + (eci / 100), 4, binary_string);
+ bin_append(2 + ((eci % 100) / 10), 4, binary_string);
+ bin_append(2 + (eci % 10), 4, binary_string);
+ }
+ if ((eci >= 1000) && (eci <= 9999)) {
+ bin_append(4, 3, binary_string); // FLG(4)
+ bin_append(2 + (eci / 1000), 4, binary_string);
+ bin_append(2 + ((eci % 1000) / 100), 4, binary_string);
+ bin_append(2 + ((eci % 100) / 10), 4, binary_string);
+ bin_append(2 + (eci % 10), 4, binary_string);
+ }
+ if ((eci >= 10000) && (eci <= 99999)) {
+ bin_append(5, 3, binary_string); // FLG(5)
+ bin_append(2 + (eci / 10000), 4, binary_string);
+ bin_append(2 + ((eci % 10000) / 1000), 4, binary_string);
+ bin_append(2 + ((eci % 1000) / 100), 4, binary_string);
+ bin_append(2 + ((eci % 100) / 10), 4, binary_string);
+ bin_append(2 + (eci % 10), 4, binary_string);
+ }
+ if (eci >= 100000) {
+ bin_append(6, 3, binary_string); // FLG(6)
+ bin_append(2 + (eci / 100000), 4, binary_string);
+ bin_append(2 + ((eci % 100000) / 10000), 4, binary_string);
+ bin_append(2 + ((eci % 10000) / 1000), 4, binary_string);
+ bin_append(2 + ((eci % 1000) / 100), 4, binary_string);
+ bin_append(2 + ((eci % 100) / 10), 4, binary_string);
+ bin_append(2 + (eci % 10), 4, binary_string);
+ }
+ }
+
+ current_mode = 'U';
+ for (i = 0; i < reduced_length; i++) {
+
+ if (reduced_encode_mode[i] != 'B') {
+ byte_mode = 0;
+ }
+
+ if ((reduced_encode_mode[i] != current_mode) && (!byte_mode)) {
+ // Change mode
+ if (current_mode == 'U') {
+ switch (reduced_encode_mode[i]) {
+ case 'L':
+ if (!az_bin_append(28, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // L/L
+ break;
+ case 'M':
+ if (!az_bin_append(29, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // M/L
+ break;
+ case 'P':
+ if (!az_bin_append(29, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // M/L
+ if (!az_bin_append(30, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // P/L
+ break;
+ case 'p':
+ if (!az_bin_append(0, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // P/S
+ break;
+ case 'D':
+ if (!az_bin_append(30, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // D/L
+ break;
+ case 'B':
+ if (!az_bin_append(31, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // B/S
+ break;
+ }
+ }
+
+ if (current_mode == 'L') {
+ switch (reduced_encode_mode[i]) {
+ case 'U':
+ if (!az_bin_append(30, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // D/L
+ if (!az_bin_append(14, 4, binary_string)) return ZINT_ERROR_TOO_LONG; // U/L
+ break;
+ case 'u':
+ if (!az_bin_append(28, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // U/S
+ break;
+ case 'M':
+ if (!az_bin_append(29, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // M/L
+ break;
+ case 'P':
+ if (!az_bin_append(29, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // M/L
+ if (!az_bin_append(30, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // P/L
+ break;
+ case 'p':
+ if (!az_bin_append(0, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // P/S
+ break;
+ case 'D':
+ if (!az_bin_append(30, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // D/L
+ break;
+ case 'B':
+ if (!az_bin_append(31, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // B/S
+ break;
+ }
+ }
+
+ if (current_mode == 'M') {
+ switch (reduced_encode_mode[i]) {
+ case 'U':
+ if (!az_bin_append(29, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // U/L
+ break;
+ case 'L':
+ if (!az_bin_append(28, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // L/L
+ break;
+ case 'P':
+ if (!az_bin_append(30, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // P/L
+ break;
+ case 'p':
+ if (!az_bin_append(0, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // P/S
+ break;
+ case 'D':
+ if (!az_bin_append(29, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // U/L
+ if (!az_bin_append(30, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // D/L
+ break;
+ case 'B':
+ if (!az_bin_append(31, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // B/S
+ break;
+ }
+ }
+
+ if (current_mode == 'P') {
+ switch (reduced_encode_mode[i]) {
+ case 'U':
+ if (!az_bin_append(31, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // U/L
+ break;
+ case 'L':
+ if (!az_bin_append(31, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // U/L
+ if (!az_bin_append(28, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // L/L
+ break;
+ case 'M':
+ if (!az_bin_append(31, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // U/L
+ if (!az_bin_append(29, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // M/L
+ break;
+ case 'D':
+ if (!az_bin_append(31, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // U/L
+ if (!az_bin_append(30, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // D/L
+ break;
+ case 'B':
+ if (!az_bin_append(31, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // U/L
+ current_mode = 'U';
+ if (!az_bin_append(31, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // B/S
+ break;
+ }
+ }
+
+ if (current_mode == 'D') {
+ switch (reduced_encode_mode[i]) {
+ case 'U':
+ if (!az_bin_append(14, 4, binary_string)) return ZINT_ERROR_TOO_LONG; // U/L
+ break;
+ case 'u':
+ if (!az_bin_append(15, 4, binary_string)) return ZINT_ERROR_TOO_LONG; // U/S
+ break;
+ case 'L':
+ if (!az_bin_append(14, 4, binary_string)) return ZINT_ERROR_TOO_LONG; // U/L
+ if (!az_bin_append(28, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // L/L
+ break;
+ case 'M':
+ if (!az_bin_append(14, 4, binary_string)) return ZINT_ERROR_TOO_LONG; // U/L
+ if (!az_bin_append(29, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // M/L
+ break;
+ case 'P':
+ if (!az_bin_append(14, 4, binary_string)) return ZINT_ERROR_TOO_LONG; // U/L
+ if (!az_bin_append(29, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // M/L
+ if (!az_bin_append(30, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // P/L
+ break;
+ case 'p':
+ if (!az_bin_append(0, 4, binary_string)) return ZINT_ERROR_TOO_LONG; // P/S
+ break;
+ case 'B':
+ if (!az_bin_append(14, 4, binary_string)) return ZINT_ERROR_TOO_LONG; // U/L
+ current_mode = 'U';
+ if (!az_bin_append(31, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // B/S
+ break;
+ }
+ }
+
+ // Byte mode length descriptor
+ if ((reduced_encode_mode[i] == 'B') && (!byte_mode)) {
+ for (count = 0; ((i + count) < reduced_length) && (reduced_encode_mode[i + count] == 'B'); count++);
+
+ if (count > 2079) {
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ if (count > 31) {
+ /* Put 00000 followed by 11-bit number of bytes less 31 */
+ if (!az_bin_append(0, 5, binary_string)) return ZINT_ERROR_TOO_LONG;
+ if (!az_bin_append(count - 31, 11, binary_string)) return ZINT_ERROR_TOO_LONG;
+ } else {
+ /* Put 5-bit number of bytes */
+ if (!az_bin_append(count, 5, binary_string)) return ZINT_ERROR_TOO_LONG;
+ }
+ byte_mode = 1;
+ }
+
+ if ((reduced_encode_mode[i] != 'B') && (reduced_encode_mode[i] != 'u') && (reduced_encode_mode[i] != 'p')) {
+ current_mode = reduced_encode_mode[i];
+ }
+ }
+
+ if ((reduced_encode_mode[i] == 'U') || (reduced_encode_mode[i] == 'u')) {
+ if (reduced_source[i] == ' ') {
+ if (!az_bin_append(1, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // SP
+ } else {
+ if (!az_bin_append(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string)) return ZINT_ERROR_TOO_LONG;
+ }
+ }
+
+ if (reduced_encode_mode[i] == 'L') {
+ if (reduced_source[i] == ' ') {
+ if (!az_bin_append(1, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // SP
+ } else {
+ if (!az_bin_append(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string)) return ZINT_ERROR_TOO_LONG;
+ }
+ }
+
+ if (reduced_encode_mode[i] == 'M') {
+ if (reduced_source[i] == ' ') {
+ if (!az_bin_append(1, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // SP
+ } else if (reduced_source[i] == 13) {
+ if (!az_bin_append(14, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // CR
+ } else {
+ if (!az_bin_append(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string)) return ZINT_ERROR_TOO_LONG;
+ }
+ }
+
+ if ((reduced_encode_mode[i] == 'P') || (reduced_encode_mode[i] == 'p')) {
+ if (gs1 && (reduced_source[i] == '[')) {
+ if (!az_bin_append(0, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // FLG(n)
+ if (!az_bin_append(0, 3, binary_string)) return ZINT_ERROR_TOO_LONG; // FLG(0) = FNC1
+ } else if (reduced_source[i] == 13) {
+ if (!az_bin_append(1, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // CR
+ } else if (reduced_source[i] == 'a') {
+ if (!az_bin_append(2, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // CR LF
+ } else if (reduced_source[i] == 'b') {
+ if (!az_bin_append(3, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // . SP
+ } else if (reduced_source[i] == 'c') {
+ if (!az_bin_append(4, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // , SP
+ } else if (reduced_source[i] == 'd') {
+ if (!az_bin_append(5, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // : SP
+ } else if (reduced_source[i] == ',') {
+ if (!az_bin_append(17, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // Comma
+ } else if (reduced_source[i] == '.') {
+ if (!az_bin_append(19, 5, binary_string)) return ZINT_ERROR_TOO_LONG; // Full stop
+ } else {
+ if (!az_bin_append(AztecSymbolChar[(int) reduced_source[i]], 5, binary_string)) return ZINT_ERROR_TOO_LONG;
+ }
+ }
+
+ if (reduced_encode_mode[i] == 'D') {
+ if (reduced_source[i] == ' ') {
+ if (!az_bin_append(1, 4, binary_string)) return ZINT_ERROR_TOO_LONG; // SP
+ } else if (reduced_source[i] == ',') {
+ if (!az_bin_append(12, 4, binary_string)) return ZINT_ERROR_TOO_LONG; // Comma
+ } else if (reduced_source[i] == '.') {
+ if (!az_bin_append(13, 4, binary_string)) return ZINT_ERROR_TOO_LONG; // Full stop
+ } else {
+ if (!az_bin_append(AztecSymbolChar[(int) reduced_source[i]], 4, binary_string)) return ZINT_ERROR_TOO_LONG;
+ }
+ }
+
+ if (reduced_encode_mode[i] == 'B') {
+ if (!az_bin_append(reduced_source[i], 8, binary_string)) return ZINT_ERROR_TOO_LONG;
+ }
+ }
+
+ if (debug) {
+ printf("Binary String:\n");
+ printf("%s\n", binary_string);
+ }
+
+ return 0;
+}
+
+/* Prevent data from obscuring reference grid */
+static int avoidReferenceGrid(int output) {
+
+ if (output > 10) {
+ output++;
+ }
+ if (output > 26) {
+ output++;
+ }
+ if (output > 42) {
+ output++;
+ }
+ if (output > 58) {
+ output++;
+ }
+ if (output > 74) {
+ output++;
+ }
+ if (output > 90) {
+ output++;
+ }
+ if (output > 106) {
+ output++;
+ }
+ if (output > 122) {
+ output++;
+ }
+ if (output > 138) {
+ output++;
+ }
+
+ return output;
+}
+
+/* Calculate the position of the bits in the grid */
+static void populate_map() {
+ int layer, n, i;
+ int x, y;
+
+ for (x = 0; x < 151; x++) {
+ for (y = 0; y < 151; y++) {
+ AztecMap[(x * 151) + y] = 0;
+ }
+ }
+
+ for (layer = 1; layer < 33; layer++) {
+ const int start = (112 * (layer - 1)) + (16 * (layer - 1) * (layer - 1)) + 2;
+ const int length = 28 + ((layer - 1) * 4) + (layer * 4);
+ /* Top */
+ i = 0;
+ x = 64 - ((layer - 1) * 2);
+ y = 63 - ((layer - 1) * 2);
+ for (n = start; n < (start + length); n += 2) {
+ AztecMap[(avoidReferenceGrid(y) * 151) + avoidReferenceGrid(x + i)] = n;
+ AztecMap[(avoidReferenceGrid(y - 1) * 151) + avoidReferenceGrid(x + i)] = n + 1;
+ i++;
+ }
+ /* Right */
+ i = 0;
+ x = 78 + ((layer - 1) * 2);
+ y = 64 - ((layer - 1) * 2);
+ for (n = start + length; n < (start + (length * 2)); n += 2) {
+ AztecMap[(avoidReferenceGrid(y + i) * 151) + avoidReferenceGrid(x)] = n;
+ AztecMap[(avoidReferenceGrid(y + i) * 151) + avoidReferenceGrid(x + 1)] = n + 1;
+ i++;
+ }
+ /* Bottom */
+ i = 0;
+ x = 77 + ((layer - 1) * 2);
+ y = 78 + ((layer - 1) * 2);
+ for (n = start + (length * 2); n < (start + (length * 3)); n += 2) {
+ AztecMap[(avoidReferenceGrid(y) * 151) + avoidReferenceGrid(x - i)] = n;
+ AztecMap[(avoidReferenceGrid(y + 1) * 151) + avoidReferenceGrid(x - i)] = n + 1;
+ i++;
+ }
+ /* Left */
+ i = 0;
+ x = 63 - ((layer - 1) * 2);
+ y = 77 + ((layer - 1) * 2);
+ for (n = start + (length * 3); n < (start + (length * 4)); n += 2) {
+ AztecMap[(avoidReferenceGrid(y - i) * 151) + avoidReferenceGrid(x)] = n;
+ AztecMap[(avoidReferenceGrid(y - i) * 151) + avoidReferenceGrid(x - 1)] = n + 1;
+ i++;
+ }
+ }
+
+ /* Central finder pattern */
+ for (y = 69; y <= 81; y++) {
+ for (x = 69; x <= 81; x++) {
+ AztecMap[(x * 151) + y] = 1;
+ }
+ }
+ for (y = 70; y <= 80; y++) {
+ for (x = 70; x <= 80; x++) {
+ AztecMap[(x * 151) + y] = 0;
+ }
+ }
+ for (y = 71; y <= 79; y++) {
+ for (x = 71; x <= 79; x++) {
+ AztecMap[(x * 151) + y] = 1;
+ }
+ }
+ for (y = 72; y <= 78; y++) {
+ for (x = 72; x <= 78; x++) {
+ AztecMap[(x * 151) + y] = 0;
+ }
+ }
+ for (y = 73; y <= 77; y++) {
+ for (x = 73; x <= 77; x++) {
+ AztecMap[(x * 151) + y] = 1;
+ }
+ }
+ for (y = 74; y <= 76; y++) {
+ for (x = 74; x <= 76; x++) {
+ AztecMap[(x * 151) + y] = 0;
+ }
+ }
+
+ /* Guide bars */
+ for (y = 11; y < 151; y += 16) {
+ for (x = 1; x < 151; x += 2) {
+ AztecMap[(x * 151) + y] = 1;
+ AztecMap[(y * 151) + x] = 1;
+ }
+ }
+
+ /* Descriptor */
+ for (i = 0; i < 10; i++) {
+ /* Top */
+ AztecMap[(avoidReferenceGrid(64) * 151) + avoidReferenceGrid(66 + i)] = 20000 + i;
+ }
+ for (i = 0; i < 10; i++) {
+ /* Right */
+ AztecMap[(avoidReferenceGrid(66 + i) * 151) + avoidReferenceGrid(77)] = 20010 + i;
+ }
+ for (i = 0; i < 10; i++) {
+ /* Bottom */
+ AztecMap[(avoidReferenceGrid(77) * 151) + avoidReferenceGrid(75 - i)] = 20020 + i;
+ }
+ for (i = 0; i < 10; i++) {
+ /* Left */
+ AztecMap[(avoidReferenceGrid(75 - i) * 151) + avoidReferenceGrid(64)] = 20030 + i;
+ }
+
+ /* Orientation */
+ AztecMap[(avoidReferenceGrid(64) * 151) + avoidReferenceGrid(64)] = 1;
+ AztecMap[(avoidReferenceGrid(65) * 151) + avoidReferenceGrid(64)] = 1;
+ AztecMap[(avoidReferenceGrid(64) * 151) + avoidReferenceGrid(65)] = 1;
+ AztecMap[(avoidReferenceGrid(64) * 151) + avoidReferenceGrid(77)] = 1;
+ AztecMap[(avoidReferenceGrid(65) * 151) + avoidReferenceGrid(77)] = 1;
+ AztecMap[(avoidReferenceGrid(76) * 151) + avoidReferenceGrid(77)] = 1;
+}
+
+INTERNAL int aztec(struct zint_symbol *symbol, unsigned char source[], const size_t length) {
+ int x, y, i, j, p, data_blocks, ecc_blocks, layers, total_bits;
+ char binary_string[AZTEC_BIN_CAPACITY + 1], bit_pattern[20045], descriptor[42];
+ char adjusted_string[AZTEC_MAX_CAPACITY + 1];
+ 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 = (symbol->debug & ZINT_DEBUG_PRINT), reader = 0;
+ int comp_loop = 4;
+
+#ifdef _MSC_VER
+ unsigned int* data_part;
+ unsigned int* ecc_part;
+#endif
+
+ memset(binary_string, 0, AZTEC_BIN_CAPACITY + 1);
+ memset(adjusted_string, 0, AZTEC_MAX_CAPACITY + 1);
+
+ if ((symbol->input_mode & 0x07) == GS1_MODE) {
+ gs1 = 1;
+ } else {
+ gs1 = 0;
+ }
+ if (symbol->output_options & READER_INIT) {
+ reader = 1;
+ comp_loop = 1;
+ }
+ if (gs1 && reader) {
+ strcpy(symbol->errtxt, "501: Cannot encode in GS1 and Reader Initialisation mode at the same time");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ populate_map();
+
+ err_code = aztec_text_process(source, length, binary_string, gs1, symbol->eci, symbol->debug);
+
+ if (err_code != 0) {
+ strcpy(symbol->errtxt, "502: Input too long or too many extended ASCII characters");
+ return err_code;
+ }
+
+ if (!((symbol->option_1 >= -1) && (symbol->option_1 <= 4))) {
+ strcpy(symbol->errtxt, "503: Invalid error correction level - using default instead");
+ err_code = ZINT_WARN_INVALID_OPTION;
+ symbol->option_1 = -1;
+ }
+
+ ecc_level = symbol->option_1;
+
+ if ((ecc_level == -1) || (ecc_level == 0)) {
+ ecc_level = 2;
+ }
+
+ data_length = (int) 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, "504: Input too long (too many bits for selected ECC)");
+ return ZINT_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;
+ count = 0;
+ for (i = 0; i < data_length; i++) {
+
+ if ((j + 1) % codeword_size == 0) {
+ // Last bit of codeword
+ /* 7.3.1.2 "whenever the first B-1 bits ... are all “0â€s, then a dummy “1†is inserted..."
+ * "Similarly a message codeword that starts with B-1 “1â€s has a dummy “0†inserted..." */
+
+ if (count == (codeword_size - 1)) {
+ // Codeword of B-1 '1's
+ adjusted_string[j] = '0';
+ j++;
+ }
+
+ if (count == 0) {
+ // Codeword of B-1 '0's
+ adjusted_string[j] = '1';
+ j++;
+ }
+
+ count = 0;
+ } else if (binary_string[i] == '1') { /* Skip B so only counting B-1 */
+ count++;
+ }
+
+ adjusted_string[j] = binary_string[i];
+ j++;
+ }
+ adjusted_string[j] = '\0';
+ adjusted_length = j;
+ 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++) {
+ strcat(adjusted_string, "1");
+ }
+ adjusted_length = (int) 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(" ");
+ }
+ 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, "510: Invalid Aztec Code size");
+ return ZINT_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;
+ count = 0;
+ for (i = 0; i < data_length; i++) {
+
+ if ((j + 1) % codeword_size == 0) {
+ // Last bit of codeword
+
+ if (count == (codeword_size - 1)) {
+ // Codeword of B-1 '1's
+ adjusted_string[j] = '0';
+ j++;
+ }
+
+ if (count == 0) {
+ // Codeword of B-1 '0's
+ adjusted_string[j] = '1';
+ j++;
+ }
+
+ count = 0;
+ } else if (binary_string[i] == '1') { /* Skip B so only counting B-1 */
+ count++;
+ }
+
+ adjusted_string[j] = binary_string[i];
+ j++;
+ }
+ adjusted_string[j] = '\0';
+ adjusted_length = j;
+
+ remainder = adjusted_length % codeword_size;
+
+ padbits = codeword_size - remainder;
+ if (padbits == codeword_size) {
+ padbits = 0;
+ }
+
+ for (i = 0; i < padbits; i++) {
+ strcat(adjusted_string, "1");
+ }
+ adjusted_length = (int) 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, "505: Data too long for specified Aztec Code symbol size");
+ return ZINT_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(" ");
+ }
+ printf("\n");
+ }
+
+ }
+
+ if (reader && (layers > 22)) {
+ strcpy(symbol->errtxt, "506: Data too long for reader initialisation symbol");
+ return ZINT_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
+ data_part = (unsigned int*) _alloca((data_blocks + 3) * sizeof (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-solomon error correction codes */
+ for (i = 0; i < data_blocks; i++) {
+ for (p = 0; p < codeword_size; p++) {
+ if (adjusted_string[i * codeword_size + p] == '1') {
+ data_part[i] += 0x01 << (codeword_size - (p + 1));
+ }
+ }
+ }
+
+ switch (codeword_size) {
+ case 6:
+ rs_init_gf(0x43);
+ break;
+ case 8:
+ rs_init_gf(0x12d);
+ break;
+ case 10:
+ rs_init_gf(0x409);
+ break;
+ case 12:
+ rs_init_gf(0x1069);
+ break;
+ }
+
+ rs_init_code(ecc_blocks, 1);
+ rs_encode_long(data_blocks, data_part, ecc_part);
+ for (i = (ecc_blocks - 1); i >= 0; i--) {
+ bin_append(ecc_part[i], codeword_size, adjusted_string);
+ }
+ rs_free();
+
+ /* 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';
+ }
+ }
+
+ for (i = 3; i < 8; i++) {
+ if ((data_blocks - 1) & (0x10 >> (i - 3))) {
+ descriptor[i] = '1';
+ } else {
+ descriptor[i] = '0';
+ }
+ }
+
+ descriptor[8] = '\0';
+ if (debug) printf("Mode Message = %s\n", descriptor);
+ } else {
+ /* The first 5 bits represent the number of layers minus 1 */
+ for (i = 0; i < 5; i++) {
+ if ((layers - 1) & (0x10 >> i)) {
+ descriptor[i] = '1';
+ } else {
+ descriptor[i] = '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';
+ }
+ }
+ for (i = 6; i < 16; i++) {
+ if ((data_blocks - 1) & (0x200 >> (i - 6))) {
+ descriptor[i] = '1';
+ } else {
+ descriptor[i] = '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;
+}
+
+/* Encodes Aztec runes as specified in ISO/IEC 24778:2008 Annex A */
+INTERNAL 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, "507: Input too large");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number != 0) {
+ strcpy(symbol->errtxt, "508: Invalid characters in input");
+ return ZINT_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, "509: Input too large");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ strcpy(binary_string, "");
+ bin_append(input_value, 8, binary_string);
+
+ 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;
+}
diff --git a/backend/aztec.h b/backend/aztec.h
new file mode 100644
index 0000000..69b55fc
--- /dev/null
+++ b/backend/aztec.h
@@ -0,0 +1,146 @@
+/* aztec.c - Handles Aztec Mesa 2D Symbols */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+
+#define UPPER 1
+#define LOWER 2
+#define MIXED 4
+#define PUNC 8
+#define DIGIT 16
+#define BINARY 32
+
+static const unsigned short 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
+};
+
+static const char AztecSymbolChar[128] = {
+ /* From Table 2 */
+ 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 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, 0, 18, 0, 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
+};
+
+static const char AztecModes[129] = "BMMMMMMMMMMMMXBBBBBBBBBBBBBMMMMMXPPPPPPPPPPPXPXPDDDDDDDDDDPPPPPPMUUUUUUUUUUUUUUUUUUUUUUUUUUPMPMMMLLLLLLLLLLLLLLLLLLLLLLLLLLPMPMM";
+
+static const unsigned short 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 const int AztecCompactSizes[4] = {
+ 17, 40, 51, 76
+};
+
+static const unsigned short 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 const unsigned short 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 const unsigned short 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 const unsigned short 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 const unsigned short int AztecCompact10DataSizes [4] = {
+ 78, 198, 336, 520
+};
+
+static const unsigned short int AztecCompact23DataSizes [4] = {
+ 66, 168, 288, 440
+};
+
+static const unsigned short int AztecCompact36DataSizes [4] = {
+ 48, 138, 232, 360
+};
+
+static const unsigned short int AztecCompact50DataSizes [4] = {
+ 36, 102, 176, 280
+};
+
+static const char 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 const char AztecCompactOffset[4] = {
+ 6, 4, 2, 0
+};
+
diff --git a/backend/bmp.c b/backend/bmp.c
new file mode 100644
index 0000000..240c697
--- /dev/null
+++ b/backend/bmp.c
@@ -0,0 +1,181 @@
+/* bmp.c - Handles output to Windows Bitmap file */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <stdio.h>
+#include "common.h"
+#include "bmp.h" /* Bitmap header structure */
+#ifdef _MSC_VER
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
+ int i, row, column;
+ unsigned int fgred, fggrn, fgblu, bgred, bggrn, bgblu;
+ int row_size;
+ unsigned int data_offset, data_size, file_size;
+ unsigned char *bitmap_file_start, *bmp_posn;
+ unsigned char *bitmap;
+ FILE *bmp_file;
+ bitmap_file_header_t file_header;
+ bitmap_info_header_t info_header;
+
+ row_size = 4 * ((24 * symbol->bitmap_width + 31) / 32);
+ data_size = symbol->bitmap_height * row_size;
+ data_offset = sizeof (bitmap_file_header_t) + sizeof (bitmap_info_header_t);
+ file_size = data_offset + data_size;
+
+ bitmap_file_start = (unsigned char *) malloc(file_size);
+ if (bitmap_file_start == NULL) {
+ strcpy(symbol->errtxt, "602: Out of memory");
+ return ZINT_ERROR_MEMORY;
+ }
+ memset(bitmap_file_start, 0, file_size); /* Not required but keeps padding bytes consistent */
+
+ bitmap = bitmap_file_start + data_offset;
+
+ 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]);
+
+ /* Pixel Plotting */
+ for (row = 0; row < symbol->bitmap_height; row++) {
+ for (column = 0; column < symbol->bitmap_width; column++) {
+ i = (3 * column) + (row * row_size);
+ switch (*(pixelbuf + (symbol->bitmap_width * (symbol->bitmap_height - row - 1)) + column)) {
+ case 'W': // White
+ bitmap[i] = 255;
+ bitmap[i + 1] = 255;
+ bitmap[i + 2] = 255;
+ break;
+ case 'C': // Cyan
+ bitmap[i] = 255;
+ bitmap[i + 1] = 255;
+ bitmap[i + 2] = 0;
+ break;
+ case 'B': // Blue
+ bitmap[i] = 255;
+ bitmap[i + 1] = 0;
+ bitmap[i + 2] = 0;
+ break;
+ case 'M': // Magenta
+ bitmap[i] = 255;
+ bitmap[i + 1] = 0;
+ bitmap[i + 2] = 255;
+ break;
+ case 'R': // Red
+ bitmap[i] = 0;
+ bitmap[i + 1] = 0;
+ bitmap[i + 2] = 255;
+ break;
+ case 'Y': // Yellow
+ bitmap[i] = 0;
+ bitmap[i + 1] = 255;
+ bitmap[i + 2] = 255;
+ break;
+ case 'G': // Green
+ bitmap[i] = 0;
+ bitmap[i + 1] = 255;
+ bitmap[i + 2] = 0;
+ break;
+ case 'K': // Black
+ bitmap[i] = 0;
+ bitmap[i + 1] = 0;
+ bitmap[i + 2] = 0;
+ break;
+ case '1':
+ bitmap[i] = fgblu;
+ bitmap[i + 1] = fggrn;
+ bitmap[i + 2] = fgred;
+ break;
+ default:
+ bitmap[i] = bgblu;
+ bitmap[i + 1] = bggrn;
+ bitmap[i + 2] = bgred;
+ break;
+
+ }
+ }
+ }
+
+ symbol->bitmap_byte_length = data_size;
+
+ file_header.header_field = 0x4d42; // "BM"
+ file_header.file_size = file_size;
+ file_header.reserved = 0;
+ file_header.data_offset = data_offset;
+
+ info_header.header_size = sizeof (bitmap_info_header_t);
+ info_header.width = symbol->bitmap_width;
+ info_header.height = symbol->bitmap_height;
+ info_header.colour_planes = 1;
+ info_header.bits_per_pixel = 24;
+ info_header.compression_method = 0; // BI_RGB
+ info_header.image_size = 0;
+ info_header.horiz_res = 0;
+ info_header.vert_res = 0;
+ info_header.colours = 0;
+ info_header.important_colours = 0;
+
+ bmp_posn = bitmap_file_start;
+ memcpy(bitmap_file_start, &file_header, sizeof (bitmap_file_header_t));
+ bmp_posn += sizeof (bitmap_file_header_t);
+ memcpy(bmp_posn, &info_header, sizeof (bitmap_info_header_t));
+
+ /* 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, "600: Can't open output file");
+ free(bitmap_file_start);
+ return ZINT_ERROR_FILE_ACCESS;
+ }
+#endif
+ bmp_file = stdout;
+ } else {
+ if (!(bmp_file = fopen(symbol->outfile, "wb"))) {
+ free(bitmap_file_start);
+ strcpy(symbol->errtxt, "601: Can't open output file");
+ return ZINT_ERROR_FILE_ACCESS;
+ }
+ }
+
+ fwrite(bitmap_file_start, file_header.file_size, 1, bmp_file);
+ fclose(bmp_file);
+
+ free(bitmap_file_start);
+ return 0;
+}
diff --git a/backend/bmp.h b/backend/bmp.h
new file mode 100644
index 0000000..3a6ab34
--- /dev/null
+++ b/backend/bmp.h
@@ -0,0 +1,77 @@
+/* bmp.h - header structure for Windows bitmap files
+
+ libzint - the open source barcode library
+ Copyright (C) 2009-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+
+#ifndef BMP_H
+#define BMP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _MSC_VER
+#include <windows.h>
+#include "stdint_msvc.h"
+#else
+#include <stdint.h>
+#endif
+
+#pragma pack (1)
+
+ typedef struct bitmap_file_header {
+ uint16_t header_field;
+ uint32_t file_size;
+ uint32_t reserved;
+ uint32_t data_offset;
+ } bitmap_file_header_t;
+
+ typedef struct bitmap_info_header {
+ uint32_t header_size;
+ int32_t width;
+ int32_t height;
+ uint16_t colour_planes;
+ uint16_t bits_per_pixel;
+ uint32_t compression_method;
+ uint32_t image_size;
+ int32_t horiz_res;
+ int32_t vert_res;
+ uint32_t colours;
+ uint32_t important_colours;
+ } bitmap_info_header_t;
+
+#pragma pack ()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BMP_H */
+
+
diff --git a/backend/channel_precalcs.h b/backend/channel_precalcs.h
new file mode 100644
index 0000000..f979e1a
--- /dev/null
+++ b/backend/channel_precalcs.h
@@ -0,0 +1,106 @@
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/* Channel code precalculated values to avoid excessive looping */
+/* To generate uncomment CHANNEL_GENERATE_PRECALCS define and run "./test_channel -f generate -g" */
+/* Paste result below here */
+static channel_precalc channel_precalcs7[] = {
+ { 115338, { 1, 3, 1, 1, 1, 1, 5, 1, }, { 1, 1, 1, 2, 1, 2, 3, 3, }, { 1, 7, 5, 5, 5, 5, 5, }, { 1, 7, 7, 7, 6, 6, 5, }, },
+ { 230676, { 1, 1, 2, 2, 4, 1, 1, 2, }, { 1, 2, 1, 3, 2, 1, 3, 1, }, { 1, 7, 7, 6, 5, 2, 2, }, { 1, 7, 6, 6, 4, 3, 3, }, },
+ { 346014, { 1, 2, 3, 1, 1, 1, 3, 2, }, { 1, 2, 2, 1, 1, 3, 1, 3, }, { 1, 7, 6, 4, 4, 4, 4, }, { 1, 7, 6, 5, 5, 5, 3, }, },
+ { 461352, { 1, 2, 1, 1, 1, 2, 2, 4, }, { 1, 3, 1, 1, 3, 2, 2, 1, }, { 1, 7, 6, 6, 6, 6, 5, }, { 1, 7, 5, 5, 5, 3, 2, }, },
+};
+static channel_precalc channel_precalcs8[] = {
+ { 119121, { 2, 1, 3, 2, 1, 3, 2, 1, }, { 1, 1, 1, 4, 3, 2, 1, 2, }, { 8, 7, 7, 5, 4, 4, 2, }, { 8, 8, 8, 8, 5, 3, 2, }, },
+ { 238242, { 2, 1, 1, 2, 2, 2, 1, 4, }, { 1, 1, 3, 1, 1, 2, 4, 2, }, { 8, 7, 7, 7, 6, 5, 4, }, { 8, 8, 8, 6, 6, 6, 5, }, },
+ { 357363, { 2, 2, 1, 4, 1, 1, 1, 3, }, { 1, 1, 1, 1, 3, 2, 5, 1, }, { 8, 7, 6, 6, 3, 3, 3, }, { 8, 8, 8, 8, 8, 6, 5, }, },
+ { 476484, { 2, 2, 1, 1, 3, 2, 3, 1, }, { 1, 1, 3, 1, 2, 2, 3, 2, }, { 8, 7, 6, 6, 6, 4, 3, }, { 8, 8, 8, 6, 6, 5, 4, }, },
+ { 595605, { 2, 3, 3, 2, 1, 1, 1, 2, }, { 1, 1, 2, 1, 1, 1, 5, 3, }, { 8, 7, 5, 3, 2, 2, 2, }, { 8, 8, 8, 7, 7, 7, 7, }, },
+ { 714726, { 2, 1, 1, 6, 1, 1, 2, 1, }, { 1, 2, 1, 3, 1, 4, 1, 2, }, { 8, 7, 7, 7, 2, 2, 2, }, { 8, 8, 7, 7, 5, 5, 2, }, },
+ { 833847, { 2, 1, 1, 3, 1, 3, 3, 1, }, { 1, 2, 3, 1, 1, 3, 2, 2, }, { 8, 7, 7, 7, 5, 5, 3, }, { 8, 8, 7, 5, 5, 5, 3, }, },
+ { 952968, { 2, 2, 2, 3, 2, 1, 2, 1, }, { 1, 2, 2, 1, 2, 2, 2, 3, }, { 8, 7, 6, 5, 3, 2, 2, }, { 8, 8, 7, 6, 6, 5, 4, }, },
+ { 1072089, { 2, 5, 1, 1, 2, 2, 1, 1, }, { 1, 2, 1, 3, 1, 3, 3, 1, }, { 8, 7, 3, 3, 3, 2, 1, }, { 8, 8, 7, 7, 5, 5, 3, }, },
+ { 1191210, { 2, 2, 1, 2, 1, 1, 3, 3, }, { 1, 3, 1, 1, 5, 1, 1, 2, }, { 8, 7, 6, 6, 5, 5, 5, }, { 8, 8, 6, 6, 6, 2, 2, }, },
+ { 1310331, { 2, 1, 2, 1, 2, 3, 2, 2, }, { 1, 4, 1, 3, 1, 1, 2, 2, }, { 8, 7, 7, 6, 6, 5, 3, }, { 8, 8, 5, 5, 3, 3, 3, }, },
+ { 1429452, { 2, 2, 1, 2, 2, 3, 2, 1, }, { 1, 5, 3, 1, 2, 1, 1, 1, }, { 8, 7, 6, 6, 5, 4, 2, }, { 8, 8, 4, 2, 2, 1, 1, }, },
+ { 1548573, { 3, 1, 1, 2, 5, 1, 1, 1, }, { 1, 1, 2, 2, 1, 2, 5, 1, }, { 8, 6, 6, 6, 5, 1, 1, }, { 8, 8, 8, 7, 6, 6, 5, }, },
+ { 1667694, { 3, 2, 2, 1, 1, 3, 2, 1, }, { 1, 1, 1, 1, 2, 4, 3, 2, }, { 8, 6, 5, 4, 4, 4, 2, }, { 8, 8, 8, 8, 8, 7, 4, }, },
+ { 1786815, { 3, 4, 2, 1, 2, 1, 1, 1, }, { 1, 1, 2, 1, 1, 2, 1, 6, }, { 8, 6, 3, 2, 2, 1, 1, }, { 8, 8, 8, 7, 7, 7, 6, }, },
+ { 1905936, { 3, 2, 1, 3, 1, 3, 1, 1, }, { 1, 2, 1, 1, 1, 4, 2, 3, }, { 8, 6, 5, 5, 3, 3, 1, }, { 8, 8, 7, 7, 7, 7, 4, }, },
+ { 2025057, { 3, 1, 2, 2, 1, 1, 4, 1, }, { 1, 3, 2, 1, 1, 1, 5, 1, }, { 8, 6, 6, 5, 4, 4, 4, }, { 8, 8, 6, 5, 5, 5, 5, }, },
+ { 2144178, { 3, 1, 2, 1, 2, 2, 2, 2, }, { 1, 5, 1, 1, 4, 1, 1, 1, }, { 8, 6, 6, 5, 5, 4, 3, }, { 8, 8, 4, 4, 4, 1, 1, }, },
+ { 2263299, { 4, 2, 1, 2, 1, 1, 1, 3, }, { 1, 1, 1, 1, 3, 3, 3, 2, }, { 8, 5, 4, 4, 3, 3, 3, }, { 8, 8, 8, 8, 8, 6, 4, }, },
+ { 2382420, { 4, 2, 1, 1, 1, 1, 4, 1, }, { 1, 2, 2, 2, 2, 2, 2, 2, }, { 8, 5, 4, 4, 4, 4, 4, }, { 8, 8, 7, 6, 5, 4, 3, }, },
+ { 2501541, { 5, 1, 1, 2, 2, 1, 1, 2, }, { 1, 1, 2, 3, 3, 1, 1, 3, }, { 8, 4, 4, 4, 3, 2, 2, }, { 8, 8, 8, 7, 5, 3, 3, }, },
+ { 2620662, { 6, 1, 1, 1, 2, 1, 1, 2, }, { 1, 2, 4, 1, 2, 3, 1, 1, }, { 8, 3, 3, 3, 3, 2, 2, }, { 8, 8, 7, 4, 4, 3, 1, }, },
+ { 2739783, { 1, 1, 1, 1, 3, 3, 4, 1, }, { 2, 1, 2, 1, 6, 1, 1, 1, }, { 8, 8, 8, 8, 8, 6, 4, }, { 8, 7, 7, 6, 6, 1, 1, }, },
+ { 2858904, { 1, 1, 2, 3, 3, 1, 3, 1, }, { 2, 1, 3, 1, 3, 1, 2, 2, }, { 8, 8, 8, 7, 5, 3, 3, }, { 8, 7, 7, 5, 5, 3, 3, }, },
+ { 2978025, { 1, 2, 2, 4, 1, 2, 1, 2, }, { 2, 1, 1, 1, 1, 3, 4, 2, }, { 8, 8, 7, 6, 3, 3, 2, }, { 8, 7, 7, 7, 7, 7, 5, }, },
+ { 3097146, { 1, 2, 2, 1, 3, 3, 2, 1, }, { 2, 1, 3, 3, 2, 2, 1, 1, }, { 8, 8, 7, 6, 6, 4, 2, }, { 8, 7, 7, 5, 3, 2, 1, }, },
+ { 3216267, { 1, 3, 1, 1, 1, 3, 1, 4, }, { 2, 1, 3, 2, 3, 2, 1, 1, }, { 8, 8, 6, 6, 6, 6, 4, }, { 8, 7, 7, 5, 4, 2, 1, }, },
+ { 3335388, { 1, 1, 1, 4, 4, 1, 2, 1, }, { 2, 2, 1, 1, 1, 1, 3, 4, }, { 8, 8, 8, 8, 5, 2, 2, }, { 8, 7, 6, 6, 6, 6, 6, }, },
+ { 3454509, { 1, 1, 2, 4, 3, 1, 2, 1, }, { 2, 2, 2, 5, 1, 1, 1, 1, }, { 8, 8, 8, 7, 4, 2, 2, }, { 8, 7, 6, 5, 1, 1, 1, }, },
+ { 3573630, { 1, 2, 1, 3, 1, 2, 3, 2, }, { 2, 2, 2, 1, 1, 4, 2, 1, }, { 8, 8, 7, 7, 5, 5, 4, }, { 8, 7, 6, 5, 5, 5, 2, }, },
+ { 3692751, { 1, 4, 2, 3, 2, 1, 1, 1, }, { 2, 2, 1, 1, 2, 1, 2, 4, }, { 8, 8, 5, 4, 2, 1, 1, }, { 8, 7, 6, 6, 6, 5, 5, }, },
+ { 3811872, { 1, 1, 2, 1, 3, 5, 1, 1, }, { 2, 3, 3, 2, 2, 1, 1, 1, }, { 8, 8, 8, 7, 7, 5, 1, }, { 8, 7, 5, 3, 2, 1, 1, }, },
+ { 3930993, { 1, 1, 1, 1, 6, 2, 2, 1, }, { 2, 4, 1, 2, 1, 3, 1, 1, }, { 8, 8, 8, 8, 8, 3, 2, }, { 8, 7, 4, 4, 3, 3, 1, }, },
+ { 4050114, { 1, 3, 3, 2, 2, 1, 2, 1, }, { 2, 6, 2, 1, 1, 1, 1, 1, }, { 8, 8, 6, 4, 3, 2, 2, }, { 8, 7, 2, 1, 1, 1, 1, }, },
+ { 4169235, { 2, 1, 2, 2, 4, 2, 1, 1, }, { 2, 1, 2, 1, 1, 1, 4, 3, }, { 8, 7, 7, 6, 5, 2, 1, }, { 8, 7, 7, 6, 6, 6, 6, }, },
+ { 4288356, { 2, 2, 2, 1, 1, 3, 3, 1, }, { 2, 1, 1, 4, 2, 1, 1, 3, }, { 8, 7, 6, 5, 5, 5, 3, }, { 8, 7, 7, 7, 4, 3, 3, }, },
+ { 4407477, { 2, 3, 3, 1, 2, 1, 1, 2, }, { 2, 1, 3, 2, 4, 1, 1, 1, }, { 8, 7, 5, 3, 3, 2, 2, }, { 8, 7, 7, 5, 4, 1, 1, }, },
+ { 4526598, { 2, 1, 4, 1, 4, 1, 1, 1, }, { 2, 2, 2, 1, 2, 3, 1, 2, }, { 8, 7, 7, 4, 4, 1, 1, }, { 8, 7, 6, 5, 5, 4, 2, }, },
+ { 4645719, { 2, 4, 2, 1, 1, 2, 1, 2, }, { 2, 2, 1, 1, 3, 2, 3, 1, }, { 8, 7, 4, 3, 3, 3, 2, }, { 8, 7, 6, 6, 6, 4, 3, }, },
+ { 4764840, { 2, 1, 1, 1, 2, 4, 1, 3, }, { 2, 4, 1, 2, 1, 3, 1, 1, }, { 8, 7, 7, 7, 7, 6, 3, }, { 8, 7, 4, 4, 3, 3, 1, }, },
+ { 4883961, { 3, 1, 1, 3, 2, 2, 1, 2, }, { 2, 1, 2, 2, 2, 1, 2, 3, }, { 8, 6, 6, 6, 4, 3, 2, }, { 8, 7, 7, 6, 5, 4, 4, }, },
+ { 5003082, { 3, 3, 3, 1, 1, 1, 2, 1, }, { 2, 1, 2, 1, 1, 3, 1, 4, }, { 8, 6, 4, 2, 2, 2, 2, }, { 8, 7, 7, 6, 6, 6, 4, }, },
+ { 5122203, { 3, 1, 1, 2, 1, 2, 1, 4, }, { 2, 3, 1, 1, 1, 2, 4, 1, }, { 8, 6, 6, 6, 5, 5, 4, }, { 8, 7, 5, 5, 5, 5, 4, }, },
+ { 5241324, { 4, 1, 1, 3, 1, 2, 2, 1, }, { 2, 1, 3, 1, 1, 3, 3, 1, }, { 8, 5, 5, 5, 3, 3, 2, }, { 8, 7, 7, 5, 5, 5, 3, }, },
+ { 5360445, { 4, 3, 1, 1, 2, 1, 1, 2, }, { 2, 4, 1, 3, 2, 1, 1, 1, }, { 8, 5, 3, 3, 3, 2, 2, }, { 8, 7, 4, 4, 2, 1, 1, }, },
+ { 5479566, { 1, 1, 3, 1, 3, 2, 1, 3, }, { 3, 1, 1, 2, 1, 2, 1, 4, }, { 8, 8, 8, 6, 6, 4, 3, }, { 8, 6, 6, 6, 5, 5, 4, }, },
+ { 5598687, { 1, 2, 1, 1, 5, 1, 3, 1, }, { 3, 1, 1, 1, 1, 3, 1, 4, }, { 8, 8, 7, 7, 7, 3, 3, }, { 8, 6, 6, 6, 6, 6, 4, }, },
+ { 5717808, { 1, 3, 1, 2, 1, 3, 1, 3, }, { 3, 1, 1, 2, 4, 1, 1, 2, }, { 8, 8, 6, 6, 5, 5, 3, }, { 8, 6, 6, 6, 5, 2, 2, }, },
+ { 5836929, { 1, 1, 2, 3, 1, 2, 3, 2, }, { 3, 2, 1, 1, 1, 1, 2, 4, }, { 8, 8, 8, 7, 5, 5, 4, }, { 8, 6, 5, 5, 5, 5, 5, }, },
+ { 5956050, { 1, 2, 3, 3, 2, 2, 1, 1, }, { 3, 2, 3, 1, 1, 1, 1, 3, }, { 8, 8, 7, 5, 3, 2, 1, }, { 8, 6, 5, 3, 3, 3, 3, }, },
+ { 6075171, { 1, 3, 1, 1, 3, 3, 2, 1, }, { 3, 3, 1, 1, 3, 1, 2, 1, }, { 8, 8, 6, 6, 6, 4, 2, }, { 8, 6, 4, 4, 4, 2, 2, }, },
+ { 6194292, { 2, 1, 1, 3, 4, 1, 2, 1, }, { 3, 1, 2, 1, 3, 1, 3, 1, }, { 8, 7, 7, 7, 5, 2, 2, }, { 8, 6, 6, 5, 5, 3, 3, }, },
+ { 6313413, { 2, 3, 2, 2, 1, 2, 2, 1, }, { 3, 1, 1, 2, 1, 3, 2, 2, }, { 8, 7, 5, 4, 3, 3, 2, }, { 8, 6, 6, 6, 5, 5, 3, }, },
+ { 6432534, { 2, 3, 1, 1, 2, 2, 3, 1, }, { 3, 2, 1, 2, 3, 1, 2, 1, }, { 8, 7, 5, 5, 5, 4, 3, }, { 8, 6, 5, 5, 4, 2, 2, }, },
+ { 6551655, { 3, 1, 1, 2, 1, 4, 1, 2, }, { 3, 1, 2, 3, 1, 1, 3, 1, }, { 8, 6, 6, 6, 5, 5, 2, }, { 8, 6, 6, 5, 3, 3, 3, }, },
+ { 6670776, { 3, 1, 1, 1, 1, 3, 4, 1, }, { 3, 3, 1, 2, 1, 1, 3, 1, }, { 8, 6, 6, 6, 6, 6, 4, }, { 8, 6, 4, 4, 3, 3, 3, }, },
+ { 6789897, { 5, 2, 1, 1, 2, 1, 2, 1, }, { 3, 1, 1, 1, 2, 2, 3, 2, }, { 8, 4, 3, 3, 3, 2, 2, }, { 8, 6, 6, 6, 6, 5, 4, }, },
+ { 6909018, { 1, 2, 2, 2, 2, 1, 4, 1, }, { 4, 1, 1, 2, 1, 2, 1, 3, }, { 8, 8, 7, 6, 5, 4, 4, }, { 8, 5, 5, 5, 4, 4, 3, }, },
+ { 7028139, { 1, 1, 3, 2, 2, 2, 1, 3, }, { 4, 2, 2, 1, 2, 2, 1, 1, }, { 8, 8, 8, 6, 5, 4, 3, }, { 8, 5, 4, 3, 3, 2, 1, }, },
+ { 7147260, { 2, 1, 4, 3, 2, 1, 1, 1, }, { 4, 1, 1, 1, 4, 1, 1, 2, }, { 8, 7, 7, 4, 2, 1, 1, }, { 8, 5, 5, 5, 5, 2, 2, }, },
+ { 7266381, { 2, 4, 1, 3, 2, 1, 1, 1, }, { 4, 2, 1, 1, 1, 2, 1, 3, }, { 8, 7, 4, 4, 2, 1, 1, }, { 8, 5, 4, 4, 4, 4, 3, }, },
+ { 7385502, { 4, 2, 1, 3, 1, 2, 1, 1, }, { 4, 1, 1, 4, 2, 1, 1, 1, }, { 8, 5, 4, 4, 2, 2, 1, }, { 8, 5, 5, 5, 2, 1, 1, }, },
+ { 7504623, { 1, 1, 3, 4, 3, 1, 1, 1, }, { 5, 2, 1, 1, 1, 1, 1, 3, }, { 8, 8, 8, 6, 3, 1, 1, }, { 8, 4, 3, 3, 3, 3, 3, }, },
+ { 7623744, { 3, 1, 1, 2, 2, 1, 2, 3, }, { 5, 2, 1, 1, 1, 2, 1, 2, }, { 8, 6, 6, 6, 5, 4, 4, }, { 8, 4, 3, 3, 3, 3, 2, }, },
+};
diff --git a/backend/codablock.c b/backend/codablock.c
new file mode 100644
index 0000000..2eef2a7
--- /dev/null
+++ b/backend/codablock.c
@@ -0,0 +1,988 @@
+/* codablock.c - Handles Codablock-F and Codablock-E */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2016 - 2020 Harald Oehlmann
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+#include <assert.h>
+#include "common.h"
+
+INTERNAL int code_128(struct zint_symbol *symbol, const unsigned char source[], const size_t length);
+
+#define uchar unsigned char
+
+/* FTab C128 flags - may be added */
+#define CodeA 1
+#define CodeB 2
+#define CodeC 4
+#define CEnd 8
+#define CShift 16
+#define CFill 32
+#define CodeFNC1 64
+#define CodeFNC4 128
+#define ZTNum (CodeA+CodeB+CodeC)
+#define ZTFNC1 (CodeA+CodeB+CodeC+CodeFNC1)
+
+/* ASCII-Extension for Codablock-F */
+#define aFNC1 (uchar)(128)
+#define aFNC2 (uchar)(129)
+#define aFNC3 (uchar)(130)
+#define aFNC4 (uchar)(131)
+#define aCodeA (uchar)(132)
+#define aCodeB (uchar)(133)
+#define aCodeC (uchar)(134)
+#define aShift (uchar)(135)
+
+static const char *C128Table[107] = {
+ /* Code 128 character encodation - Table 1 */
+ "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 F Analysing-Chart */
+typedef struct sCharacterSetTable
+{
+ int CharacterSet; /* Still possible character sets for actual*/
+ int AFollowing; /* Still following Characters in Charset A */
+ int BFollowing; /* Still following Characters in Charset B */
+ int CFollowing; /* Still following Characters in Charset C */
+} CharacterSetTable;
+
+/* Find the possible Code-128 Character sets for a character
+ * The result is an or of CodeA, CodeB, CodeC, CodeFNC1, CodeFNC4 depending on the
+ * possible Code 128 character sets.
+ */
+static int GetPossibleCharacterSet(unsigned char C)
+{
+ if (C<='\x1f') /* Control chars */
+ return CodeA;
+ if (C>='0' && C<='9')
+ return ZTNum; /* ZTNum=CodeA+CodeB+CodeC */
+ if (C==aFNC1)
+ return ZTFNC1; /* ZTFNC1=CodeA+CodeB+CodeC+CodeFNC1 */
+ if (C==aFNC4)
+ return (CodeA | CodeB | CodeFNC4);
+ if (C>='\x60' && C<='\x7f') /* 60 to 127 */
+ return CodeB;
+ return CodeA+CodeB;
+}
+
+/* Create a Table with the following information for each Data character:
+ * int CharacterSet is an or of CodeA, CodeB, CodeC, CodeFNC1, CodeFNC4,
+ * depending on which character set is applicable.
+ * (Result of GetPossibleCharacterSet)
+ * int AFollowing,BFollowing The number of source characters you still may encode
+ * in this character set.
+ * int CFollowing The number of characters encodable in CodeC if we
+ * start here.
+ */
+static void CreateCharacterSetTable(CharacterSetTable T[], unsigned char *data, const int dataLength)
+{
+ int charCur;
+ int runChar;
+
+ /* Treat the Data backwards */
+ charCur=dataLength-1;
+ T[charCur].CharacterSet=GetPossibleCharacterSet(data[charCur]);
+ T[charCur].AFollowing=((T[charCur].CharacterSet & CodeA)==0)?0:1;
+ T[charCur].BFollowing=((T[charCur].CharacterSet & CodeB)==0)?0:1;
+ T[charCur].CFollowing=0;
+
+ for (charCur--;charCur>=0;charCur--)
+ {
+ T[charCur].CharacterSet=GetPossibleCharacterSet(data[charCur]);
+ T[charCur].AFollowing=
+ ((T[charCur].CharacterSet & CodeA)==0)?0:T[charCur+1].AFollowing+1;
+ T[charCur].BFollowing=
+ ((T[charCur].CharacterSet & CodeB)==0)?0:T[charCur+1].BFollowing+1;
+ T[charCur].CFollowing=0;
+
+ }
+ /* Find the CodeC-chains */
+ for (charCur=0;charCur<dataLength;charCur++)
+ {
+ T[charCur].CFollowing=0;
+ if ((T[charCur].CharacterSet & CodeC)!=0)
+ {
+ /* CodeC possible */
+ runChar=charCur;
+ do{
+ /* Whether this is FNC1, whether next is */
+ /* numeric */
+ if (T[runChar].CharacterSet==ZTFNC1)
+ /* FNC1 */
+ ++(T[charCur].CFollowing);
+ else
+ {
+ ++runChar;
+ if (runChar>=dataLength)
+ break;
+ /* Only a Number may follow */
+ if (T[runChar].CharacterSet==ZTNum)
+ T[charCur].CFollowing+=2;
+ else
+ break;
+ }
+ ++runChar;
+ } while (runChar<dataLength);
+ }
+ }
+}
+
+/* Find the amount of numerical characters in pairs which will fit in
+ * one bundle into the line (up to here). This is calculated online because
+ * it depends on the space in the line.
+ */
+static int RemainingDigits(CharacterSetTable *T, int charCur,int emptyColumns)
+{
+ int digitCount; /* Numerical digits fitting in the line */
+ int runChar;
+ runChar=charCur;
+ digitCount=0;
+ while(emptyColumns>0 && runChar<charCur+T[charCur].CFollowing)
+ {
+ if (T[runChar].CharacterSet!=ZTFNC1)
+ {
+ /* NOT FNC1 */
+ digitCount+=2;
+ runChar++;
+ }
+ runChar++;
+ emptyColumns--;
+ }
+ return digitCount;
+}
+
+/* Find the Character distribution at a given column count.
+ * If too many rows (>44) are requested the columns are extended.
+ * Parameters :
+ * T Pointer on the Characters which fit in the row
+ * If a different count is calculated it is corrected
+ * in the callers workspace.
+ * pFillings Output of filling characters
+ * pSet Output of the character sets used, allocated by me.
+ * Return value Resulting row count
+ */
+
+static int Columns2Rows(struct zint_symbol *symbol, CharacterSetTable *T, const int dataLength,
+ int * pRows, int * pUseColumns, int * pSet, int * pFillings)
+{
+ int useColumns; /* Usable Characters per line */
+ int fillings; /* Number of filling characters */
+ int rowsCur;
+ int runChar;
+ int emptyColumns; /* Number of codes still empty in line. */
+ int emptyColumns2; /* Alternative emptyColumns to compare */
+ int CPaires; /* Number of digit pairs which may fit in the line */
+ int characterSetCur; /* Current Character Set */
+ int isFNC4; /* Set if current character FNC4 */
+
+ useColumns=*pUseColumns;
+
+ /* >>> Loop until rowsCur <= 44 */
+ do {
+ int charCur=0;
+ memset(pSet,0,dataLength*sizeof(int));
+ rowsCur=0;
+
+ /* >>> Line Loop */
+ do{
+ /* >> Start Character */
+ emptyColumns=useColumns; /* Remained place in Line */
+
+ /* >>Choose in Set A or B */
+ /* (C is changed as an option later on) */
+
+ pSet[charCur]=characterSetCur=
+ (T[charCur].AFollowing > T[charCur].BFollowing)
+ ? CodeA : CodeB;
+
+ /* >> Test on Numeric Mode C */
+ CPaires=RemainingDigits(T,charCur, emptyColumns);
+ if (CPaires>=4)
+ {
+ /* 4 Digits in Numeric compression ->OK */
+ /* > May an odd start find more ? */
+ /* Skip leading <FNC1>'s */
+ /* Typical structure : <FNC1><FNC1>12... */
+ /* Test if numeric after one isn't better.*/
+ runChar=charCur;
+ emptyColumns2=emptyColumns;
+ while (T[runChar].CharacterSet==ZTFNC1)
+ {
+ ++runChar;
+ --emptyColumns2;
+ }
+ if (CPaires>=RemainingDigits(T,runChar+1,emptyColumns2-1))
+ {
+ /* Start odd is not better */
+ /* We start in C */
+ pSet[charCur]=characterSetCur=CodeC;
+ /* Increment charCur */
+ if (T[charCur].CharacterSet!=ZTFNC1)
+ ++charCur; /* 2 Num.Digits */
+ }
+ }
+ ++charCur;
+ --emptyColumns;
+
+ /* >> Following characters */
+ while(emptyColumns>0 && charCur<dataLength)
+ {
+ isFNC4 = (T[charCur].CharacterSet & CodeFNC4);
+ switch(characterSetCur){
+ case CodeA:
+ case CodeB:
+ /* >> Check switching to CodeC */
+ /* Switch if :
+ * - Character not FNC1
+ * - 4 real Digits will fit in line
+ * - an odd Start will not be better
+ */
+ if (T[charCur].CharacterSet==ZTNum
+ && (CPaires=RemainingDigits(T,charCur, emptyColumns-1))>=4
+ && CPaires > RemainingDigits(T,charCur+1,emptyColumns-2))
+ {
+ /* > Change to C */
+ pSet[charCur]=characterSetCur=CodeC;
+ charCur+=2; /* 2 Digit */
+ emptyColumns-=2; /* <SwitchC>12 */
+ } else if (characterSetCur==CodeA)
+ {
+ if (T[charCur].AFollowing == 0 || (isFNC4 && T[charCur].AFollowing == 1))
+ {
+ /* Must change to B */
+ if (emptyColumns == 1 || (isFNC4 && emptyColumns == 2))
+ {
+ /* Can't switch: */
+ pSet[charCur-1]|=CEnd+CFill;
+ emptyColumns=0;
+ }else{
+ /* <Shift> or <switchB>? */
+ if (T[charCur].BFollowing == 1 || (isFNC4 && T[charCur].BFollowing == 2))
+ {
+ /* Note using order "FNC4 shift char" (same as CODE128) not "shift FNC4 char" as given in Table B.1 and Table B.2 */
+ if (isFNC4) { /* So skip FNC4 and shift value instead */
+ --emptyColumns;
+ ++charCur;
+ }
+ pSet[charCur]|=CShift;
+ } else {
+ pSet[charCur]|=CodeB;
+ characterSetCur = CodeB;
+ }
+ emptyColumns-=2;
+ ++charCur;
+ }
+ } else if (isFNC4 && emptyColumns == 1) {
+ /* Can't fit extended ASCII on same line */
+ pSet[charCur-1]|=CEnd+CFill;
+ emptyColumns=0;
+ }else{
+ --emptyColumns;
+ ++charCur;
+ }
+ } else { /* Last possibility : CodeB */
+ if (T[charCur].BFollowing == 0 || (isFNC4 && T[charCur].BFollowing == 1))
+ {
+ /* Must change to A */
+ if (emptyColumns == 1 || (isFNC4 && emptyColumns == 2))
+ {
+ /* Can't switch: */
+ pSet[charCur-1]|=CEnd+CFill;
+ emptyColumns=0;
+ } else {
+ /* <Shift> or <switchA>? */
+ if (T[charCur].AFollowing == 1 || (isFNC4 && T[charCur].AFollowing == 2))
+ {
+ /* Note using order "FNC4 shift char" (same as CODE128) not "shift FNC4 char" as given in Table B.1 and Table B.2 */
+ if (isFNC4) { /* So skip FNC4 and shift value instead */
+ --emptyColumns;
+ ++charCur;
+ }
+ pSet[charCur]|=CShift;
+ } else {
+ pSet[charCur]|=CodeA;
+ characterSetCur = CodeA;
+ }
+ emptyColumns-=2;
+ ++charCur;
+ }
+ } else if (isFNC4 && emptyColumns == 1) {
+ /* Can't fit extended ASCII on same line */
+ pSet[charCur-1]|=CEnd+CFill;
+ emptyColumns=0;
+ }else{
+ --emptyColumns;
+ ++charCur;
+ }
+ }
+ break;
+ case CodeC:
+ if(T[charCur].CFollowing>0)
+ {
+ charCur+=(T[charCur].CharacterSet==ZTFNC1)?1:2;
+ emptyColumns--;
+ }else{
+ /* Must change to A or B */
+ if (emptyColumns==1)
+ {
+ /* Can't switch: */
+ pSet[charCur-1]|=CEnd+CFill;
+ emptyColumns=0;
+ }else{
+ /*<SwitchA> or <switchA>?*/
+ characterSetCur=pSet[charCur]=
+ (T[charCur].AFollowing > T[charCur].BFollowing)
+ ?CodeA:CodeB;
+ emptyColumns-=2;
+ ++charCur;
+ }
+ }
+ break;
+ } /* switch */
+ } /* while */
+
+ /* > End of Codeline */
+ pSet[charCur-1]|=CEnd;
+ ++rowsCur;
+ } while (charCur<dataLength); /* <= Data.Len-1 */
+
+ /* Allow for check characters K1, K2 */
+ switch (emptyColumns) {
+ case 1:
+ pSet[charCur-1]|=CFill;
+ /* fall through */
+ case 0:
+ ++rowsCur;
+ fillings=useColumns-2+emptyColumns;
+ break;
+ case 2:
+ fillings=0;
+ break;
+ default:
+ pSet[charCur-1]|=CFill;
+ fillings=emptyColumns-2;
+ }
+
+ if (rowsCur>44) {
+ ++useColumns;
+ if (useColumns > 62) {
+ return ZINT_ERROR_TOO_LONG;
+ }
+ } else if (rowsCur == 1) {
+ rowsCur = 2;
+ fillings += useColumns;
+ }
+ } while(rowsCur>44);
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf(" -> out: rowsCur <%i>, useColumns <%i>, fillings <%i>\n",rowsCur,useColumns,fillings);
+ }
+ *pUseColumns=useColumns;
+ *pRows=rowsCur;
+ *pFillings=fillings;
+ return 0;
+}
+
+/* Find columns if row count is given.
+ */
+static int Rows2Columns(struct zint_symbol *symbol, CharacterSetTable *T, const int dataLength,
+ int * pRows, int * pUseColumns, int * pSet, int * pFillings)
+{
+ int rowsCur;
+ int rowsRequested; /* Number of requested rows */
+ int columnsRequested; /* Number of requested columns (if any) */
+ int backupRows = 0;
+ int fillings;
+ int backupFillings = 0;
+ int useColumns;
+ int testColumns; /* To enter into Width2Rows */
+ int backupColumns = 0;
+ int fBackupOk = 0; /* The memorised set is o.k. */
+ int testListSize = 0;
+ int pTestList[62];
+#ifndef _MSC_VER
+ int *pBackupSet[dataLength];
+#else
+ int *pBackupSet = (int *)_alloca(dataLength*sizeof(int));
+#endif
+
+ rowsRequested=*pRows;
+ columnsRequested = *pUseColumns >= 4 ? *pUseColumns : 0;
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Optimizer : Searching <%i> rows\n", rowsRequested);
+ }
+
+ if (columnsRequested) {
+ testColumns = columnsRequested;
+ } else {
+ /* First guess */
+ testColumns=dataLength/rowsRequested;
+ if (testColumns > 62)
+ testColumns = 62;
+ else if (testColumns < 4)
+ testColumns = 4;
+ }
+
+ for (;;) {
+ int errorCur;
+ pTestList[testListSize] = testColumns;
+ testListSize++;
+ useColumns=testColumns; /* Make a copy because it may be modified */
+ errorCur = Columns2Rows(symbol, T, dataLength, &rowsCur, &useColumns, pSet, &fillings);
+ if (errorCur != 0)
+ return errorCur;
+ if (rowsCur<=rowsRequested) {
+ /* Less or exactly line number found */
+ /* check if column count below already tested or at smallest/requested */
+ int fInTestList = (rowsCur == 2 || testColumns == 4 || testColumns == columnsRequested);
+ int posCur;
+ for (posCur = 0; posCur < testListSize && ! fInTestList; posCur++) {
+ if ( pTestList[posCur] == testColumns-1 )
+ fInTestList = 1;
+ }
+ if (fInTestList) {
+ /* >> Smaller Width already tested
+ */
+ if (rowsCur < rowsRequested) {
+ fillings += useColumns * (rowsRequested - rowsCur);
+ rowsCur = rowsRequested;
+ }
+ /* Exit with actual */
+ *pFillings=fillings;
+ *pRows=rowsCur;
+ *pUseColumns = useColumns;
+ return 0;
+ }
+ /* > Test more rows (shorter CDB) */
+ fBackupOk=(rowsCur==rowsRequested);
+ memcpy(pBackupSet,pSet,dataLength*sizeof(int));
+ backupFillings=fillings;
+ backupColumns=useColumns;
+ backupRows=rowsCur;
+ --testColumns;
+ } else {
+ /* > Too many rows */
+ int fInTestList = fBackupOk;
+ int posCur;
+ for (posCur = 0; posCur < testListSize && ! fInTestList; posCur++) {
+ if ( pTestList[posCur] == testColumns+1 )
+ fInTestList = 1;
+ }
+ if (fInTestList) {
+ /* The next less-rows (larger) code was
+ * already tested. So give the larger
+ * back.
+ */
+ memcpy(pSet,pBackupSet,dataLength*sizeof(int));
+ *pFillings=backupFillings;
+ *pRows=backupRows;
+ *pUseColumns=backupColumns;
+ return 0;
+ }
+ /* > Test less rows (longer code) */
+ backupRows=rowsCur;
+ memcpy(pBackupSet,pSet,dataLength*sizeof(int));
+ backupFillings=fillings;
+ backupColumns=useColumns;
+ fBackupOk=0;
+ ++testColumns;
+ }
+ }
+}
+
+/* Print a character in character set A
+ */
+static void A2C128_A(uchar **ppOutPos,uchar c)
+{
+ uchar * pOutPos = *ppOutPos;
+ switch(c){
+ case aCodeB: *pOutPos=100; break;
+ case aFNC4: *pOutPos=101; break;
+ case aFNC1: *pOutPos=102; break;
+ case aFNC2: *pOutPos=97; break;
+ case aFNC3: *pOutPos=96; break;
+ case aCodeC: *pOutPos=99; break;
+ case aShift: *pOutPos=98; break;
+ default:
+ /* +++ HaO 13.11.98 c>' ' && c < '\x1F' corrected */
+ if(c>=' ' && c<='_')
+ *pOutPos=(uchar)(c-' ');
+ else
+ *pOutPos=(uchar)(c+64);
+ break;
+ }
+ (*ppOutPos)++;
+}
+
+/* Output c in Set B
+ */
+static void A2C128_B(uchar **ppOutPos,uchar c)
+{
+ uchar * pOutPos = *ppOutPos;
+ switch(c){
+ case aFNC1: *pOutPos=102; break;
+ case aFNC2: *pOutPos=97; break;
+ case aFNC3: *pOutPos=96; break;
+ case aFNC4: *pOutPos=100; break;
+ case aCodeA: *pOutPos=101; break;
+ case aCodeC: *pOutPos=99; break;
+ case aShift: *pOutPos=98; break;
+ default: *pOutPos=(uchar)(c-' '); break;
+ }
+ ++(*ppOutPos);
+}
+
+/* Output c1, c2 in Set C
+ */
+static void A2C128_C(uchar **ppOutPos,uchar c1,uchar c2)
+{
+ uchar * pOutPos = *ppOutPos;
+ switch(c1){
+ case aFNC1: *pOutPos=102; break;
+ case aCodeB: *pOutPos=100; break;
+ case aCodeA: *pOutPos=101; break;
+ default: *pOutPos=(char)(10 * (c1- '0') + (c2 - '0'));break;
+ }
+ (*ppOutPos)++;
+}
+
+/* Output a character in Characterset
+ */
+static void ASCIIZ128(uchar **ppOutPos, int CharacterSet,uchar c1, uchar c2)
+{
+ if (CharacterSet==CodeA)
+ A2C128_A(ppOutPos,c1);
+ else if(CharacterSet==CodeB)
+ A2C128_B(ppOutPos,c1);
+ else
+ A2C128_C(ppOutPos,c1,c2);
+}
+
+/* XLate Tables D.2, D.3 and F.1 of Codablock-F Specification and call output
+ */
+static void SumASCII(uchar **ppOutPos, int Sum, int CharacterSet)
+{
+ switch (CharacterSet){
+ case CodeA: /* Row # Indicators and Data Check Characters K1/K2 for CodeA and CodeB are the same */
+ case CodeB:
+ if (Sum<=31)
+ A2C128_B(ppOutPos, (uchar)(Sum+96));
+ else if(Sum<=47)
+ A2C128_B(ppOutPos, (uchar)Sum);
+ else
+ A2C128_B(ppOutPos, (uchar)(Sum+10));
+ break;
+ case CodeC:
+ A2C128_C(ppOutPos
+ ,(char)(Sum/10+'0') ,(uchar)(Sum%10+'0'));
+ break;
+ }
+}
+
+/* Main function called by zint framework
+ */
+INTERNAL int codablock(struct zint_symbol *symbol,const unsigned char source[], const size_t length) {
+ int charCur, dataLength;
+ int Error;
+ int rows, columns, useColumns;
+ int fillings;
+ int Sum1,Sum2;
+ uchar * pOutPos;
+ int rowCur;
+ int characterSetCur;
+ int emptyColumns;
+ char dest[1000];
+ int r, c;
+#ifdef _MSC_VER
+ CharacterSetTable *T;
+ unsigned char *data;
+ int *pSet;
+ uchar * pOutput;
+#endif
+ /* Suppresses clang-analyzer-core.VLASize warning */
+ assert(length > 0);
+
+ /* Parameter check */
+ /* option1: rows <= 0: automatic, 1..44 */
+ rows = symbol->option_1;
+ if (rows == 1) {
+ Error = code_128(symbol, source, length);
+ if (Error < 5) {
+ symbol->output_options |= BARCODE_BIND;
+ if (symbol->border_width == 0) { /* Allow override if non-zero */
+ symbol->border_width = 1; /* AIM ISS-X-24 Section 4.6.1 b) (note change from previous default 2) */
+ }
+ }
+ return Error;
+ }
+ if (rows > 44) {
+ strcpy(symbol->errtxt, "410: Rows parameter not in 0..44");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+ /* option_2: (usable data) columns: <= 0: automatic, 9..67 (min 9 == 4 data, max 67 == 62 data) */
+ columns = symbol->option_2;
+ if ( ! (columns <= 0 || (columns >= 9 && columns <= 67)) ) {
+ strcpy(symbol->errtxt, "411: Columns parameter not in 0, 9..67");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+#ifndef _MSC_VER
+ unsigned char data[length*2+1];
+#else
+ data = (unsigned char *) _alloca(length * 2+1);
+#endif
+
+ dataLength = 0;
+ if (symbol->output_options & READER_INIT) {
+ data[dataLength] = aFNC3;
+ dataLength++;
+ }
+ /* Replace all Codes>127 with <fnc4>Code-128 */
+ for (charCur = 0; charCur < (int) length; charCur++) {
+ if (source[charCur]>127)
+ {
+ data[dataLength] = aFNC4;
+ dataLength++;
+ data[dataLength] = (unsigned char)(source[charCur]&127);
+ } else
+ data[dataLength] = source[charCur];
+ dataLength++;
+ }
+
+ /* Build character set table */
+#ifndef _MSC_VER
+ CharacterSetTable T[dataLength];
+ int pSet[dataLength];
+#else
+ T=(CharacterSetTable *)_alloca(dataLength*sizeof(CharacterSetTable));
+ pSet = (int *)_alloca(dataLength*sizeof(int));
+#endif
+ CreateCharacterSetTable(T,data,dataLength);
+
+ /* Find final row and column count */
+ /* nor row nor column count given */
+ if (rows <= 0 && columns <= 0) {
+ /* use 1/1 aspect/ratio Codablock */
+ columns = floor(sqrt(dataLength)) + 5;
+ if (columns > 67) {
+ columns = 67;
+ } else if (columns < 9) {
+ columns = 9;
+ }
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Auto column count for %d characters:%d\n", dataLength, columns);
+ }
+ }
+ /* There are 5 Codewords for Organisation Start(2),row(1),CheckSum,Stop */
+ useColumns = columns - 5;
+ if ( rows > 0 ) {
+ /* row count given */
+ Error = Rows2Columns(symbol, T, dataLength, &rows, &useColumns, pSet, &fillings);
+ } else {
+ /* column count given */
+ Error = Columns2Rows(symbol, T, dataLength, &rows, &useColumns, pSet, &fillings);
+ }
+ if (Error != 0) {
+ strcpy(symbol->errtxt, "413: Data string too long");
+ return Error;
+ }
+ /* Suppresses clang-analyzer-core.VLASize warning */
+ assert(rows >= 2 && useColumns >= 4);
+
+ /* Data Check Characters K1 and K2, Annex F */
+ Sum1 = Sum2 = 0;
+ for (charCur = 0; charCur < (int) length; charCur++) {
+ Sum1 = (Sum1 + (charCur + 1) * source[charCur]) % 86; /* Mod as we go along to avoid overflow */
+ Sum2 = (Sum2 + charCur * source[charCur]) % 86;
+ }
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) { /* start a new level of local variables */
+ int DPos;
+ printf("\nData:");
+ for (DPos=0 ; DPos< dataLength ; DPos++)
+ fputc(data[DPos],stdout);
+ printf("\n Set:");
+ for (DPos=0 ; DPos< dataLength ; DPos++) {
+ switch (pSet[DPos]&(CodeA+CodeB+CodeC)) {
+ case CodeA: fputc('A',stdout); break;
+ case CodeB: fputc('B',stdout); break;
+ case CodeC: fputc('C',stdout); break;
+ default: fputc('.',stdout); break;
+ }
+ }
+ printf("\nFNC1:");
+ for (DPos=0 ; DPos< dataLength ; DPos++)
+ fputc((pSet[DPos]&CodeFNC1)==0?'.':'X',stdout);
+ printf("\n END:");
+ for (DPos=0 ; DPos< dataLength ; DPos++)
+ fputc((pSet[DPos]&CEnd)==0?'.':'X',stdout);
+ printf("\nShif:");
+ for (DPos=0 ; DPos< dataLength ; DPos++)
+ fputc((pSet[DPos]&CShift)==0?'.':'X',stdout);
+ printf("\nFILL:");
+ for (DPos=0 ; DPos< dataLength ; DPos++)
+ fputc((pSet[DPos]&CFill)==0?'.':'X',stdout);
+ fputc('\n',stdout);
+ printf("K1 %d, K2 %d\n", Sum1, Sum2);
+ }
+
+ columns = useColumns + 5;
+
+ /* >>> Build C128 code numbers */
+ /* The C128 column count contains Start (2CW), Row ID, Checksum, Stop */
+#ifndef _MSC_VER
+ uchar pOutput[columns * rows];
+#else
+ pOutput = (unsigned char *)_alloca(columns * rows * sizeof(char));
+#endif
+ pOutPos = pOutput;
+ charCur=0;
+ /* >> Loop over rows */
+ for (rowCur=0 ; rowCur<rows ; rowCur++) {
+ if (charCur>=dataLength)
+ {
+ /* >> Empty line with StartA, aCodeB, row #, and then filler aCodeC aCodeB etc */
+ *pOutPos='\x67';
+ pOutPos++;
+ *pOutPos = 100; /* aCodeB */
+ pOutPos++;
+ characterSetCur = CodeB;
+ SumASCII(&pOutPos, rowCur + 42, characterSetCur); /* Row # */
+ emptyColumns = useColumns;
+ if (rowCur == rows - 1) {
+ emptyColumns -= 2;
+ }
+ while (emptyColumns>0)
+ {
+ if(characterSetCur==CodeC)
+ {
+ A2C128_C(&pOutPos,aCodeB,'\0');
+ characterSetCur=CodeB;
+ }else{
+ A2C128_B(&pOutPos,aCodeC);
+ characterSetCur=CodeC;
+ }
+ --emptyColumns;
+ }
+ }else{
+ /* >> Normal Line */
+ /* > Startcode */
+ switch (pSet[charCur] & (CodeA+CodeB+CodeC)){
+ case CodeA:
+ *pOutPos = '\x67';
+ pOutPos++;
+ *pOutPos = '\x62';
+ pOutPos++;
+ characterSetCur=CodeA;
+ break;
+ case CodeB:
+ *pOutPos = '\x67';
+ pOutPos++;
+ *pOutPos = '\x64';
+ pOutPos++;
+ characterSetCur=CodeB;
+ break;
+ case CodeC:
+ default:
+ *pOutPos = '\x67';
+ pOutPos++;
+ *pOutPos = '\x63';
+ pOutPos++;
+ characterSetCur=CodeC;
+ break;
+ }
+ /* > Set F1 */
+ /* In first line : # of rows */
+ SumASCII(&pOutPos, rowCur == 0 ? rows - 2 : rowCur + 42, characterSetCur);
+ /* >>> Data */
+ emptyColumns=useColumns;
+ /* >> Character loop */
+ while (emptyColumns > 0 && charCur < dataLength)
+ {
+ /* ? Change character set */
+ if (emptyColumns < useColumns)
+ {
+ if ((pSet[charCur]&CodeA)!=0)
+ {
+ /* Change to A */
+ ASCIIZ128(&pOutPos,characterSetCur,aCodeA,'\0');
+ --emptyColumns;
+ characterSetCur=CodeA;
+ } else if ((pSet[charCur]&CodeB)!=0)
+ {
+ /* Change to B */
+ ASCIIZ128(&pOutPos,characterSetCur,aCodeB,'\0');
+ --emptyColumns;
+ characterSetCur=CodeB;
+ } else if ((pSet[charCur]&CodeC)!=0)
+ {
+ /* Change to C */
+ ASCIIZ128(&pOutPos,characterSetCur,aCodeC,'\0');
+ --emptyColumns;
+ characterSetCur=CodeC;
+ }
+ }
+ if ((pSet[charCur]&CShift)!=0)
+ {
+ /* >> Shift it and put out the shifted character */
+ ASCIIZ128(&pOutPos,characterSetCur,aShift,'\0');
+ emptyColumns-=2;
+ characterSetCur=(characterSetCur==CodeB)?CodeA:CodeB;
+ ASCIIZ128(&pOutPos,characterSetCur,data[charCur],'\0');
+ characterSetCur=(characterSetCur==CodeB)?CodeA:CodeB;
+ }else{
+ /* Normal Character */
+ if (characterSetCur==CodeC)
+ {
+ if (data[charCur]==aFNC1)
+ A2C128_C(&pOutPos,aFNC1,'\0');
+ else
+ {
+ A2C128_C(&pOutPos, data[charCur], charCur + 1 < dataLength ? data[charCur + 1] : 0);
+ ++charCur;
+ /* We need this here to get the good index */
+ /* for the termination flags in Set. */
+ }
+ }else
+ ASCIIZ128(&pOutPos,characterSetCur,data[charCur],'\0');
+ --emptyColumns;
+ }
+ /* >> End Criteria */
+ if ((pSet[charCur] & CFill) || (pSet[charCur] & CEnd))
+ {
+ /* Fill Line but leave space for checks in last line */
+ if (rowCur == rows - 1) {
+ emptyColumns -= 2;
+ }
+ while(emptyColumns>0)
+ {
+ switch(characterSetCur){
+ case CodeC:
+ A2C128_C(&pOutPos,aCodeB,'\0');
+ characterSetCur=CodeB;
+ break;
+ case CodeB:
+ A2C128_B(&pOutPos,aCodeC);
+ characterSetCur=CodeC;
+ break;
+ case CodeA:
+ A2C128_A(&pOutPos,aCodeC);
+ characterSetCur=CodeC;
+ break;
+ }
+ --emptyColumns;
+ }
+ }
+ ++charCur;
+ } /* Loop over characters */
+ } /* if filling-Line / normal */
+
+ /* Add checksum in last line */
+ if (rowCur == rows - 1)
+ {
+ SumASCII(&pOutPos,Sum1,characterSetCur);
+ SumASCII(&pOutPos,Sum2,characterSetCur);
+ }
+ /* Add Code 128 checksum */
+ {
+ int Sum = pOutput[columns * rowCur] % 103;
+ int Pos = 1;
+ for ( ; Pos < useColumns+3 ; Pos++)
+ {
+ Sum = (Sum + pOutput[columns * rowCur + Pos] * Pos) % 103;
+ }
+ *pOutPos=(uchar)Sum;
+ pOutPos++;
+ }
+ /* Add end character */
+ *pOutPos=106;
+ pOutPos++;
+ } /* End Lineloop */
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ /* Dump the output to the screen
+ */
+ printf("\nCode 128 Code Numbers:\n");
+ { /* start a new level of local variables */
+ int DPos, DPos2;
+ for (DPos=0 ; DPos< rows ; DPos++)
+ {
+ for (DPos2=0 ; DPos2 < columns ; DPos2++)
+ {
+ printf("%3d ",(int)(pOutput[DPos*columns+DPos2]));
+ }
+ printf("\n");
+ }
+ }
+ printf("rows=%i columns=%i fillings=%i\n", rows, columns, fillings);
+ }
+#ifdef ZINT_TEST
+ if (symbol->debug & ZINT_DEBUG_TEST) {
+ debug_test_codeword_dump(symbol, pOutput, rows * columns);
+ }
+#endif
+
+ /* Paint the C128 patterns */
+ for (r = 0; r < rows; r++) {
+ strcpy(dest, "");
+ for(c = 0; c < columns; c++) {
+ strcat(dest, C128Table[pOutput[r * columns + c]]);
+ }
+ expand(symbol, dest);
+ symbol->row_height[r] = 10;
+ }
+
+ symbol->output_options |= BARCODE_BIND;
+
+ if (symbol->border_width == 0) { /* Allow override if non-zero */
+ symbol->border_width = 1; /* AIM ISS-X-24 Section 4.6.1 b) (note change from previous default 2) */
+ }
+
+ return 0;
+}
diff --git a/backend/code.c b/backend/code.c
index 9d30e5a..455491c 100644
--- a/backend/code.c
+++ b/backend/code.c
@@ -1,8 +1,11 @@
-/* code.c - Handles Code 11, 39, 39+ and 93 */
+/* code.c - Handles Code 11, 39, 39+, 93, PZN, Channel and VIN */
+/* LOGMARS MIL-STD-1189 Rev. B https://apps.dtic.mil/dtic/tr/fulltext/u2/a473534.pdf */
+/* PZN https://www.ifaffm.de/mandanten/1/documents/04_ifa_coding_system/IFA_Info_Code_39_EN.pdf */
+/* PZN https://www.ifaffm.de/mandanten/1/documents/04_ifa_coding_system/IFA-Info_Check_Digit_Calculations_PZN_PPN_UDI_EN.pdf */
/*
libzint - the open source barcode library
- Copyright (C) 2008 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -28,161 +31,769 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
/* In version 0.5 this file was 1,553 lines long! */
-#include <string.h>
#include <stdio.h>
-#include <stdlib.h>
+#include <assert.h>
#include "common.h"
-#define SODIUM "0123456789-"
-#define SILVER "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd"
-
-static const char *C11Table[11] = {"111121", "211121", "121121", "221111", "112121", "212111", "122111",
- "111221", "211211", "211111", "112111"};
+#define SODIUM "0123456789-"
+#define SILVER "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd"
+#define ARSENIC "0123456789ABCDEFGHJKLMNPRSTUVWXYZ"
+static const 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 const 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 const 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 const 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 const 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];
-
-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;
+static const char *C39Table[43] = {
+ /* Code 39 character assignments (Table 1) */
+ "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"
+};
+
+static const char *EC39Ctrl[128] = {
+ /* Encoding the full ASCII character set in Code 39 (Table A2) */
+ "%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"
+};
+
+static const 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", "$", "%", "cF", "cG", "cH", "cI", "cJ",
+ "+", "cL", "-", ".", "/", "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 const 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"
+};
+
+/* *********************** CODE 11 ******************** */
+INTERNAL int code_11(struct zint_symbol *symbol, unsigned char source[], int length) { /* Code 11 */
+
+ int i;
+ int h, c_digit, c_weight, c_count, k_digit, k_weight, k_count;
+ int weight[122], error_number;
+ char dest[750]; /* 6 + 121 * 6 + 2 * 6 + 5 + 1 == 750 */
+ char checkstr[3];
+ int num_check_digits;
+
+ /* Suppresses clang-tidy clang-analyzer-core.UndefinedBinaryOperatorResult warning */
+ assert(length > 0);
+
+ if (length > 121) {
+ strcpy(symbol->errtxt, "320: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(SODIUM, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "321: Invalid characters in data");
+ return error_number;
+ }
+
+ if (symbol->option_2 < 0 || symbol->option_2 > 2) {
+ strcpy(symbol->errtxt, "339: Invalid check digit version");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+ if (symbol->option_2 == 2) {
+ num_check_digits = 0;
+ } else if (symbol->option_2 == 1) {
+ num_check_digits = 1;
+ } else {
+ num_check_digits = 2;
+ }
+
+ 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]);
+ }
+
+ if (num_check_digits) {
+ /* 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;
+
+ if (num_check_digits == 1) {
+ checkstr[0] = itoc(c_digit);
+ if (checkstr[0] == 'A') {
+ checkstr[0] = '-';
+ }
+ checkstr[1] = '\0';
+ lookup(SODIUM, C11Table, checkstr[0], dest);
+ } else {
+ 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 */
+ strcat(dest, "11221");
+
+ expand(symbol, dest);
+
+ ustrcpy(symbol->text, source);
+ if (num_check_digits) {
+ ustrcat(symbol->text, checkstr);
+ }
+ return error_number;
+}
+
+/* Code 39 */
+INTERNAL int c39(struct zint_symbol *symbol, unsigned char source[], const size_t length) {
+ int i;
+ int counter;
+ int error_number;
+ char dest[880]; /* 10 (Start) + 85 * 10 + 10 (Check) + 9 (Stop) + 1 = 880 */
+ char localstr[2] = {0};
+
+ counter = 0;
+
+ if ((symbol->option_2 < 0) || (symbol->option_2 > 1)) {
+ symbol->option_2 = 0;
+ }
+
+ if ((symbol->symbology == BARCODE_LOGMARS) && (length > 30)) { /* MIL-STD-1189 Rev. B Section 5.2.6.2 */
+ strcpy(symbol->errtxt, "322: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ } else if ((symbol->symbology == BARCODE_HIBC_39) && (length > 68)) { /* Prevent encoded_data out-of-bounds >= 143 due to wider 'wide' bars */
+ strcpy(symbol->errtxt, "319: Input too long"); /* Note use 319 (2of5 range) as 340 taken by CODE128 */
+ return ZINT_ERROR_TOO_LONG;
+ } else if (length > 85) {
+ strcpy(symbol->errtxt, "323: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ to_upper(source);
+ error_number = is_sane(SILVER, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "324: Invalid characters in data");
+ return error_number;
+ }
+
+ /* Start character */
+ strcpy(dest, "1211212111");
+
+ for (i = 0; i < (int) length; i++) {
+ lookup(SILVER, C39Table, source[i], dest);
+ counter += posn(SILVER, source[i]);
+ }
+
+ if (symbol->option_2 == 1) {
+
+ char check_digit;
+ 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 */
+ strcat(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, "*");
+ ustrcat(symbol->text, source);
+ ustrcat(symbol->text, localstr);
+ ustrcat(symbol->text, "*");
+ } else {
+ ustrcpy(symbol->text, source);
+ ustrcat(symbol->text, localstr);
+ }
+ return error_number;
+}
+
+/* Pharmazentral Nummer (PZN) */
+INTERNAL int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length) {
+
+ int i, error_number, zeroes;
+ unsigned int count, check_digit;
+ char localstr[11];
+
+ if (length > 7) {
+ strcpy(symbol->errtxt, "325: Input wrong length");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "326: Invalid characters in data");
+ return error_number;
+ }
+
+ localstr[0] = '-';
+ zeroes = 7 - length + 1;
+ for (i = 1; i < zeroes; i++)
+ localstr[i] = '0';
+ ustrcpy(localstr + zeroes, source);
+
+ count = 0;
+ for (i = 1; i < 8; i++) {
+ count += i * ctoi(localstr[i]);
+ }
+
+ check_digit = count % 11;
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("PZN: %s, check digit %d\n", localstr, check_digit);
+ }
+
+ if (check_digit == 10) {
+ strcpy(symbol->errtxt, "327: Invalid PZN Data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ localstr[8] = itoc(check_digit);
+ localstr[9] = '\0';
+ error_number = c39(symbol, (unsigned char *) localstr, strlen(localstr));
+ ustrcpy(symbol->text, "PZN ");
+ ustrcat(symbol->text, localstr);
+ return error_number;
+}
+
+/* Extended Code 39 - ISO/IEC 16388:2007 Annex A */
+INTERNAL int ec39(struct zint_symbol *symbol, unsigned char source[], int length) {
+
+ unsigned char buffer[85 * 2 + 1] = {0};
+ int i;
+ int error_number;
+
+ if (length > 85) {
+ strcpy(symbol->errtxt, "328: Input too long");
+ return ZINT_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, "329: Invalid characters in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ ustrcat(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 is an advancement on Code 39 and the definition is a lot tighter */
+INTERNAL int c93(struct zint_symbol *symbol, unsigned char source[], int length) {
+
+ /* 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, "330: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ /* Message Content */
+ for (i = 0; i < length; i++) {
+ if (source[i] > 127) {
+ /* Cannot encode extended ASCII */
+ strcpy(symbol->errtxt, "331: Invalid characters in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ strcat(buffer, C93Ctrl[source[i]]);
+ symbol->text[i] = source[i] ? source[i] : ' ';
+ }
+
+ /* Now we can check the true length of the barcode */
+ h = (int) strlen(buffer);
+ if (h > 107) {
+ strcpy(symbol->errtxt, "332: Input too long");
+ return ZINT_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 */
+ strcat(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;
+}
+
+typedef const struct s_channel_precalc {
+ long value; unsigned char B[8]; unsigned char S[8]; unsigned char bmax[7]; unsigned char smax[7];
+} channel_precalc;
+
+//#define CHANNEL_GENERATE_PRECALCS
+
+#ifdef CHANNEL_GENERATE_PRECALCS
+/* To generate precalc tables uncomment define and run "./test_channel -f generate -g" and place result in "channel_precalcs.h" */
+static void channel_generate_precalc(int channels, long value, int mod, int last, int B[8], int S[8], int bmax[7], int smax[7]) {
+ int i;
+ if (value == mod) printf("static channel_precalc channel_precalcs%d[] = {\n", channels);
+ printf(" { %7ld, {", value); for (i = 0; i < 8; i++) printf(" %d,", B[i]); printf(" },");
+ printf(" {"); for (i = 0; i < 8; i++) printf(" %d,", S[i]); printf(" },");
+ printf(" {"); for (i = 0; i < 7; i++) printf(" %d,", bmax[i]); printf(" },");
+ printf(" {"); for (i = 0; i < 7; i++) printf(" %d,", smax[i]); printf(" }, },\n");
+ if (value == last) printf("};\n");
+}
+#else
+#include "channel_precalcs.h"
+#endif
+
+static long channel_copy_precalc(channel_precalc precalc, int B[8], int S[8], int bmax[7], int smax[7]) {
+ int i;
+
+ for (i = 0; i < 7; i++) {
+ B[i] = precalc.B[i];
+ S[i] = precalc.S[i];
+ bmax[i] = precalc.bmax[i];
+ smax[i] = precalc.smax[i];
+ }
+ B[7] = precalc.B[7];
+ S[7] = precalc.S[7];
+
+ return precalc.value;
+}
+
+/* CHNCHR is adapted from ANSI/AIM BC12-1998 Annex D Figure D5 and is Copyright (c) AIM 1997 */
+
+/* It is used here on the understanding that it forms part of the specification
+ for Channel Code and therefore its 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 member companies, or individual officers
+ assume no liability for the use of this document." */
+
+static void CHNCHR(int channels, long target_value, int B[8], int S[8]) {
+ /* Use of initial pre-calculations taken from Barcode Writer in Pure PostScript (bwipp)
+ * Copyright (c) 2004-2020 Terry Burton (MIT/X-Consortium license) */
+ static channel_precalc initial_precalcs[6] = {
+ { 0, { 1, 1, 1, 1, 1, 2, 1, 2, }, { 1, 1, 1, 1, 1, 1, 1, 3, }, { 1, 1, 1, 1, 1, 3, 2, }, { 1, 1, 1, 1, 1, 3, 3, }, },
+ { 0, { 1, 1, 1, 1, 2, 1, 1, 3, }, { 1, 1, 1, 1, 1, 1, 1, 4, }, { 1, 1, 1, 1, 4, 3, 3, }, { 1, 1, 1, 1, 4, 4, 4, }, },
+ { 0, { 1, 1, 1, 2, 1, 1, 2, 3, }, { 1, 1, 1, 1, 1, 1, 1, 5, }, { 1, 1, 1, 5, 4, 4, 4, }, { 1, 1, 1, 5, 5, 5, 5, }, },
+ { 0, { 1, 1, 2, 1, 1, 2, 1, 4, }, { 1, 1, 1, 1, 1, 1, 1, 6, }, { 1, 1, 6, 5, 5, 5, 4, }, { 1, 1, 6, 6, 6, 6, 6, }, },
+ { 0, { 1, 2, 1, 1, 2, 1, 1, 5, }, { 1, 1, 1, 1, 1, 1, 1, 7, }, { 1, 7, 6, 6, 6, 5, 5, }, { 1, 7, 7, 7, 7, 7, 7, }, },
+ { 0, { 2, 1, 1, 2, 1, 1, 2, 5, }, { 1, 1, 1, 1, 1, 1, 1, 8, }, { 8, 7, 7, 7, 6, 6, 6, }, { 8, 8, 8, 8, 8, 8, 8, }, },
+ };
+ int bmax[7], smax[7];
+ long value = 0;
+
+ channel_copy_precalc(initial_precalcs[channels - 3], B, S, bmax, smax);
+
+#ifndef CHANNEL_GENERATE_PRECALCS
+ if (channels == 7 && target_value >= channel_precalcs7[0].value) {
+ value = channel_copy_precalc(channel_precalcs7[(target_value / channel_precalcs7[0].value) - 1], B, S, bmax, smax);
+ } else if (channels == 8 && target_value >= channel_precalcs8[0].value) {
+ value = channel_copy_precalc(channel_precalcs8[(target_value / channel_precalcs8[0].value) - 1], B, S, bmax, smax);
+ }
+#endif
+
+ goto chkchr;
+
+ls0:smax[1] = smax[0] + 1 - S[0]; B[0] = 1;
+ if (S[0] == 1) goto nb0;
+lb0: bmax[1] = bmax[0] + 1 - B[0]; S[1] = 1;
+ls1: smax[2] = smax[1] + 1 - S[1]; B[1] = 1;
+ if (S[0] + B[0] + S[1] == 3) goto nb1;
+lb1: bmax[2] = bmax[1] + 1 - B[1]; S[2] = 1;
+ls2: smax[3] = smax[2] + 1 - S[2]; B[2] = 1;
+ if (B[0] + S[1] + B[1] + S[2] == 4) goto nb2;
+lb2: bmax[3] = bmax[2] + 1 - B[2]; S[3] = 1;
+ls3: smax[4] = smax[3] + 1 - S[3]; B[3] = 1;
+ if (B[1] + S[2] + B[2] + S[3] == 4) goto nb3;
+lb3: bmax[4] = bmax[3] + 1 - B[3]; S[4] = 1;
+ls4: smax[5] = smax[4] + 1 - S[4]; B[4] = 1;
+ if (B[2] + S[3] + B[3] + S[4] == 4) goto nb4;
+lb4: bmax[5] = bmax[4] + 1 - B[4]; S[5] = 1;
+ls5: smax[6] = smax[5] + 1 - S[5]; B[5] = 1;
+ if (B[3] + S[4] + B[4] + S[5] == 4) goto nb5;
+lb5: bmax[6] = bmax[5] + 1 - B[5]; S[6] = 1;
+ls6: S[7] = smax[6] + 1 - S[6]; B[6] = 1;
+ if (B[4] + S[5] + B[5] + S[6] == 4) goto nb6;
+lb6: B[7] = bmax[6] + 1 - B[6];
+ if (B[5] + S[6] + B[6] + S[7] + B[7] == 5) goto nb6;
+chkchr:
+#ifdef CHANNEL_GENERATE_PRECALCS
+ if (channels == 7 && value && value % 115338 == 0) { /* 115338 == (576688 + 2) / 5 */
+ channel_generate_precalc(channels, value, 115338, 115338 * (5 - 1), B, S, bmax, smax);
+ } else if (channels == 8 && value && value % 119121 == 0) { /* 119121 == (7742862 + 3) / 65 */
+ channel_generate_precalc(channels, value, 119121, 119121 * (65 - 1), B, S, bmax, smax);
+ }
+#endif
+ if (value == target_value) return;
+ value++;
+nb6: if (++B[6] <= bmax[6]) goto lb6;
+ if (++S[6] <= smax[6]) goto ls6;
+nb5: if (++B[5] <= bmax[5]) goto lb5;
+ if (++S[5] <= smax[5]) goto ls5;
+nb4: if (++B[4] <= bmax[4]) goto lb4;
+ if (++S[4] <= smax[4]) goto ls4;
+nb3: if (++B[3] <= bmax[3]) goto lb3;
+ if (++S[3] <= smax[3]) goto ls3;
+nb2: if (++B[2] <= bmax[2]) goto lb2;
+ if (++S[2] <= smax[2]) goto ls2;
+nb1: if (++B[1] <= bmax[1]) goto lb1;
+ if (++S[1] <= smax[1]) goto ls1;
+nb0: if (++B[0] <= bmax[0]) goto lb0;
+ if (++S[0] <= smax[0]) goto ls0;
+}
+
+/* Channel Code - According to ANSI/AIM BC12-1998 */
+INTERNAL int channel_code(struct zint_symbol *symbol, unsigned char source[], int length) {
+ int S[8] = {0}, B[8] = {0};
+ long target_value = 0;
+ char pattern[30];
+ int channels, i;
+ int error_number, range = 0, zeroes;
+ char hrt[9];
+
+ if (length > 7) {
+ strcpy(symbol->errtxt, "333: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "334: Invalid characters in data");
+ return error_number;
+ }
+
+ if ((symbol->option_2 < 3) || (symbol->option_2 > 8)) {
+ channels = 0;
+ } else {
+ channels = symbol->option_2;
+ }
+
+ for (i = 0; i < length; i++) {
+ target_value *= 10;
+ target_value += ctoi((char) source[i]);
+ }
+
+ if (channels == 0) {
+ channels = length + 1;
+ if (target_value > 576688 && channels < 8) {
+ channels = 8;
+ } else if (target_value > 44072 && channels < 7) {
+ channels = 7;
+ } else if (target_value > 3493 && channels < 6) {
+ channels = 6;
+ } else if (target_value > 292 && channels < 5) {
+ channels = 5;
+ } else if (target_value > 26 && channels < 4) {
+ channels = 4;
+ }
+ }
+ if (channels == 2) {
+ channels = 3;
+ }
+
+ 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, "335: Value out of range");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ CHNCHR(channels, target_value, B, S);
+
+ strcpy(pattern, "111111111"); /* Finder pattern */
+ for (i = 8 - channels; i < 8; i++) {
+ char part[3];
+ part[0] = itoc(S[i]);
+ part[1] = itoc(B[i]);
+ part[2] = '\0';
+ strcat(pattern, part);
+ }
+
+ zeroes = channels - 1 - length;
+ if (zeroes < 0) {
+ zeroes = 0;
+ }
+ memset(hrt, '0', zeroes);
+ ustrcpy(hrt + zeroes, source);
+ ustrcpy(symbol->text, hrt);
+
+ expand(symbol, pattern);
+
+ return error_number;
+}
+
+/* Vehicle Identification Number (VIN) */
+INTERNAL int vin(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length) {
+
+ /* This code verifies the check digit present in North American VIN codes */
+
+ char local_source[18];
+ char dest[200];
+ char input_check;
+ char output_check;
+ int value[17];
+ int weight[17] = {8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2};
+ int sum;
+ int i;
+ int length = (int) in_length;
+
+ // Check length
+ if (length != 17) {
+ strcpy(symbol->errtxt, "336: Input wrong length, 17 characters required");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ // Check input characters, I, O and Q are not allowed
+ if (is_sane(ARSENIC, source, length) == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "337: Invalid characters in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ ustrcpy(local_source, source);
+
+ to_upper((unsigned char *) local_source);
+
+
+ // Check digit only valid for North America
+ if (local_source[0] >= '1' && local_source[0] <= '5') {
+ input_check = local_source[8];
+
+ for (i = 0; i < 17; i++) {
+ if ((local_source[i] >= '0') && (local_source[i] <= '9')) {
+ value[i] = local_source[i] - '0';
+ } else if ((local_source[i] >= 'A') && (local_source[i] <= 'I')) {
+ value[i] = (local_source[i] - 'A') + 1;
+ } else if ((local_source[i] >= 'J') && (local_source[i] <= 'R')) {
+ value[i] = (local_source[i] - 'J') + 1;
+ } else if ((local_source[i] >= 'S') && (local_source[i] <= 'Z')) {
+ value[i] = (local_source[i] - 'S') + 2;
+ }
+ }
+
+ sum = 0;
+ for (i = 0; i < 17; i++) {
+ sum += value[i] * weight[i];
+ }
+
+ output_check = '0' + (sum % 11);
+
+ if (output_check == ':') {
+ // Check digit was 10
+ output_check = 'X';
+ }
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Producing VIN code: %s\n", local_source);
+ printf("Input check was %c, calculated check is %c\n", input_check, output_check);
+ }
+
+ if (input_check != output_check) {
+ strcpy(symbol->errtxt, "338: Invalid check digit in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ }
+
+ /* Start character */
+ strcpy(dest, "1211212111");
+
+ /* Import character 'I' prefix? */
+ if (symbol->option_2 & 1) {
+ strcat(dest, "1121122111");
+ }
+
+ // Copy glyphs to symbol
+ for (i = 0; i < 17; i++) {
+ lookup(SILVER, C39Table, local_source[i], dest);
+ }
+
+ strcat(dest, "121121211");
+
+ ustrcpy(symbol->text, local_source);
+ expand(symbol, dest);
+
+ return 0;
}
diff --git a/backend/code1.c b/backend/code1.c
new file mode 100644
index 0000000..8ba456b
--- /dev/null
+++ b/backend/code1.c
@@ -0,0 +1,1770 @@
+/* code1.c - USS Code One */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2009-2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include "common.h"
+#include "code1.h"
+#include "reedsol.h"
+#include "large.h"
+#include <stdio.h>
+#include <math.h>
+
+static 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);
+ }
+ }
+}
+
+static 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);
+ }
+ }
+ }
+}
+
+static 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);
+ }
+ }
+}
+
+static 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);
+ }
+ }
+}
+
+static 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;
+}
+
+static int dq4bi(unsigned char source[], int sourcelen, int position) {
+ int i;
+
+ for (i = 0; ((position + i) < sourcelen) && isedi(source[position + i]); i++);
+
+ if ((position + i) == sourcelen) {
+ /* Reached end of input */
+ return 0;
+ }
+ if (i == 0) {
+ /* Not EDI */
+ 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;
+}
+
+static 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, 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 = ceil(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 = ceil(ascii_count);
+ c40_count = ceil(c40_count);
+ text_count = ceil(text_count);
+ edi_count = ceil(edi_count);
+ byte_count = ceil(byte_count);
+ best_scheme = C1_ASCII;
+
+ if (sp == sourcelen) {
+ /* Step K */
+ int best_count = (int) edi_count;
+
+ if (text_count <= best_count) {
+ best_count = (int) text_count;
+ best_scheme = C1_TEXT;
+ }
+
+ if (c40_count <= best_count) {
+ best_count = (int) c40_count;
+ best_scheme = C1_C40;
+ }
+
+ if (ascii_count <= best_count) {
+ best_count = (int) ascii_count;
+ best_scheme = C1_ASCII;
+ }
+
+ if (byte_count <= best_count) {
+ // best_count = (int) 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 {
+ 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;
+ }
+ }
+
+ return best_scheme;
+}
+
+static 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, p, 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;
+ memset(c40_buffer, 0, sizeof(*c40_buffer));
+ c40_p = 0;
+ memset(text_buffer, 0, sizeof(*text_buffer));
+ text_p = 0;
+ memset(edi_buffer, 0, sizeof(*edi_buffer));
+ edi_p = 0;
+ strcpy(decimal_binary, "");
+
+ if ((symbol->input_mode & 0x07) == GS1_MODE) {
+ gs1 = 1;
+ } else {
+ gs1 = 0;
+ }
+ if (gs1) {
+ /* FNC1 */
+ target[tp] = 232;
+ tp++;
+ }
+
+ /* 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;
+ bin_append(15, 4, decimal_binary);
+ }
+ }
+
+ 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[i] >= '0') && (source[i] <= '9'))) {
+ latch = 1;
+ }
+ }
+
+ if (!(latch)) {
+ next_mode = C1_DECIMAL;
+ bin_append(15, 4, decimal_binary);
+ }
+ }
+ }
+
+ if (next_mode == C1_ASCII) { /* Step B3 */
+ if (istwodigits(source, length, sp)) {
+ 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[i] >= '0') && (source[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; /* FNC4 */
+ tp++;
+ target[tp] = (source[sp] - 128) + 1;
+ tp++;
+ sp++;
+ } else {
+ /* Step B8 */
+ if ((gs1) && (source[sp] == '[')) {
+ target[tp] = 232; /* FNC1 */
+ tp++;
+ sp++;
+ } else {
+ target[tp] = source[sp] + 1;
+ tp++;
+ sp++;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (current_mode == C1_C40) {
+ /* Step C - C40 encodation */
+
+ next_mode = C1_C40;
+ if (c40_p == 0) {
+ int done = 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) {
+ int latch = 0;
+ 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; /* Unlatch */
+ tp++;
+ } else {
+ int shift_set, value;
+ if (source[sp] > 127) {
+ c40_buffer[c40_p] = 1;
+ c40_p++;
+ c40_buffer[c40_p] = 30; /* Upper Shift */
+ c40_p++;
+ 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 */
+
+ next_mode = C1_TEXT;
+ if (text_p == 0) {
+ int done = 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) {
+ int latch = 0;
+ 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 {
+ int shift_set, value;
+ 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 */
+
+ 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;
+ }
+ }
+
+ if ((length - sp) >= 8) {
+ int latch = 0;
+ 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;
+ }
+ }
+
+ if (!((isedi(source[sp]) && isedi(source[sp + 1])) && isedi(source[sp + 2]))) {
+ next_mode = C1_ASCII;
+ }
+ }
+
+ if (next_mode != C1_EDI) {
+ target[tp] = 255; /* Unlatch */
+ tp++;
+ } else {
+ int value = 0;
+ 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 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) {
+ size_t bits_left_in_byte, target_count;
+ int sub_target;
+ /* Finish Decimal mode and go back to ASCII */
+
+ bin_append(63, 6, decimal_binary); /* 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) {
+ bin_append(1, 2, decimal_binary);
+ }
+
+ if ((bits_left_in_byte == 4) || (bits_left_in_byte == 6)) {
+ if (decimal_count >= 1) {
+ bin_append(ctoi(source[sp]) + 1, 4, decimal_binary);
+ sp++;
+ } else {
+ bin_append(15, 4, decimal_binary);
+ }
+ }
+
+ if (bits_left_in_byte == 6) {
+ bin_append(1, 2, decimal_binary);
+ }
+
+ /* Binary buffer is full - transfer to target */
+ if (target_count >= 1) {
+ sub_target = 0;
+
+ for (i = 0; i < 8; i++) {
+ if (decimal_binary[i] == '1') {
+ sub_target += 128 >> i;
+ }
+ }
+ target[tp] = sub_target;
+ tp++;
+ }
+ if (target_count >= 2) {
+ sub_target = 0;
+
+ for (i = 0; i < 8; i++) {
+ if (decimal_binary[i + 8] == '1') {
+ sub_target += 128 >> i;
+ }
+ }
+ target[tp] = sub_target;
+ tp++;
+ }
+ if (target_count == 3) {
+ sub_target = 0;
+
+ for (i = 0; i < 8; i++) {
+ if (decimal_binary[i + 16] == '1') {
+ sub_target += 128 >> i;
+ }
+ }
+ target[tp] = sub_target;
+ tp++;
+ }
+
+ next_mode = C1_ASCII;
+ } else {
+ /* There are three digits - convert the value to binary */
+ bin_append((100 * ctoi(source[sp])) + (10 * ctoi(source[sp + 1])) + ctoi(source[sp + 2]) + 1, 10, decimal_binary);
+ 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 */
+
+ for (p = 0; p < 8; p++) {
+ if (decimal_binary[p] == '1') {
+ target1 += (0x80 >> p);
+ }
+ if (decimal_binary[p + 8] == '1') {
+ target2 += (0x80 >> p);
+ }
+ if (decimal_binary[p + 16] == '1') {
+ target3 += (0x80 >> p);
+ }
+ }
+ target[tp] = target1;
+ tp++;
+ target[tp] = target2;
+ tp++;
+ target[tp] = target3;
+ tp++;
+
+ strcpy(temp_binary, "");
+ if (strlen(decimal_binary) > 24) {
+ for (i = 0; i <= (int) (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, "511: 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) {
+ size_t bits_left_in_byte, target_count;
+ int sub_target;
+ /* Finish Decimal mode and go back to ASCII */
+
+ bin_append(63, 6, decimal_binary); /* 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) {
+ bin_append(1, 2, decimal_binary);
+ }
+
+ if ((bits_left_in_byte == 4) || (bits_left_in_byte == 6)) {
+ bin_append(15, 4, decimal_binary);
+ }
+
+ if (bits_left_in_byte == 6) {
+ bin_append(1, 2, decimal_binary);
+ }
+
+ /* Binary buffer is full - transfer to target */
+ if (target_count >= 1) {
+ sub_target = 0;
+
+ for (i = 0; i < 8; i++) {
+ if (decimal_binary[i] == '1') {
+ sub_target += 128 >> i;
+ }
+ }
+ target[tp] = sub_target;
+ tp++;
+ }
+ if (target_count >= 2) {
+ sub_target = 0;
+
+ for (i = 0; i < 8; i++) {
+ if (decimal_binary[i + 8] == '1') {
+ sub_target += 128 >> i;
+ }
+ }
+ target[tp] = sub_target;
+ tp++;
+ }
+ if (target_count == 3) {
+ sub_target = 0;
+
+ for (i = 0; i < 8; i++) {
+ if (decimal_binary[i + 16] == '1') {
+ sub_target += 128 >> i;
+ }
+ }
+ 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, "512: Input data too long");
+ return 0;
+ }
+ /*
+ printf("targets:\n");
+ for(i = 0; i < tp; i++) {
+ printf("[%d]", target[i]);
+ }
+ printf("\n");
+ */
+ return tp;
+}
+
+static 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);
+ }
+ }
+ }
+}
+
+INTERNAL int code_one(struct zint_symbol *symbol, unsigned char source[], int length) {
+ int size = 1, i, j;
+
+ char datagrid[136][120];
+ int row, col;
+ int sub_version = 0;
+
+ if ((symbol->option_2 < 0) || (symbol->option_2 > 10)) {
+ strcpy(symbol->errtxt, "513: Invalid symbol size");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ if (symbol->option_2 == 9) {
+ /* Version S */
+ int codewords;
+ large_int elreg;
+ unsigned int data[15], ecc[15];
+ int stream[30];
+ int block_width;
+
+ if (length > 18) {
+ strcpy(symbol->errtxt, "514: Input data too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ if (is_sane(NEON, source, length) == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "515: Invalid input data (Version S encodes numeric input only)");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ sub_version = 3;
+ codewords = 12;
+ block_width = 6; /* Version S-30 */
+ if (length <= 12) {
+ /* Version S-20 */
+ sub_version = 2;
+ codewords = 8;
+ block_width = 4;
+ }
+ if (length <= 6) {
+ /* Version S-10 */
+ sub_version = 1;
+ codewords = 4;
+ block_width = 2;
+ }
+
+ large_load_str_u64(&elreg, source, length);
+
+ for (i = 0; i < 15; i++) {
+ data[i] = 0;
+ ecc[i] = 0;
+ }
+
+ large_uint_array(&elreg, data, codewords, 5 /*bits*/);
+
+ 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[80] = {0}; /* Allow for doubled digits */
+ unsigned int ecc[22];
+ unsigned int stream[60];
+ int data_length;
+ int data_cw, ecc_cw, block_width;
+
+ if (length > 80) {
+ strcpy(symbol->errtxt, "519: Input data too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ data_length = c1_encode(symbol, source, data, length);
+
+ if (data_length == 0) {
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ if (data_length > 38) {
+ strcpy(symbol->errtxt, "516: Input data too long");
+ return ZINT_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;
+ int data_blocks;
+
+ for (i = 0; i < 1500; i++) {
+ data[i] = 0;
+ }
+ data_length = c1_encode(symbol, source, data, length);
+
+ if (data_length == 0) {
+ strcpy(symbol->errtxt, "517: Input data is too long");
+ return ZINT_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;
+ }
+
+ if ((symbol-> option_2 != 0) && (symbol->option_2 < size)) {
+ strcpy(symbol->errtxt, "518: Input too long for selected symbol size");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ 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];
+
+ rs_init_gf(0x12d);
+ rs_init_code(c1_ecc_blocks[size - 1], 0);
+ 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++;
+ }
+ }
+
+ 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 0000000..aaf4898
--- /dev/null
+++ b/backend/code1.h
@@ -0,0 +1,102 @@
+/* code1.h - Lookup info for USS Code One */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2009-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+
+static const char 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 const char 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 const char 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 const char 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 const unsigned short int c1_height[] = {
+ 16, 22, 28, 40, 52, 70, 104, 148
+};
+
+static const unsigned short int c1_width[] = {
+ 18, 22, 32, 42, 54, 76, 98, 134
+};
+
+static const unsigned short int c1_data_length[] = {
+ 10, 19, 44, 91, 182, 370, 732, 1480
+};
+
+static const unsigned short int c1_ecc_length[] = {
+ 10, 16, 26, 44, 70, 140, 280, 560
+};
+
+static const unsigned short int c1_blocks[] = {
+ 1, 1, 1, 1, 1, 2, 4, 8
+};
+
+static const unsigned short int c1_data_blocks[] = {
+ 10, 19, 44, 91, 182, 185, 183, 185
+};
+
+static const unsigned short int c1_ecc_blocks[] = {
+ 10, 16, 26, 44, 70, 70, 70, 70
+};
+
+static const unsigned short int c1_grid_width[] = {
+ 4, 5, 7, 9, 12, 17, 22, 30
+};
+
+static const unsigned short 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
diff --git a/backend/code128.c b/backend/code128.c
index f0f985d..b69613a 100644
--- a/backend/code128.c
+++ b/backend/code128.c
@@ -2,7 +2,7 @@
/*
libzint - the open source barcode library
- Copyright (C) 2008 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2008-2020 Robin Stuart <rstuart114@gmail.com>
Bugfixes thanks to Christian Sakowski and BogDan Vatra
Redistribution and use in source and binary forms, with or without
@@ -29,162 +29,208 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
#include <stdio.h>
#include <string.h>
-#include <stdlib.h>
#ifdef _MSC_VER
-#include <malloc.h>
+#include <malloc.h>
#endif
+#include <assert.h>
#include "common.h"
+#include "code128.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
+/* Code 128 tables checked against ISO/IEC 15417:2007 */
-#define DPDSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*"
+static const char *C128Table[107] = {
+ /* Code 128 character encodation - Table 1 */
+ "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"
+};
-static int list[2][170];
+/* Determine appropriate mode for a given character */
+INTERNAL int parunmodd(const unsigned char llyth) {
+ int modd;
-/* Code 128 tables checked against ISO/IEC 15417:2007 */
+ 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;
+ }
-static const 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;
+ return modd;
}
/**
* bring together same type blocks
*/
-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++;
- }
- }
+static void grwp(int list[2][C128_MAX], int *indexliste) {
+
+ /* bring together same type blocks */
+ if (*(indexliste) > 1) {
+ int i = 1;
+ while (i < *(indexliste)) {
+ if (list[1][i - 1] == list[1][i]) {
+ int j;
+ /* bring together */
+ list[0][i - 1] = list[0][i - 1] + list[0][i];
+ j = i + 1;
+
+ /* decrease 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++;
+ }
+ }
}
/**
* Implements rules from ISO 15417 Annex E
*/
-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);
+INTERNAL void dxsmooth(int list[2][C128_MAX], int *indexliste) {
+ int i, last, next;
+
+ for (i = 0; i < *(indexliste); i++) {
+ int current = list[1][i]; /* Either ABORC, AORB, SHIFTA or SHIFTB */
+ int 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 (current == ABORC) {
+ if ((*(indexliste) == 1) && (length == 2)) {
+ /* Rule 1a */
+ list[1][i] = LATCHC;
+ current = LATCHC;
+ } else if (length >= 4) {
+ /* Rule 1b */
+ list[1][i] = LATCHC;
+ current = LATCHC;
+ } else {
+ current = AORB; /* Determine below */
+ }
+ }
+ if (current == AORB) {
+ if (next == SHIFTA) {
+ /* Rule 1c */
+ list[1][i] = LATCHA;
+ } else {
+ /* Rule 1d */
+ list[1][i] = LATCHB;
+ }
+ } else if (current == SHIFTA) {
+ /* Rule 1c */
+ list[1][i] = LATCHA;
+ } else if (current == SHIFTB) { /* Unless LATCHC set above, can only be SHIFTB */
+ /* Rule 1d */
+ list[1][i] = LATCHB;
+ }
+ } else {
+ if (current == ABORC) {
+ if (length >= 4) {
+ /* Rule 3 */
+ list[1][i] = LATCHC;
+ current = LATCHC;
+ } else {
+ current = AORB; /* Determine below */
+ }
+ }
+ if (current == AORB) {
+ if (last == LATCHA || last == SHIFTB) { /* Maintain state */
+ list[1][i] = LATCHA;
+ } else if (last == LATCHB || last == SHIFTA) { /* Maintain state */
+ list[1][i] = LATCHB;
+ } else if (next == SHIFTA) {
+ list[1][i] = LATCHA;
+ } else {
+ list[1][i] = LATCHB;
+ }
+ } else if (current == SHIFTA) {
+ if (length > 1) {
+ /* Rule 4 */
+ list[1][i] = LATCHA;
+ } else if (last == LATCHA || last == SHIFTB) { /* Maintain state */
+ list[1][i] = LATCHA;
+ } else if (last == LATCHC) {
+ list[1][i] = LATCHA;
+ }
+ } else if (current == SHIFTB) { /* Unless LATCHC set above, can only be SHIFTB */
+ if (length > 1) {
+ /* Rule 5 */
+ list[1][i] = LATCHB;
+ } else if (last == LATCHB || last == SHIFTA) { /* Maintain state */
+ list[1][i] = LATCHB;
+ } else if (last == LATCHC) {
+ list[1][i] = LATCHB;
+ }
+ }
+ } /* Rule 2 is implemented elsewhere, Rule 6 is implied */
+ }
+
+ grwp(list, indexliste);
}
/**
* Translate Code 128 Set A characters into barcodes.
- * This set handles all control characters NULL to US.
+ * This set handles all control characters NUL to US.
*/
-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)++;
+static void c128_set_a(unsigned char source, char dest[], int values[], int *bar_chars) {
+
+ if (source > 127) {
+ if (source < 160) {
+ strcat(dest, C128Table[(source - 128) + 64]);
+ values[(*bar_chars)] = (source - 128) + 64;
+ } else {
+ strcat(dest, C128Table[(source - 128) - 32]);
+ values[(*bar_chars)] = (source - 128) - 32;
+ }
+ } else {
+ if (source < 32) {
+ strcat(dest, C128Table[source + 64]);
+ values[(*bar_chars)] = source + 64;
+ } else {
+ strcat(dest, C128Table[source - 32]);
+ values[(*bar_chars)] = source - 32;
+ }
+ }
+ (*bar_chars)++;
}
/**
@@ -192,822 +238,834 @@ void c128_set_a(unsigned char source, char dest[], int values[], int *bar_chars)
* This set handles all characters which are not part of long numbers and not
* control characters.
*/
-void c128_set_b(unsigned char source, char dest[], int values[], int *bar_chars)
-{
- 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)++;
+static void c128_set_b(unsigned char source, char dest[], int values[], int *bar_chars) {
+ if (source > 127) {
+ strcat(dest, C128Table[source - 32 - 128]);
+ values[(*bar_chars)] = source - 32 - 128;
+ } else {
+ strcat(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)++;
+/* Translate Code 128 Set C characters into barcodes
+ * This set handles numbers in a compressed form
+ */
+static void c128_set_c(unsigned char source_a, unsigned char source_b, char dest[], int values[], int *bar_chars) {
+ int weight;
+
+ weight = (10 * ctoi(source_a)) + ctoi(source_b);
+ strcat(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,values[170] = { 0 }, bar_characters, read, total_sum;
- int error_number, indexchaine, indexliste, sourcelen, f_state;
- char set[170] = { ' ' }, fset[170] = { ' ' }, mode, last_set, current_set = ' ';
- float glyph_count;
- char dest[1000];
-
- error_number = 0;
- strcpy(dest, "");
-
- sourcelen = length;
-
- j = 0;
- bar_characters = 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] & 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] & 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 = ' ';
- 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') {
- glyph_count = glyph_count + 2.0;
- }
- } else {
- if((fset[i] == 'F') && (fset[i - 1] != 'F')) {
- glyph_count = glyph_count + 2.0;
- }
- if((fset[i] != 'F') && (fset[i - 1] == 'F')) {
- 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;
+/* Handle Code 128, 128B and HIBC 128 */
+INTERNAL int code_128(struct zint_symbol *symbol, const unsigned char source[], const size_t length) {
+ int i, j, k, values[C128_MAX] = {0}, bar_characters, read, total_sum;
+ int error_number, indexchaine, indexliste, f_state;
+ int sourcelen;
+ int list[2][C128_MAX] = {{0}};
+ char set[C128_MAX] = {0}, fset[C128_MAX], mode, last_set, current_set = ' ';
+ float glyph_count;
+ char dest[1000];
+
+ /* Suppresses clang-analyzer-core.UndefinedBinaryOperatorResult warning on fset which is fully set */
+ assert(length > 0);
+
+ error_number = 0;
+ strcpy(dest, "");
+
+ sourcelen = length;
+
+ bar_characters = 0;
+ f_state = 0;
+
+ if (sourcelen > C128_MAX) {
+ /* This only blocks ridiculously long input - the actual length of the
+ resulting barcode depends on the type of data, so this is trapped later */
+ strcpy(symbol->errtxt, "340: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ /* Detect extended ASCII characters */
+ for (i = 0; i < sourcelen; i++) {
+ fset[i] = source[i] >= 128 ? 'f' : ' ';
+ }
+
+ /* 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; ((i + j) < sourcelen) && (fset[i + j] == ' '); j++);
+ /* Count how many 8859-1 beyond */
+ k = 0;
+ if (i + j < sourcelen) {
+ for (k = 1; ((i + j + k) < sourcelen) && (fset[i + j + k] != ' '); k++);
+ }
+ if (j < 3 || (j < 5 && k > 2)) {
+ /* Change to shifting back rather than latching back */
+ /* Inverts the same figures recommended by Annex E note 3 */
+ 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;
+ }
+
+ do {
+ list[1][indexliste] = mode;
+ while ((list[1][indexliste] == mode) && (indexchaine < sourcelen)) {
+ list[0][indexliste]++;
+ indexchaine++;
+ if (indexchaine == sourcelen) {
+ break;
+ }
+ mode = parunmodd(source[indexchaine]);
+ if ((symbol->symbology == BARCODE_CODE128B) && (mode == ABORC)) {
+ mode = AORB;
+ }
+ }
+ indexliste++;
+ } while (indexchaine < sourcelen);
+
+ dxsmooth(list, &indexliste);
+
+ /* Resolve odd length LATCHC blocks */
+ if ((list[1][0] == LATCHC) && (list[0][0] & 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] & 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++;
+ }
+ }
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Data: %.*s (%d)\n", sourcelen, source, sourcelen);
+ printf(" Set: %.*s\n", sourcelen, set);
+ printf("FSet: %.*s\n", sourcelen, fset);
+ }
+
+ /* Now we can calculate how long the barcode is going to be - and stop it from
+ being too long */
+ last_set = set[0];
+ 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') {
+ glyph_count = glyph_count + 2.0;
+ }
+ } else {
+ if ((fset[i] == 'F') && (fset[i - 1] != 'F')) {
+ glyph_count = glyph_count + 2.0;
+ }
+ if ((fset[i] != 'F') && (fset[i - 1] == 'F')) {
+ 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 > 60.0) {
+ strcpy(symbol->errtxt, "341: Input too long");
+ return ZINT_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 */
+ strcat(dest, C128Table[103]);
+ values[0] = 103;
+ current_set = 'A';
+ strcat(dest, C128Table[96]); /* FNC3 */
+ values[1] = 96;
+ bar_characters++;
+ break;
+ case 'B': /* Start B */
+ strcat(dest, C128Table[104]);
+ values[0] = 104;
+ current_set = 'B';
+ strcat(dest, C128Table[96]); /* FNC3 */
+ values[1] = 96;
+ bar_characters++;
+ break;
+ case 'C': /* Start C */
+ strcat(dest, C128Table[104]); /* Start B */
+ values[0] = 104;
+ strcat(dest, C128Table[96]); /* FNC3 */
+ values[1] = 96;
+ strcat(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 */
+ strcat(dest, C128Table[103]);
+ values[0] = 103;
+ current_set = 'A';
+ break;
+ case 'B': /* Start B */
+ strcat(dest, C128Table[104]);
+ values[0] = 104;
+ current_set = 'B';
+ break;
+ case 'C': /* Start C */
+ strcat(dest, C128Table[105]);
+ values[0] = 105;
+ current_set = 'C';
+ break;
+ }
+ }
+ bar_characters++;
+
+ if (fset[0] == 'F') {
+ switch (current_set) {
+ case 'A':
+ strcat(dest, C128Table[101]);
+ strcat(dest, C128Table[101]);
+ values[bar_characters] = 101;
+ values[bar_characters + 1] = 101;
+ break;
+ case 'B':
+ strcat(dest, C128Table[100]);
+ strcat(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': strcat(dest, C128Table[101]);
+ values[bar_characters] = 101;
+ bar_characters++;
+ current_set = 'A';
+ break;
+ case 'B': strcat(dest, C128Table[100]);
+ values[bar_characters] = 100;
+ bar_characters++;
+ current_set = 'B';
+ break;
+ case 'C': strcat(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':
+ strcat(dest, C128Table[101]);
+ strcat(dest, C128Table[101]);
+ values[bar_characters] = 101;
+ values[bar_characters + 1] = 101;
+ break;
+ case 'B':
+ strcat(dest, C128Table[100]);
+ strcat(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':
+ strcat(dest, C128Table[101]);
+ strcat(dest, C128Table[101]);
+ values[bar_characters] = 101;
+ values[bar_characters + 1] = 101;
+ break;
+ case 'B':
+ strcat(dest, C128Table[100]);
+ strcat(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':
+ strcat(dest, C128Table[101]); /* FNC 4 */
+ values[bar_characters] = 101;
+ break;
+ case 'B':
+ strcat(dest, C128Table[100]); /* FNC 4 */
+ values[bar_characters] = 100;
+ break;
+ }
+ bar_characters++;
+ }
+
+ if ((set[read] == 'a') || (set[read] == 'b')) {
+ /* Insert shift character */
+ strcat(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 = values[0] % 103; /* Mod as we go along to avoid overflow */
+
+ for (i = 1; i < bar_characters; i++) {
+ total_sum = (total_sum + values[i] * i) % 103;
+ }
+ strcat(dest, C128Table[total_sum]);
+ values[bar_characters] = total_sum;
+ bar_characters++;
+
+ /* Stop character */
+ strcat(dest, C128Table[106]);
+ values[bar_characters] = 106;
+ bar_characters++;
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Codewords:");
+ for (i = 0; i < bar_characters; i++) {
+ printf(" %d", values[i]);
+ }
+ printf("\n");
+ }
+#ifdef ZINT_TEST
+ if (symbol->debug & ZINT_DEBUG_TEST) {
+ debug_test_codeword_dump_int(symbol, values, bar_characters);
+ }
+#endif
+
+ expand(symbol, dest);
+ 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,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;
+/* Handle EAN-128 (Now known as GS1-128) */
+INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length) {
+ int i, j, values[C128_MAX] = {0}, bar_characters, read, total_sum;
+ int error_number, indexchaine, indexliste;
+ int list[2][C128_MAX] = {{0}};
+ char set[C128_MAX] = {0}, mode, last_set;
+ float glyph_count;
+ char dest[1000];
+ int separator_row, linkage_flag, c_count;
+ int reduced_length;
#ifndef _MSC_VER
- char reduced[length + 1];
+ char reduced[length + 1];
#else
- char* reduced = (char*)_alloca(length + 1);
+ char* reduced = (char*) _alloca(length + 1);
+#endif
+
+ strcpy(dest, "");
+ linkage_flag = 0;
+
+ bar_characters = 0;
+ separator_row = 0;
+
+ if (length > C128_MAX) {
+ /* This only blocks ridiculously long input - the actual length of the
+ resulting barcode depends on the type of data, so this is trapped later */
+ strcpy(symbol->errtxt, "342: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ /* 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;
+ }
+
+ error_number = gs1_verify(symbol, source, length, reduced);
+ if (error_number != 0) {
+ return error_number;
+ }
+ reduced_length = strlen(reduced);
+
+ /* 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;
+ }
+
+ do {
+ list[1][indexliste] = mode;
+ while ((list[1][indexliste] == mode) && (indexchaine < reduced_length)) {
+ list[0][indexliste]++;
+ indexchaine++;
+ if (indexchaine == reduced_length) {
+ break;
+ }
+ mode = parunmodd(reduced[indexchaine]);
+ if (reduced[indexchaine] == '[') {
+ mode = ABORC;
+ }
+ }
+ indexliste++;
+ } while (indexchaine < reduced_length);
+
+ dxsmooth(list, &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 & 1) {
+ 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 & 1) {
+ if ((i - c_count) != 0) {
+ set[i - c_count] = 'B';
+ } else {
+ set[i - 1] = 'B';
+ }
+ }
+ c_count = 0;
+ }
+ }
+ if (c_count & 1) {
+ 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';
+ }
+ }
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Data: %s (%d)\n", reduced, reduced_length);
+ printf(" Set: %.*s\n", reduced_length, set);
+ }
+
+ /* Now we can calculate how long the barcode is going to be - and stop it from
+ being too long */
+ last_set = set[0];
+ glyph_count = 0.0;
+ for (i = 0; i < reduced_length; 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 > 60.0) {
+ strcpy(symbol->errtxt, "344: Input too long");
+ return ZINT_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 */
+ strcat(dest, C128Table[103]);
+ values[0] = 103;
+ break;
+ case 'B': /* Start B */
+ strcat(dest, C128Table[104]);
+ values[0] = 104;
+ break;
+ case 'C': /* Start C */
+ strcat(dest, C128Table[105]);
+ values[0] = 105;
+ break;
+ }
+ bar_characters++;
+
+ strcat(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': strcat(dest, C128Table[101]);
+ values[bar_characters] = 101;
+ bar_characters++;
+ break;
+ case 'B': strcat(dest, C128Table[100]);
+ values[bar_characters] = 100;
+ bar_characters++;
+ break;
+ case 'C': strcat(dest, C128Table[99]);
+ values[bar_characters] = 99;
+ bar_characters++;
+ break;
+ }
+ }
+
+ if ((set[read] == 'a') || (set[read] == 'b')) {
+ /* Insert shift character */
+ strcat(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 {
+ strcat(dest, C128Table[102]);
+ values[bar_characters] = 102;
+ bar_characters++;
+ read++;
+ }
+ } while (read < reduced_length);
+
+ /* "...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[reduced_length - 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[reduced_length - 1]) {
+ case 'A': linkage_flag = 99;
+ break;
+ case 'B': linkage_flag = 101;
+ break;
+ case 'C': linkage_flag = 100;
+ break;
+ }
+ break;
+ }
+
+ if (linkage_flag != 0) {
+ strcat(dest, C128Table[linkage_flag]);
+ values[bar_characters] = linkage_flag;
+ bar_characters++;
+ }
+
+ /* check digit calculation */
+ total_sum = values[0] % 103; /* Mod as we go along to avoid overflow */
+
+ for (i = 1; i < bar_characters; i++) {
+ total_sum = (total_sum + values[i] * i) % 103;
+ }
+ strcat(dest, C128Table[total_sum]);
+ values[bar_characters] = total_sum;
+ bar_characters++;
+
+ /* Stop character */
+ strcat(dest, C128Table[106]);
+ values[bar_characters] = 106;
+ bar_characters++;
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Codewords:");
+ for (i = 0; i < bar_characters; i++) {
+ printf(" %d", values[i]);
+ }
+ printf("\n");
+ }
+#ifdef ZINT_TEST
+ if (symbol->debug & ZINT_DEBUG_TEST) {
+ debug_test_codeword_dump_int(symbol, values, bar_characters);
+ }
#endif
- error_number = 0;
- strcpy(dest, "");
- linkage_flag = 0;
-
- j = 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 & 1) {
- 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 & 1) {
- if((i - c_count) != 0) {
- set[i - c_count] = 'B';
- } else {
- set[i - 1] = 'B';
- }
- }
- c_count = 0;
- }
- }
- if(c_count & 1) {
- 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;
+
+ 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 < (int) 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 & 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;
+/* Add check digit if encoding an NVE18 symbol */
+INTERNAL int nve_18(struct zint_symbol *symbol, unsigned char source[], int length) {
+ 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, "345: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "346: 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 & 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 & 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;
+/* EAN-14 - A version of EAN-128 */
+INTERNAL int ean_14(struct zint_symbol *symbol, unsigned char source[], int length) {
+ int i, count, check_digit;
+ int error_number, zeroes;
+ unsigned char ean128_equiv[20];
+
+ if (length > 13) {
+ strcpy(symbol->errtxt, "347: Input wrong length");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "348: 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 & 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/code128.h b/backend/code128.h
new file mode 100644
index 0000000..0b1f042
--- /dev/null
+++ b/backend/code128.h
@@ -0,0 +1,57 @@
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#ifndef CODE128_H
+#define CODE128_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define C128_MAX 160
+
+#define SHIFTA 90
+#define LATCHA 91
+#define SHIFTB 92
+#define LATCHB 93
+#define SHIFTC 94
+#define LATCHC 95
+#define AORB 96
+#define ABORC 97
+
+INTERNAL int parunmodd(const unsigned char llyth);
+INTERNAL void dxsmooth(int list[2][C128_MAX], int *indexliste);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* CODE128_H */
diff --git a/backend/code16k.c b/backend/code16k.c
new file mode 100644
index 0000000..c7394c5
--- /dev/null
+++ b/backend/code16k.c
@@ -0,0 +1,504 @@
+/* code16k.c - Handles Code 16k stacked symbology */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/* Updated to comply with BS EN 12323:2005 */
+
+/* Code 16k can hold up to 77 characters or 154 numbers */
+
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+#include "common.h"
+#include "code128.h"
+
+static const char *C16KTable[107] = {
+ /* EN 12323 Table 1 - "Code 16K" character encodations */
+ "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"
+};
+
+
+static const char *C16KStartStop[8] = {
+ /* EN 12323 Table 3 and Table 4 - Start patterns and stop patterns */
+ "3211", "2221", "2122", "1411", "1132", "1231", "1114", "3112"
+};
+
+/* EN 12323 Table 5 - Start and stop values defining row numbers */
+static const int C16KStartValues[16] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7
+};
+
+static const int C16KStopValues[16] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3
+};
+
+static void c16k_set_a(const unsigned char source, int values[], 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)++;
+}
+
+static void c16k_set_b(const unsigned char source, int values[], int *bar_chars) {
+ if (source > 127) {
+ values[(*bar_chars)] = source - 32 - 128;
+ } else {
+ values[(*bar_chars)] = source - 32;
+ }
+ (*bar_chars)++;
+}
+
+static void c16k_set_c(const unsigned char source_a, unsigned char source_b, int values[], int *bar_chars) {
+ int weight;
+
+ weight = (10 * ctoi(source_a)) + ctoi(source_b);
+ values[(*bar_chars)] = weight;
+ (*bar_chars)++;
+}
+
+INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[], const size_t length) {
+ char width_pattern[100];
+ int current_row, rows_needed, looper, first_check, second_check;
+ int indexchaine;
+ int list[2][C128_MAX] = {{0}};
+ char set[C128_MAX] = {0}, fset[C128_MAX], mode, last_set, current_set;
+ int pads_needed, indexliste, i, j, m, read, mx_reader;
+ int values[C128_MAX] = {0};
+ int bar_characters;
+ float glyph_count;
+ int errornum, first_sum, second_sum;
+ int input_length;
+ int gs1, c_count;
+
+ /* Suppresses clang-analyzer-core.UndefinedBinaryOperatorResult warning on fset which is fully set */
+ assert(length > 0);
+
+ errornum = 0;
+ strcpy(width_pattern, "");
+ input_length = length;
+
+ if ((symbol->input_mode & 0x07) == GS1_MODE) {
+ gs1 = 1;
+ } else {
+ gs1 = 0;
+ }
+
+ if (input_length > C128_MAX) {
+ strcpy(symbol->errtxt, "420: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ bar_characters = 0;
+
+ /* Detect extended ASCII characters */
+ for (i = 0; i < input_length; i++) {
+ fset[i] = source[i] >= 128 ? 'f' : ' ';
+ }
+ /* Note to be safe not using extended ASCII latch as not mentioned in BS EN 12323:2005 */
+
+ /* Detect mode A, B and C characters */
+ indexliste = 0;
+ indexchaine = 0;
+
+ mode = parunmodd(source[indexchaine]);
+ if ((gs1) && (source[indexchaine] == '[')) {
+ mode = ABORC;
+ } /* FNC1 */
+
+ do {
+ list[1][indexliste] = mode;
+ while ((list[1][indexliste] == mode) && (indexchaine < input_length)) {
+ list[0][indexliste]++;
+ indexchaine++;
+ if (indexchaine == input_length) {
+ break;
+ }
+ mode = parunmodd(source[indexchaine]);
+ if ((gs1) && (source[indexchaine] == '[')) {
+ mode = ABORC;
+ } /* FNC1 */
+ }
+ indexliste++;
+ } while (indexchaine < input_length);
+
+ dxsmooth(list, &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 (source[i] == '[') {
+ if (c_count & 1) {
+ 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 & 1) {
+ if ((i - c_count) != 0) {
+ set[i - c_count] = 'B';
+ } else {
+ set[i - 1] = 'B';
+ }
+ }
+ c_count = 0;
+ }
+ }
+ if (c_count & 1) {
+ 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';
+ }
+ }
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Data: %.*s\n", input_length, source);
+ printf(" Set: %.*s\n", input_length, set);
+ printf("FSet: %.*s\n", input_length, fset);
+ }
+
+ /* Make sure the data will fit in the symbol */
+ last_set = set[0];
+ 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') {
+ 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 ((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, "421: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ /* Calculate how tall the symbol will be */
+ glyph_count = glyph_count + 2.0;
+ i = (int)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, "422: Cannot use both GS1 mode and Reader Initialisation");
+ return ZINT_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];
+ 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;
+ }
+ }
+
+ if (fset[read] == 'f') {
+ /* 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[read] == 'a') || (set[read] == '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++;
+ }
+ } while (read < input_length);
+
+ 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] = 103;
+ 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;
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Codewords:");
+ for (i = 0; i < bar_characters; i++) {
+ printf(" %d", values[i]);
+ }
+ printf("\n");
+ }
+#ifdef ZINT_TEST
+ if (symbol->debug & ZINT_DEBUG_TEST) {
+ debug_test_codeword_dump_int(symbol, values, bar_characters); /* Missing row start/stop */
+ }
+#endif
+
+ for (current_row = 0; current_row < rows_needed; current_row++) {
+ int writer;
+ int flip_flop;
+ int len;
+
+ strcpy(width_pattern, "");
+ strcat(width_pattern, C16KStartStop[C16KStartValues[current_row]]);
+ strcat(width_pattern, "1");
+ for (i = 0; i < 5; i++) {
+ strcat(width_pattern, C16KTable[values[(current_row * 5) + i]]);
+ }
+ strcat(width_pattern, C16KStartStop[C16KStopValues[current_row]]);
+
+ /* Write the information into the symbol */
+ writer = 0;
+ flip_flop = 1;
+ for (mx_reader = 0, len = strlen(width_pattern); mx_reader < len; 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;
+
+ symbol->output_options |= BARCODE_BIND;
+
+ if (symbol->border_width == 0) { /* Allow override if non-zero */
+ symbol->border_width = 1; /* BS EN 12323:2005 Section 4.3.7 minimum (note change from previous default 2) */
+ }
+
+ return errornum;
+}
diff --git a/backend/code49.c b/backend/code49.c
new file mode 100644
index 0000000..3d7aebf
--- /dev/null
+++ b/backend/code49.c
@@ -0,0 +1,361 @@
+/* code49.c - Handles Code 49 */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <string.h>
+#include <stdio.h>
+#include "common.h"
+#include "code49.h"
+
+#define INSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%!&*"
+
+/* "!" represents Shift 1 and "&" represents Shift 2, "*" represents FNC1 */
+
+INTERNAL int code_49(struct zint_symbol *symbol, unsigned char source[], const int length) {
+ int i, j, rows, M, x_count, y_count, z_count, posn_val, local_value;
+ 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[80];
+ int gs1;
+ int h, len;
+
+ if (length > 81) {
+ strcpy(symbol->errtxt, "430: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ if ((symbol->input_mode & 0x07) == GS1_MODE) {
+ gs1 = 1;
+ strcpy(intermediate, "*"); /* FNC1 */
+ } else {
+ gs1 = 0;
+ }
+
+ for (i = 0; i < length; i++) {
+ if (source[i] > 127) {
+ strcpy(symbol->errtxt, "431: Invalid characters in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ if (gs1 && (source[i] == '['))
+ strcat(intermediate, "*"); /* FNC1 */
+ else
+ strcat(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;
+ break;
+ case 43: M = 4;
+ break;
+ case 44: M = 5;
+ break;
+ default: M = 0;
+ break;
+ }
+
+ if (M != 0) {
+ codeword_count--;
+ for (i = 0; i < codeword_count; i++) {
+ codewords[i] = codewords[i + 1];
+ }
+ }
+
+ if (codeword_count > 49) {
+ strcpy(symbol->errtxt, "432: Input too long");
+ return ZINT_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;
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Codewords:\n");
+ for (i = 0; i < rows; i++) {
+ for (j = 0; j < 8; j++) {
+ printf(" %2d", c_grid[i][j]);
+ }
+ printf("\n");
+ }
+ }
+#ifdef ZINT_TEST
+ if (symbol->debug & ZINT_DEBUG_TEST) {
+ debug_test_codeword_dump_int(symbol, (int *)c_grid, rows * 8);
+ }
+#endif
+
+ /* 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, "10"); /* Start character */
+ for (j = 0; j < 4; j++) {
+ if (i != (rows - 1)) {
+ if (c49_table4[i][j] == 'E') {
+ /* Even Parity */
+ bin_append(c49_even_bitpattern[w_grid[i][j]], 16, pattern);
+ } else {
+ /* Odd Parity */
+ bin_append(c49_odd_bitpattern[w_grid[i][j]], 16, pattern);
+ }
+ } else {
+ /* Last row uses all even parity */
+ bin_append(c49_even_bitpattern[w_grid[i][j]], 16, pattern);
+ }
+ }
+ strcat(pattern, "1111"); /* Stop character */
+
+ /* Expand into symbol */
+ symbol->row_height[i] = 10;
+
+ for (j = 0, len = strlen(pattern); j < len; j++) {
+ if (pattern[j] == '1') {
+ set_module(symbol, i, j);
+ }
+ }
+ }
+
+ symbol->rows = rows;
+ symbol->width = strlen(pattern);
+
+ symbol->output_options |= BARCODE_BIND;
+
+ if (symbol->border_width == 0) { /* Allow override if non-zero */
+ symbol->border_width = 1; /* ANSI/AIM BC6-2000 Section 2.1 (note change from previous default 2) */
+ }
+
+ return 0;
+}
diff --git a/backend/code49.h b/backend/code49.h
new file mode 100644
index 0000000..01dec46
--- /dev/null
+++ b/backend/code49.h
@@ -0,0 +1,558 @@
+/* code49.h - Code 49 Tables */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2009-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+
+/* This data set taken from ANSI/AIM-BC6-2000, 4th April 2000 */
+
+static const 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 */
+static const char 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
+};
+
+static const char 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
+};
+
+static const char 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 const char *c49_table4[8] = {
+ /* Table 4: Row Parity Pattern for Code 49 Symbols */
+ "OEEO", "EOEO", "OOEE", "EEOO", "OEOE", "EOOE", "OOOO", "EEEE"
+};
+
+static const unsigned short int c49_even_bitpattern[] = {
+ /* Appendix E - Code 49 Encodation Patterns (Even Symbol Character Parity) */
+ 0xBE5C, 0xC16E, 0x86DC, 0xC126, 0x864C, 0x9EDC, 0xC726, 0x9E4C, 0xDF26, 0x82CC,
+ 0x8244, 0x8ECC, 0xC322, 0x8E44, 0xBECC, 0xCF22, 0xBE44, 0xC162, 0x86C4, 0xC762,
+ 0x9EC4, 0xDF62, 0x812E, 0x872E, 0x9F2E, 0x836E, 0x8326, 0x8F6E, 0x8F26, 0xBF6E,
+ 0x8166, 0x8122, 0x8766, 0x8722, 0x9F66, 0x9F22, 0x8362, 0x8F62, 0xBF62, 0xA2E0,
+ 0xE8B8, 0xFA2E, 0xD370, 0xF4DC, 0xD130, 0xF44C, 0xAEE0, 0xEBB8, 0xFAEE, 0xA660,
+ 0xE998, 0xFA66, 0xA220, 0xE888, 0xFA22, 0xD730, 0xF5CC, 0xD310, 0xF4C4, 0xAE20,
+ 0xEB88, 0xFAE2, 0x9170, 0xE45C, 0xD8B8, 0xF62E, 0xC9B8, 0xF26E, 0xB370, 0xC898,
+ 0xF226, 0xB130, 0xEC4C, 0x9770, 0xE5DC, 0x9330, 0xE4CC, 0x9110, 0xE444, 0xD888,
+ 0xF622, 0xCB98, 0xF2E6, 0xB730, 0xC988, 0xF262, 0xB310, 0xECC4, 0x9710, 0xE5C4,
+ 0xDB88, 0xF6E2, 0x88B8, 0xE22E, 0xCC5C, 0xB8B8, 0xEE2E, 0xC4DC, 0x99B8, 0xC44C,
+ 0x9898, 0xE626, 0xDC4C, 0x8BB8, 0xE2EE, 0x8998, 0xE266, 0xBBB8, 0x8888, 0xE222,
+ 0xB998, 0xCC44, 0xB888, 0xEE22, 0xC5CC, 0x9B98, 0xC4C4, 0x9988, 0xE662, 0xDCC4,
+ 0x8B88, 0xE2E2, 0xCDC4, 0xBB88, 0xEEE2, 0x845C, 0xC62E, 0x9C5C, 0xDE2E, 0xC26E,
+ 0x8CDC, 0xC226, 0x8C4C, 0xBCDC, 0xCE26, 0xBC4C, 0x85DC, 0x84CC, 0x9DDC, 0x8444,
+ 0x9CCC, 0xC622, 0x9C44, 0xDE22, 0xC2E6, 0x8DCC, 0xC262, 0x8CC4, 0xBDCC, 0xCE62,
+ 0xBCC4, 0x85C4, 0xC6E2, 0x9DC4, 0xDEE2, 0x822E, 0x8E2E, 0x866E, 0x8626, 0x9E6E,
+ 0x9E26, 0x82EE, 0x8266, 0x8EEE, 0x8222, 0x8E66, 0xBEEE, 0x8E22, 0xBE66, 0x86E6,
+ 0x8662, 0x9EE6, 0x9E62, 0x82E2, 0x8EE2, 0xBEE2, 0xA170, 0xE85C, 0xD1B8, 0xF46E,
+ 0xD098, 0xF426, 0xA770, 0xE9DC, 0xA330, 0xE8CC, 0xA110, 0xE844, 0xD7B8, 0xF5EE,
+ 0xD398, 0xF4E6, 0xD188, 0xF462, 0xAF30, 0xEBCC, 0xA710, 0xE9C4, 0xD788, 0xF5E2,
+ 0x90B8, 0xE42E, 0xD85C, 0xC8DC, 0xB1B8, 0xC84C, 0xB098, 0xEC26, 0x93B8, 0xE4EE,
+ 0x9198, 0xE466, 0x9088, 0xE422, 0xD844, 0xCBDC, 0xB7B8, 0xC9CC, 0xB398, 0xC8C4,
+ 0xB188, 0xEC62, 0x9798, 0xE5E6, 0x9388, 0xE4E2, 0xD9C4, 0xCBC4, 0xB788, 0xEDE2,
+ 0x885C, 0xCC2E, 0xB85C, 0xC46E, 0x98DC, 0xC426, 0x984C, 0xDC26, 0x89DC, 0x88CC,
+ 0xB9DC, 0x8844, 0xB8CC, 0xCC22, 0xB844, 0xC5EE, 0x9BDC, 0xC4E6, 0x99CC, 0xC462,
+ 0x98C4, 0xDC62, 0x8BCC, 0x89C4, 0xBBCC, 0xCCE2, 0xB9C4, 0xC5E2, 0x9BC4, 0xDDE2,
+ 0x842E, 0x9C2E, 0x8C6E, 0x8C26, 0xBC6E, 0x84EE, 0x8466, 0x9CEE, 0x8422, 0x9C66,
+ 0x9C22, 0x8DEE, 0x8CE6, 0xBDEE, 0x8C62, 0xBCE6, 0xBC62, 0x85E6, 0x84E2, 0x9DE6,
+ 0x9CE2, 0x8DE2, 0xBDE2, 0xA0B8, 0xE82E, 0xD0DC, 0xD04C, 0xA3B8, 0xE8EE, 0xA198,
+ 0xE866, 0xA088, 0xE822, 0xD3DC, 0xD1CC, 0xD0C4, 0xAFB8, 0xEBEE, 0xA798, 0xE9E6,
+ 0xA388, 0xE8E2, 0xD7CC, 0xD3C4, 0x905C, 0xD82E, 0xC86E, 0xB0DC, 0xC826, 0xB04C,
+ 0x91DC, 0x90CC, 0x9044, 0xD822, 0xC9EE, 0xB3DC, 0xC8E6, 0xB1CC, 0xC862, 0xB0C4,
+ 0x97DC, 0x93CC, 0x91C4, 0xD8E2, 0xCBE6, 0xB7CC, 0xC9E2, 0xB3C4, 0x882E, 0x986E,
+ 0x9826, 0x88EE, 0x8866, 0xB8EE, 0x8822, 0xB866, 0x99EE, 0x98E6, 0x9862, 0x8BEE,
+ 0x89E6, 0xBBEE, 0x88E2, 0xB9E6, 0xB8E2, 0x9BE6, 0x99E2, 0xA05C, 0xD06E, 0xD026,
+ 0xA1DC, 0xA0CC, 0xA044, 0xD1EE, 0xD0E6, 0xD062, 0xA7DC, 0xA3CC, 0xA1C4, 0xD7EE,
+ 0xD3E6, 0xD1E2, 0x902E, 0xB06E, 0x90EE, 0x9066, 0x9022, 0xB1EE, 0xB0E6, 0xB062,
+ 0x93EE, 0x91E6, 0x90E2, 0xB7EE, 0xB3E6, 0xB1E2, 0xA9C0, 0xEA70, 0xFA9C, 0xD460,
+ 0xF518, 0xFD46, 0xA840, 0xEA10, 0xFA84, 0xED78, 0xFB5E, 0x94E0, 0xE538, 0xF94E,
+ 0xDA70, 0xF69C, 0xCA30, 0xF28C, 0xB460, 0xED18, 0xFB46, 0x9420, 0xE508, 0xF942,
+ 0xDA10, 0xF684, 0x9AF0, 0xE6BC, 0xDD78, 0xF75E, 0x8A70, 0xE29C, 0xCD38, 0xF34E,
+ 0xBA70, 0xEE9C, 0xC518, 0xF146, 0x9A30, 0xE68C, 0xDD18, 0xF746, 0x8A10, 0xE284,
+ 0xCD08, 0xF342, 0xBA10, 0xEE84, 0x8D78, 0xE35E, 0xCEBC, 0xBD78, 0xEF5E, 0x8538,
+ 0xE14E, 0xC69C, 0x9D38, 0xE74E, 0xDE9C, 0xC28C, 0x8D18, 0xE346, 0xCE8C, 0xBD18,
+ 0xEF46, 0x8508, 0xE142, 0xC684, 0x9D08, 0xE742, 0xDE84, 0x86BC, 0xC75E, 0x9EBC,
+ 0xDF5E, 0x829C, 0xC34E, 0x8E9C, 0xCF4E, 0xBE9C, 0xC146, 0x868C, 0xC746, 0x9E8C,
+ 0xDF46, 0x8284, 0xC342, 0x8E84, 0xCF42, 0xBE84, 0x835E, 0x8F5E, 0xBF5E, 0x814E,
+ 0x874E, 0x9F4E, 0x8346, 0x8F46, 0xBF46, 0x8142, 0x8742, 0x9F42, 0xD2F0, 0xF4BC,
+ 0xADE0, 0xEB78, 0xFADE, 0xA4E0, 0xE938, 0xFA4E, 0xD670, 0xF59C, 0xD230, 0xF48C,
+ 0xAC60, 0xEB18, 0xFAC6, 0xA420, 0xE908, 0xFA42, 0xD610, 0xF584, 0xC978, 0xF25E,
+ 0xB2F0, 0xECBC, 0x96F0, 0xE5BC, 0x9270, 0xE49C, 0xD938, 0xF64E, 0xCB38, 0xF2CE,
+ 0xB670, 0xC918, 0xF246, 0xB230, 0xEC8C, 0x9630, 0xE58C, 0x9210, 0xE484, 0xD908,
+ 0xF642, 0xCB08, 0xF2C2, 0xB610, 0xED84, 0xC4BC, 0x9978, 0xE65E, 0xDCBC, 0x8B78,
+ 0xE2DE, 0x8938, 0xE24E, 0xBB78, 0xCC9C, 0xB938, 0xEE4E, 0xC59C, 0x9B38, 0xC48C,
+ 0x9918, 0xE646, 0xDC8C, 0x8B18, 0xE2C6, 0x8908, 0xE242, 0xBB18, 0xCC84, 0xB908,
+ 0xEE42, 0xC584, 0x9B08, 0xE6C2, 0xDD84, 0xC25E, 0x8CBC, 0xCE5E, 0xBCBC, 0x85BC,
+ 0x849C, 0x9DBC, 0xC64E, 0x9C9C, 0xDE4E, 0xC2CE, 0x8D9C, 0xC246, 0x8C8C, 0xBD9C,
+ 0xCE46, 0xBC8C, 0x858C, 0x8484, 0x9D8C, 0xC642, 0x9C84, 0xDE42, 0xC2C2, 0x8D84,
+ 0xCEC2, 0xBD84, 0x865E, 0x9E5E, 0x82DE, 0x824E, 0x8EDE, 0x8E4E, 0xBEDE, 0xBE4E,
+ 0x86CE, 0x8646, 0x9ECE, 0x9E46, 0x82C6, 0x8242, 0x8EC6, 0x8E42, 0xBEC6, 0xBE42,
+ 0x86C2, 0x9EC2, 0xD178, 0xF45E, 0xA6F0, 0xE9BC, 0xA270, 0xE89C, 0xD778, 0xF5DE,
+ 0xD338, 0xF4CE, 0xD118, 0xF446, 0xAE70, 0xEB9C, 0xA630, 0xE98C, 0xA210, 0xE884,
+ 0xD718, 0xF5C6, 0xD308, 0xF4C2, 0xAE10, 0xEB84, 0xC8BC, 0xB178, 0xEC5E, 0x9378,
+ 0xE4DE, 0x9138, 0xE44E, 0xD89C, 0xCBBC, 0xB778, 0xC99C, 0xB338, 0xC88C, 0xB118,
+ 0xEC46, 0x9738, 0xE5CE, 0x9318, 0xE4C6, 0x9108, 0xE442, 0xD884, 0xCB8C, 0xB718,
+ 0xC984, 0xB308, 0xECC2, 0x9708, 0xE5C2, 0xDB84, 0xC45E, 0x98BC, 0xDC5E, 0x89BC,
+ 0x889C, 0xB9BC, 0xCC4E, 0xB89C, 0xC5DE, 0x9BBC, 0xC4CE, 0x999C, 0xC446, 0x988C,
+ 0xDC46, 0x8B9C, 0x898C, 0xBB9C, 0x8884, 0xB98C, 0xCC42, 0xB884, 0xC5C6, 0x9B8C,
+ 0xC4C2, 0x9984, 0xDCC2, 0x8B84, 0xCDC2, 0xBB84, 0x8C5E, 0xBC5E, 0x84DE, 0x844E,
+ 0x9CDE, 0x9C4E, 0x8DDE, 0x8CCE, 0xBDDE, 0x8C46, 0xBCCE, 0xBC46, 0x85CE, 0x84C6,
+ 0x9DCE, 0x8442, 0x9CC6, 0x9C42, 0x8DC6, 0x8CC2, 0xBDC6, 0xBCC2, 0x85C2, 0x9DC2,
+ 0xD0BC, 0xA378, 0xE8DE, 0xA138, 0xE84E, 0xD3BC, 0xD19C, 0xD08C, 0xAF78, 0xEBDE,
+ 0xA738, 0xE9CE, 0xA318, 0xE8C6, 0xA108, 0xE842, 0xD79C, 0xD38C, 0xD184, 0xAF18,
+ 0xEBC6, 0xA708, 0xE9C2, 0xC85E, 0xB0BC, 0x91BC, 0x909C, 0xD84E, 0xC9DE, 0xB3BC,
+ 0xC8CE, 0xB19C, 0xC846, 0xB08C, 0x97BC, 0x939C, 0x918C, 0x9084, 0xD842, 0xCBCE,
+ 0xB79C, 0xC9C6, 0xB38C, 0xC8C2, 0xB184, 0x978C, 0x9384, 0xD9C2, 0x985E, 0x88DE,
+ 0x884E, 0xB8DE, 0xB84E, 0x99DE, 0x98CE, 0x9846, 0x8BDE, 0x89CE, 0xBBDE, 0x88C6,
+ 0xB9CE, 0x8842, 0xB8C6, 0xB842, 0x9BCE, 0x99C6, 0x98C2, 0x8BC6, 0x89C2, 0xBBC6,
+ 0xB9C2, 0xD05E, 0xA1BC, 0xA09C, 0xD1DE, 0xD0CE, 0xD046, 0xA7BC, 0xA39C, 0xA18C,
+ 0xA084, 0xD7DE, 0xD3CE, 0xD1C6, 0xD0C2, 0xAF9C, 0xA78C, 0xA384, 0xB05E, 0x90DE,
+ 0x904E, 0xB1DE, 0xB0CE, 0xB046, 0x93DE, 0x91CE, 0x90C6, 0x9042, 0xB7DE, 0xB3CE,
+ 0xB1C6, 0xB0C2, 0x97CE, 0x93C6, 0x91C2, 0xA0DE, 0xA04E, 0xA3DE, 0xA1CE, 0xA0C6,
+ 0xA042, 0xAFDE, 0xA7CE, 0xA3C6, 0xA1C2, 0xD4F0, 0xF53C, 0xA8E0, 0xEA38, 0xFA8E,
+ 0xD430, 0xF50C, 0xA820, 0xEA08, 0xFA82, 0xDAF8, 0xF6BE, 0xCA78, 0xF29E, 0xB4F0,
+ 0xED3C, 0x9470, 0xE51C, 0xDA38, 0xF68E, 0xCA18, 0xF286, 0xB430, 0xED0C, 0x9410,
+ 0xE504, 0xDA08, 0xF682, 0xCD7C, 0xBAF8, 0xEEBE, 0xC53C, 0x9A78, 0xE69E, 0xDD3C,
+ 0x8A38, 0xE28E, 0xCD1C, 0xBA38, 0xEE8E, 0xC50C, 0x9A18, 0xE686, 0xDD0C, 0x8A08,
+ 0xE282, 0xCD04, 0xBA08, 0xEE82, 0xC6BE, 0x9D7C, 0xDEBE, 0xC29E, 0x8D3C, 0xCE9E,
+ 0xBD3C, 0x851C, 0xC68E, 0x9D1C, 0xDE8E, 0xC286, 0x8D0C, 0xCE86, 0xBD0C, 0x8504,
+ 0xC682, 0x9D04, 0xDE82, 0x8EBE, 0xBEBE, 0x869E, 0x9E9E, 0x828E, 0x8E8E, 0xBE8E,
+ 0x8686, 0x9E86, 0x8282, 0x8E82, 0xBE82, 0xE97C, 0xD6F8, 0xF5BE, 0xD278, 0xF49E,
+ 0xACF0, 0xEB3C, 0xA470, 0xE91C, 0xD638, 0xF58E, 0xD218, 0xF486, 0xAC30, 0xEB0C,
+ 0xA410, 0xE904, 0xD608, 0xF582, 0x92F8, 0xE4BE, 0xD97C, 0xCB7C, 0xB6F8, 0xC93C,
+ 0xB278, 0xEC9E, 0x9678, 0xE59E, 0x9238, 0xE48E, 0xD91C, 0xCB1C, 0xB638, 0xC90C,
+ 0xB218, 0xEC86, 0x9618, 0xE586, 0x9208, 0xE482, 0xD904, 0xCB04, 0xB608, 0xED82,
+ 0x897C, 0xCCBE, 0xB97C, 0xC5BE, 0x9B7C, 0xC49E, 0x993C, 0xDC9E, 0x8B3C, 0x891C,
+ 0xBB3C, 0xCC8E, 0xB91C, 0xC58E, 0x9B1C, 0xC486, 0x990C, 0xDC86, 0x8B0C, 0x8904,
+ 0xBB0C, 0xCC82, 0xB904, 0xC582, 0x9B04, 0xDD82, 0x84BE, 0x9CBE, 0x8DBE, 0x8C9E,
+ 0xBDBE, 0xBC9E, 0x859E, 0x848E, 0x9D9E, 0x9C8E, 0x8D8E, 0x8C86, 0xBD8E, 0xBC86,
+ 0x8586, 0x8482, 0x9D86, 0x9C82, 0x8D82, 0xBD82, 0xA2F8, 0xE8BE, 0xD37C, 0xD13C,
+ 0xAEF8, 0xEBBE, 0xA678, 0xE99E, 0xA238, 0xE88E, 0xD73C, 0xD31C, 0xD10C, 0xAE38,
+ 0xEB8E, 0xA618, 0xE986, 0xA208, 0xE882, 0xD70C, 0xD304, 0x917C, 0xD8BE, 0xC9BE,
+ 0xB37C, 0xC89E, 0xB13C, 0x977C, 0x933C, 0x911C, 0xD88E, 0xCB9E, 0xB73C, 0xC98E,
+ 0xB31C, 0xC886, 0xB10C, 0x971C, 0x930C, 0x9104, 0xD882, 0xCB86, 0xB70C, 0xC982,
+ 0xB304, 0x88BE, 0xB8BE, 0x99BE, 0x989E, 0x8BBE, 0x899E, 0xBBBE, 0x888E, 0xB99E,
+ 0xB88E, 0x9B9E, 0x998E, 0x9886, 0x8B8E, 0x8986, 0xBB8E, 0x8882, 0xB986, 0xB882,
+ 0x9B86, 0x9982, 0xA17C, 0xD1BE, 0xD09E, 0xA77C, 0xA33C, 0xA11C, 0xD7BE, 0xD39E,
+ 0xD18E, 0xD086, 0xAF3C, 0xA71C, 0xA30C, 0xA104, 0xD78E, 0xD386, 0xD182, 0x90BE,
+ 0xB1BE, 0xB09E, 0x93BE, 0x919E, 0x908E, 0xB7BE, 0xB39E, 0xB18E, 0xB086, 0x979E,
+ 0x938E, 0x9186, 0x9082, 0xB78E, 0xB386, 0xB182, 0xA0BE, 0xA3BE, 0xA19E, 0xA08E,
+ 0xAFBE, 0xA79E, 0xA38E, 0xA186, 0xA082, 0xA9F0, 0xEA7C, 0xD478, 0xF51E, 0xA870,
+ 0xEA1C, 0xD418, 0xF506, 0xA810, 0xEA04, 0xED7E, 0x94F8, 0xE53E, 0xDA7C, 0xCA3C,
+ 0xB478, 0xED1E, 0x9438, 0xE50E, 0xDA1C, 0xCA0C, 0xB418, 0xED06, 0x9408, 0xE502,
+ 0xDA04, 0x9AFC, 0xDD7E, 0x8A7C, 0xCD3E, 0xBA7C, 0xC51E, 0x9A3C, 0xDD1E, 0x8A1C,
+ 0xCD0E, 0xBA1C, 0xC506, 0x9A0C, 0xDD06, 0x8A04, 0xCD02, 0xBA04, 0x8D7E, 0xBD7E,
+ 0x853E, 0x9D3E, 0x8D1E, 0xBD1E, 0x850E, 0x9D0E, 0x8D06, 0xBD06, 0x8502, 0x9D02,
+ 0xD2FC, 0xADF8, 0xEB7E, 0xA4F8, 0xE93E, 0xD67C, 0xD23C, 0xAC78, 0xEB1E, 0xA438,
+ 0xE90E, 0xD61C, 0xD20C, 0xAC18, 0xEB06, 0xA408, 0xE902, 0xC97E, 0xB2FC, 0x96FC,
+ 0x927C, 0xD93E, 0xCB3E, 0xB67C, 0xC91E, 0xB23C, 0x963C, 0x921C, 0xD90E, 0xCB0E,
+ 0xB61C, 0xC906, 0xB20C, 0x960C, 0x9204, 0xD902, 0x997E, 0x8B7E, 0x893E, 0xBB7E,
+ 0xB93E, 0xE4A0, 0xF928, 0xD940, 0xF650, 0xFD94, 0xCB40, 0xF2D0, 0xEDA0, 0xFB68,
+ 0x8940, 0xE250, 0xCCA0, 0xF328, 0xB940, 0xEE50, 0xFB94, 0xC5A0, 0xF168, 0x9B40,
+ 0xE6D0, 0xF9B4, 0xDDA0, 0xF768, 0xFDDA, 0x84A0, 0xE128, 0xC650, 0xF194, 0x9CA0,
+ 0xE728, 0xF9CA, 0xDE50, 0xF794, 0xC2D0, 0x8DA0, 0xE368, 0xCED0, 0xF3B4, 0xBDA0,
+ 0xEF68, 0xFBDA, 0x8250, 0xC328, 0x8E50, 0xE394, 0xCF28, 0xF3CA, 0xBE50, 0xEF94,
+ 0xC168, 0x86D0, 0xE1B4, 0xC768, 0xF1DA, 0x9ED0, 0xE7B4, 0xDF68, 0xF7DA, 0x8128,
+ 0xC194, 0x8728, 0xE1CA, 0xC794, 0x9F28, 0xE7CA, 0x8368, 0xC3B4, 0x8F68, 0xE3DA,
+ 0xCFB4, 0xBF68, 0xEFDA, 0xE8A0, 0xFA28, 0xD340, 0xF4D0, 0xFD34, 0xEBA0, 0xFAE8,
+ 0x9140, 0xE450, 0xF914, 0xD8A0, 0xF628, 0xFD8A, 0xC9A0, 0xF268, 0xB340, 0xECD0,
+ 0xFB34, 0x9740, 0xE5D0, 0xF974, 0xDBA0, 0xF6E8, 0xFDBA, 0x88A0, 0xE228, 0xCC50,
+ 0xF314, 0xB8A0, 0xEE28, 0xFB8A, 0xC4D0, 0xF134, 0x99A0, 0xE668, 0xF99A, 0xDCD0,
+ 0xF734, 0x8BA0, 0xE2E8, 0xCDD0, 0xF374, 0xBBA0, 0xEEE8, 0xFBBA, 0x8450, 0xE114,
+ 0xC628, 0xF18A, 0x9C50, 0xE714, 0xDE28, 0xF78A, 0xC268, 0x8CD0, 0xE334, 0xCE68,
+ 0xF39A, 0xBCD0, 0xEF34, 0x85D0, 0xE174, 0xC6E8, 0xF1BA, 0x9DD0, 0xE774, 0xDEE8,
+ 0xF7BA, 0x8228, 0xC314, 0x8E28, 0xE38A, 0xCF14, 0xC134, 0x8668, 0xE19A, 0xC734,
+ 0x9E68, 0xE79A, 0xDF34, 0x82E8, 0xC374, 0x8EE8, 0xE3BA, 0xCF74, 0xBEE8, 0xEFBA,
+ 0x8114, 0xC18A, 0x8714, 0xC78A, 0x8334, 0xC39A, 0x8F34, 0xCF9A, 0x8174, 0xC1BA,
+ 0x8774, 0xC7BA, 0x9F74, 0xDFBA, 0xA140, 0xE850, 0xFA14, 0xD1A0, 0xF468, 0xFD1A,
+ 0xA740, 0xE9D0, 0xFA74, 0xD7A0, 0xF5E8, 0xFD7A, 0x90A0, 0xE428, 0xF90A, 0xD850,
+ 0xF614, 0xC8D0, 0xF234, 0xB1A0, 0xEC68, 0xFB1A, 0x93A0, 0xE4E8, 0xF93A, 0xD9D0,
+ 0xF674, 0xCBD0, 0xF2F4, 0xB7A0, 0xEDE8, 0xFB7A, 0x8850, 0xE214, 0xCC28, 0xF30A,
+ 0xB850, 0xEE14, 0xC468, 0xF11A, 0x98D0, 0xE634, 0xDC68, 0xF71A, 0x89D0, 0xE274,
+ 0xCCE8, 0xF33A, 0xB9D0, 0xEE74, 0xC5E8, 0xF17A, 0x9BD0, 0xE6F4, 0xDDE8, 0xF77A,
+ 0x8428, 0xE10A, 0xC614, 0x9C28, 0xE70A, 0xC234, 0x8C68, 0xE31A, 0xCE34, 0xBC68,
+ 0xEF1A, 0x84E8, 0xE13A, 0xC674, 0x9CE8, 0xE73A, 0xDE74, 0xC2F4, 0x8DE8, 0xE37A,
+ 0xCEF4, 0xBDE8, 0xEF7A, 0x8214, 0xC30A, 0x8E14, 0xC11A, 0x8634, 0xC71A, 0x9E34,
+ 0x8274, 0xC33A, 0x8E74, 0xCF3A, 0xBE74, 0xC17A, 0x86F4, 0xC77A, 0x9EF4, 0xDF7A,
+ 0x810A, 0x870A, 0x831A, 0x8F1A, 0x813A, 0x873A, 0x9F3A, 0x837A, 0x8F7A, 0xBF7A,
+ 0xA0A0, 0xE828, 0xFA0A, 0xD0D0, 0xF434, 0xA3A0, 0xE8E8, 0xFA3A, 0xD3D0, 0xF4F4,
+ 0xAFA0, 0xEBE8, 0xFAFA, 0x9050, 0xE414, 0xD828, 0xF60A, 0xC868, 0xF21A, 0xB0D0,
+ 0xEC34, 0x91D0, 0xE474, 0xD8E8, 0xF63A, 0xC9E8, 0xF27A, 0xB3D0, 0xECF4, 0x97D0,
+ 0xE5F4, 0xDBE8, 0xF6FA, 0x8828, 0xE20A, 0xCC14, 0xC434, 0x9868, 0xE61A, 0xDC34,
+ 0x88E8, 0xE23A, 0xCC74, 0xB8E8, 0xEE3A, 0xC4F4, 0x99E8, 0xE67A, 0xDCF4, 0x8BE8,
+ 0xE2FA, 0xCDF4, 0xBBE8, 0xEEFA, 0x8414, 0xC60A, 0xC21A, 0x8C34, 0xCE1A, 0x8474,
+ 0xC63A, 0x9C74, 0xDE3A, 0xC27A, 0x8CF4, 0xCE7A, 0xBCF4, 0x85F4, 0xC6FA, 0x9DF4,
+ 0xDEFA, 0x820A, 0x861A, 0x823A, 0x8E3A, 0x867A, 0x9E7A, 0x82FA, 0x8EFA, 0xBEFA,
+ 0xA050, 0xE814, 0xD068, 0xF41A, 0xA1D0, 0xE874, 0xD1E8, 0xF47A, 0xA7D0, 0xE9F4,
+ 0xD7E8, 0xF5FA, 0x9028, 0xE40A, 0xC834, 0xB068, 0xEC1A, 0x90E8, 0xE43A, 0xD874,
+ 0xC8F4, 0xB1E8, 0xEC7A, 0x93E8, 0xE4FA, 0xD9F4, 0xCBF4, 0xB7E8, 0xEDFA, 0x8814,
+ 0xC41A, 0x9834, 0x8874, 0xCC3A, 0xB874, 0xC47A, 0x98F4, 0xDC7A, 0x89F4, 0xCCFA,
+ 0xB9F4, 0xC5FA, 0x9BF4, 0xDDFA, 0x840A, 0x8C1A, 0x843A, 0x9C3A, 0x8C7A, 0xBC7A,
+ 0x84FA, 0x9CFA, 0x8DFA, 0xBDFA, 0xEA40, 0xFA90, 0xED60, 0xFB58, 0xE520, 0xF948,
+ 0xDA40, 0xF690, 0xFDA4, 0x9AC0, 0xE6B0, 0xF9AC, 0xDD60, 0xF758, 0xFDD6, 0x8A40,
+ 0xE290, 0xCD20, 0xF348, 0xBA40, 0xEE90, 0xFBA4, 0x8D60, 0xE358, 0xCEB0, 0xF3AC,
+ 0xBD60, 0xEF58, 0xFBD6, 0x8520, 0xE148, 0xC690, 0xF1A4, 0x9D20, 0xE748, 0xF9D2,
+ 0xDE90, 0xF7A4, 0x86B0, 0xE1AC, 0xC758, 0xF1D6, 0x9EB0, 0xE7AC, 0xDF58, 0xF7D6,
+ 0x8290, 0xC348, 0x8E90, 0xE3A4, 0xCF48, 0xF3D2, 0xBE90, 0xEFA4, 0x8358, 0xC3AC,
+ 0x8F58, 0xE3D6, 0xCFAC, 0xBF58, 0xEFD6, 0x8148, 0xC1A4, 0x8748, 0xE1D2, 0xC7A4,
+ 0x9F48, 0xE7D2, 0xDFA4, 0xD2C0, 0xF4B0, 0xFD2C, 0xEB60, 0xFAD8, 0xE920, 0xFA48,
+ 0xD640, 0xF590, 0xFD64, 0xC960, 0xF258, 0xB2C0, 0xECB0, 0xFB2C, 0x96C0, 0xE5B0,
+ 0xF96C, 0x9240, 0xE490, 0xF924, 0xD920, 0xF648, 0xFD92, 0xCB20, 0xF2C8, 0xB640,
+ 0xED90, 0xFB64, 0xC4B0, 0xF12C, 0x9960, 0xE658, 0xF996, 0xDCB0, 0xF72C, 0x8B60,
+ 0xE2D8, 0x8920, 0xE248, 0xBB60, 0xCC90, 0xF324, 0xB920, 0xEE48, 0xFB92, 0xC590,
+ 0xF164, 0x9B20, 0xE6C8, 0xF9B2, 0xDD90, 0xF764, 0xC258, 0x8CB0, 0xE32C, 0xCE58,
+ 0xF396, 0xBCB0, 0xEF2C, 0x85B0, 0xE16C, 0x8490, 0xE124, 0x9DB0, 0xC648, 0xF192,
+ 0x9C90, 0xE724, 0xDE48, 0xF792, 0xC2C8, 0x8D90, 0xE364, 0xCEC8, 0xF3B2, 0xBD90,
+ 0xEF64, 0xC12C, 0x8658, 0xE196, 0xC72C, 0x9E58, 0xE796, 0xDF2C, 0x82D8, 0x8248,
+ 0x8ED8, 0xC324, 0x8E48, 0xE392, 0xBED8, 0xCF24, 0xBE48, 0xEF92, 0xC164, 0x86C8,
+ 0xE1B2, 0xC764, 0x9EC8, 0xE7B2, 0xDF64, 0x832C, 0xC396, 0x8F2C, 0xCF96, 0x816C,
+ 0x8124, 0x876C, 0xC192, 0x8724, 0x9F6C, 0xC792, 0x9F24, 0x8364, 0xC3B2, 0x8F64,
+ 0xCFB2, 0xBF64, 0xD160, 0xF458, 0xFD16, 0xA6C0, 0xE9B0, 0xFA6C, 0xA240, 0xE890,
+ 0xFA24, 0xD760, 0xF5D8, 0xFD76, 0xD320, 0xF4C8, 0xFD32, 0xAE40, 0xEB90, 0xFAE4,
+ 0xC8B0, 0xF22C, 0xB160, 0xEC58, 0xFB16, 0x9360, 0xE4D8, 0xF936, 0x9120, 0xE448,
+ 0xF912, 0xD890, 0xF624, 0xCBB0, 0xF2EC, 0xB760, 0xC990, 0xF264, 0xB320, 0xECC8,
+ 0xFB32, 0x9720, 0xE5C8, 0xF972, 0xDB90, 0xF6E4, 0xC458, 0xF116, 0x98B0, 0xE62C,
+ 0xDC58, 0xF716, 0x89B0, 0xE26C, 0x8890, 0xE224, 0xB9B0, 0xCC48, 0xF312, 0xB890,
+ 0xEE24, 0xC5D8, 0xF176, 0x9BB0, 0xC4C8, 0xF132, 0x9990, 0xE664, 0xDCC8, 0xF732,
+ 0x8B90, 0xE2E4, 0xCDC8, 0xF372, 0xBB90, 0xEEE4, 0xC22C, 0x8C58, 0xE316, 0xCE2C,
+ 0xBC58, 0xEF16, 0x84D8, 0xE136, 0x8448, 0xE112, 0x9CD8, 0xC624, 0x9C48, 0xE712,
+ 0xDE24, 0xC2EC, 0x8DD8, 0xC264, 0x8CC8, 0xE332, 0xBDD8, 0xCE64, 0xBCC8, 0xEF32,
+ 0x85C8, 0xE172, 0xC6E4, 0x9DC8, 0xE772, 0xDEE4, 0xC116, 0x862C, 0xC716, 0x9E2C,
+ 0x826C, 0x8224, 0x8E6C, 0xC312, 0x8E24, 0xBE6C, 0xCF12, 0xC176, 0x86EC, 0xC132,
+ 0x8664, 0x9EEC, 0xC732, 0x9E64, 0xDF32, 0x82E4, 0xC372, 0x8EE4, 0xCF72, 0xBEE4,
+ 0x8316, 0x8F16, 0x8136, 0x8112, 0x8736, 0x8712, 0x9F36, 0x8376, 0x8332, 0x8F76,
+ 0x8F32, 0xBF76, 0x8172, 0x8772, 0x9F72, 0xD0B0, 0xF42C, 0xA360, 0xE8D8, 0xFA36,
+ 0xA120, 0xE848, 0xFA12, 0xD3B0, 0xF4EC, 0xD190, 0xF464, 0xAF60, 0xEBD8, 0xFAF6,
+ 0xA720, 0xE9C8, 0xFA72, 0xD790, 0xF5E4, 0xC858, 0xF216, 0xB0B0, 0xEC2C, 0x91B0,
+ 0xE46C, 0x9090, 0xE424, 0xD848, 0xF612, 0xC9D8, 0xF276, 0xB3B0, 0xC8C8, 0xF232,
+ 0xB190, 0xEC64, 0x97B0, 0xE5EC, 0x9390, 0xE4E4, 0xD9C8, 0xF672, 0xCBC8, 0xF2F2,
+ 0xB790, 0xEDE4, 0xC42C, 0x9858, 0xE616, 0xDC2C, 0x88D8, 0xE236, 0x8848, 0xE212,
+ 0xB8D8, 0xCC24, 0xB848, 0xEE12, 0xC4EC, 0x99D8, 0xC464, 0x98C8, 0xE632, 0xDC64,
+ 0x8BD8, 0xE2F6, 0x89C8, 0xE272, 0xBBD8, 0xCCE4, 0xB9C8, 0xEE72, 0xC5E4, 0x9BC8,
+ 0xE6F2, 0xDDE4, 0xC216, 0x8C2C, 0xCE16, 0x846C, 0x8424, 0x9C6C, 0xC612, 0x9C24,
+ 0xC276, 0x8CEC, 0xC232, 0x8C64, 0xBCEC, 0xCE32, 0xBC64, 0x85EC, 0x84E4, 0x9DEC,
+ 0xC672, 0x9CE4, 0xDE72, 0xC2F2, 0x8DE4, 0xCEF2, 0xBDE4, 0x8616, 0x8236, 0x8212,
+ 0x8E36, 0x8E12, 0x8676, 0x8632, 0x9E76, 0x9E32, 0x82F6, 0x8272, 0x8EF6, 0x8E72,
+ 0xBEF6, 0xBE72, 0x86F2, 0x9EF2, 0xD058, 0xF416, 0xA1B0, 0xE86C, 0xA090, 0xE824,
+ 0xD1D8, 0xF476, 0xD0C8, 0xF432, 0xA7B0, 0xE9EC, 0xA390, 0xE8E4, 0xD7D8, 0xF5F6,
+ 0xD3C8, 0xF4F2, 0xAF90, 0xEBE4, 0xC82C, 0xB058, 0xEC16, 0x90D8, 0xE436, 0x9048,
+ 0xE412, 0xD824, 0xC8EC, 0xB1D8, 0xC864, 0xB0C8, 0xEC32, 0x93D8, 0xE4F6, 0x91C8,
+ 0xE472, 0xD8E4, 0xCBEC, 0xB7D8, 0xC9E4, 0xB3C8, 0xECF2, 0x97C8, 0xE5F2, 0xDBE4,
+ 0xC416, 0x982C, 0x886C, 0x8824, 0xB86C, 0xCC12, 0xC476, 0x98EC, 0xC432, 0x9864,
+ 0xDC32, 0x89EC, 0x88E4, 0xB9EC, 0xCC72, 0xB8E4, 0xC5F6, 0x9BEC, 0xC4F2, 0x99E4,
+ 0xDCF2, 0x8BE4, 0xCDF2, 0xBBE4, 0x8C16, 0x8436, 0x8412, 0x9C36, 0x8C76, 0x8C32,
+ 0xBC76, 0x84F6, 0x8472, 0x9CF6, 0x9C72, 0x8DF6, 0x8CF2, 0xBDF6, 0xBCF2, 0x85F2,
+ 0x9DF2, 0xD02C, 0xA0D8, 0xE836, 0xA048, 0xE812, 0xD0EC, 0xD064, 0xA3D8, 0xE8F6,
+ 0xA1C8, 0xE872, 0xD3EC, 0xD1E4, 0xAFD8, 0xEBF6, 0xA7C8, 0xE9F2, 0xC816, 0x906C,
+ 0x9024, 0xC876, 0xB0EC, 0xC832, 0xB064, 0x91EC, 0x90E4, 0xD872, 0xC9F6, 0xB3EC,
+ 0xC8F2, 0xB1E4, 0x97EC, 0x93E4, 0xD9F2, 0x8836, 0x8812, 0x9876, 0x9832, 0x88F6,
+ 0x8872, 0xB8F6, 0xB872, 0x99F6, 0x98F2, 0x8BF6, 0x89F2, 0xBBF6, 0xB9F2, 0xD4C0,
+ 0xF530, 0xFD4C, 0xEA20, 0xFA88, 0xDAE0, 0xF6B8, 0xFDAE, 0xCA60, 0xF298, 0xB4C0,
+ 0xED30, 0xFB4C, 0x9440, 0xE510, 0xF944, 0xDA20, 0xF688, 0xFDA2, 0xCD70, 0xF35C,
+ 0xBAE0, 0xEEB8, 0xFBAE, 0xC530, 0xF14C, 0x9A60, 0xE698, 0xF9A6, 0xDD30, 0xF74C,
+ 0x8A20, 0xE288, 0xCD10, 0xF344, 0xBA20, 0xEE88, 0xFBA2, 0xC6B8, 0xF1AE, 0x9D70,
+ 0xE75C, 0xDEB8, 0xF7AE, 0xC298, 0x8D30, 0xE34C, 0xCE98, 0xF3A6, 0xBD30, 0xEF4C,
+ 0x8510, 0xE144, 0xC688, 0xF1A2, 0x9D10, 0xE744, 0xDE88, 0xF7A2, 0xC35C, 0x8EB8,
+ 0xE3AE, 0xCF5C, 0xBEB8, 0xEFAE, 0xC14C, 0x8698, 0xE1A6, 0xC74C, 0x9E98, 0xE7A6,
+ 0xDF4C, 0x8288, 0xC344, 0x8E88, 0xE3A2, 0xCF44, 0xBE88, 0xEFA2, 0xC1AE, 0x875C,
+ 0xC7AE, 0x9F5C, 0xDFAE, 0x834C, 0xC3A6, 0x8F4C, 0xCFA6, 0xBF4C, 0x8144, 0xC1A2,
+ 0x8744, 0xC7A2, 0x9F44, 0xDFA2, 0xE970, 0xFA5C, 0xD6E0, 0xF5B8, 0xFD6E, 0xD260,
+ 0xF498, 0xFD26, 0xACC0, 0xEB30, 0xFACC, 0xA440, 0xE910, 0xFA44, 0xD620, 0xF588,
+ 0xFD62, 0x92E0, 0xE4B8, 0xF92E, 0xD970, 0xF65C, 0xCB70, 0xF2DC, 0xB6E0, 0xC930,
+ 0xF24C, 0xB260, 0xEC98, 0xFB26, 0x9660, 0xE598, 0xF966, 0x9220, 0xE488, 0xF922,
+ 0xD910, 0xF644, 0xCB10, 0xF2C4, 0xB620, 0xED88, 0xFB62, 0x8970, 0xE25C, 0xCCB8,
+ 0xF32E, 0xB970, 0xEE5C, 0xC5B8, 0xF16E, 0x9B70, 0xC498, 0xF126, 0x9930, 0xE64C,
+ 0xDC98, 0xF726, 0x8B30, 0xE2CC, 0x8910, 0xE244, 0xBB30, 0xCC88, 0xF322, 0xB910,
+ 0xEE44, 0xC588, 0xF162, 0x9B10, 0xE6C4, 0xDD88, 0xF762, 0x84B8, 0xE12E, 0xC65C,
+ 0x9CB8, 0xE72E, 0xDE5C, 0xC2DC, 0x8DB8, 0xC24C, 0x8C98, 0xE326, 0xBDB8, 0xCE4C,
+ 0xBC98, 0xEF26, 0x8598, 0xE166, 0x8488, 0xE122, 0x9D98, 0xC644, 0x9C88, 0xE722,
+ 0xDE44, 0xC2C4, 0x8D88, 0xE362, 0xCEC4, 0xBD88, 0xEF62, 0x825C, 0xC32E, 0x8E5C,
+ 0xCF2E
+};
+
+static const unsigned short int c49_odd_bitpattern[] = {
+ /* Appendix E - Code 49 Encodation Patterns (Odd Symbol Character Parity) */
+ 0xC940, 0xF250, 0xECA0, 0xFB28, 0xE5A0, 0xF968, 0xDB40, 0xF6D0, 0xFDB4, 0xC4A0,
+ 0xF128, 0x9940, 0xE650, 0xF994, 0xDCA0, 0xF728, 0xFDCA, 0x8B40, 0xE2D0, 0xCDA0,
+ 0xF368, 0xBB40, 0xEED0, 0xFBB4, 0xC250, 0x8CA0, 0xE328, 0xCE50, 0xF394, 0xBCA0,
+ 0xEF28, 0xFBCA, 0x85A0, 0xE168, 0xC6D0, 0xF1B4, 0x9DA0, 0xE768, 0xF9DA, 0xDED0,
+ 0xF7B4, 0xC128, 0x8650, 0xE194, 0xC728, 0xF1CA, 0x9E50, 0xE794, 0xDF28, 0xF7CA,
+ 0x82D0, 0xC368, 0x8ED0, 0xE3B4, 0xCF68, 0xF3DA, 0xBED0, 0xEFB4, 0x8328, 0xC394,
+ 0x8F28, 0xE3CA, 0xCF94, 0x8168, 0xC1B4, 0x8768, 0xE1DA, 0xC7B4, 0x9F68, 0xE7DA,
+ 0xDFB4, 0xD140, 0xF450, 0xFD14, 0xE9A0, 0xFA68, 0xD740, 0xF5D0, 0xFD74, 0xC8A0,
+ 0xF228, 0xB140, 0xEC50, 0xFB14, 0x9340, 0xE4D0, 0xF934, 0xD9A0, 0xF668, 0xFD9A,
+ 0xCBA0, 0xF2E8, 0xB740, 0xEDD0, 0xFB74, 0xC450, 0xF114, 0x98A0, 0xE628, 0xF98A,
+ 0xDC50, 0xF714, 0x89A0, 0xE268, 0xCCD0, 0xF334, 0xB9A0, 0xEE68, 0xFB9A, 0xC5D0,
+ 0xF174, 0x9BA0, 0xE6E8, 0xF9BA, 0xDDD0, 0xF774, 0xC228, 0x8C50, 0xE314, 0xCE28,
+ 0xF38A, 0xBC50, 0xEF14, 0x84D0, 0xE134, 0xC668, 0xF19A, 0x9CD0, 0xE734, 0xDE68,
+ 0xF79A, 0xC2E8, 0x8DD0, 0xE374, 0xCEE8, 0xF3BA, 0xBDD0, 0xEF74, 0xC114, 0x8628,
+ 0xE18A, 0xC714, 0x9E28, 0xE78A, 0x8268, 0xC334, 0x8E68, 0xE39A, 0xCF34, 0xBE68,
+ 0xEF9A, 0xC174, 0x86E8, 0xE1BA, 0xC774, 0x9EE8, 0xE7BA, 0xDF74, 0x8314, 0xC38A,
+ 0x8F14, 0x8134, 0xC19A, 0x8734, 0xC79A, 0x9F34, 0x8374, 0xC3BA, 0x8F74, 0xCFBA,
+ 0xBF74, 0xD0A0, 0xF428, 0xFD0A, 0xA340, 0xE8D0, 0xFA34, 0xD3A0, 0xF4E8, 0xFD3A,
+ 0xAF40, 0xEBD0, 0xFAF4, 0xC850, 0xF214, 0xB0A0, 0xEC28, 0xFB0A, 0x91A0, 0xE468,
+ 0xF91A, 0xD8D0, 0xF634, 0xC9D0, 0xF274, 0xB3A0, 0xECE8, 0xFB3A, 0x97A0, 0xE5E8,
+ 0xF97A, 0xDBD0, 0xF6F4, 0xC428, 0xF10A, 0x9850, 0xE614, 0xDC28, 0xF70A, 0x88D0,
+ 0xE234, 0xCC68, 0xF31A, 0xB8D0, 0xEE34, 0xC4E8, 0xF13A, 0x99D0, 0xE674, 0xDCE8,
+ 0xF73A, 0x8BD0, 0xE2F4, 0xCDE8, 0xF37A, 0xBBD0, 0xEEF4, 0xC214, 0x8C28, 0xE30A,
+ 0xCE14, 0x8468, 0xE11A, 0xC634, 0x9C68, 0xE71A, 0xDE34, 0xC274, 0x8CE8, 0xE33A,
+ 0xCE74, 0xBCE8, 0xEF3A, 0x85E8, 0xE17A, 0xC6F4, 0x9DE8, 0xE77A, 0xDEF4, 0xC10A,
+ 0x8614, 0xC70A, 0x8234, 0xC31A, 0x8E34, 0xCF1A, 0xC13A, 0x8674, 0xC73A, 0x9E74,
+ 0xDF3A, 0x82F4, 0xC37A, 0x8EF4, 0xCF7A, 0xBEF4, 0x830A, 0x811A, 0x871A, 0x833A,
+ 0x8F3A, 0x817A, 0x877A, 0x9F7A, 0xD050, 0xF414, 0xA1A0, 0xE868, 0xFA1A, 0xD1D0,
+ 0xF474, 0xA7A0, 0xE9E8, 0xFA7A, 0xD7D0, 0xF5F4, 0xC828, 0xF20A, 0xB050, 0xEC14,
+ 0x90D0, 0xE434, 0xD868, 0xF61A, 0xC8E8, 0xF23A, 0xB1D0, 0xEC74, 0x93D0, 0xE4F4,
+ 0xD9E8, 0xF67A, 0xCBE8, 0xF2FA, 0xB7D0, 0xEDF4, 0xC414, 0x9828, 0xE60A, 0x8868,
+ 0xE21A, 0xCC34, 0xB868, 0xEE1A, 0xC474, 0x98E8, 0xE63A, 0xDC74, 0x89E8, 0xE27A,
+ 0xCCF4, 0xB9E8, 0xEE7A, 0xC5F4, 0x9BE8, 0xE6FA, 0xDDF4, 0xC20A, 0x8C14, 0x8434,
+ 0xC61A, 0x9C34, 0xC23A, 0x8C74, 0xCE3A, 0xBC74, 0x84F4, 0xC67A, 0x9CF4, 0xDE7A,
+ 0xC2FA, 0x8DF4, 0xCEFA, 0xBDF4, 0x860A, 0x821A, 0x8E1A, 0x863A, 0x9E3A, 0x827A,
+ 0x8E7A, 0xBE7A, 0x86FA, 0x9EFA, 0xD028, 0xF40A, 0xA0D0, 0xE834, 0xD0E8, 0xF43A,
+ 0xA3D0, 0xE8F4, 0xD3E8, 0xF4FA, 0xAFD0, 0xEBF4, 0xC814, 0x9068, 0xE41A, 0xD834,
+ 0xC874, 0xB0E8, 0xEC3A, 0x91E8, 0xE47A, 0xD8F4, 0xC9F4, 0xB3E8, 0xECFA, 0x97E8,
+ 0xE5FA, 0xDBF4, 0xC40A, 0x8834, 0xCC1A, 0xC43A, 0x9874, 0xDC3A, 0x88F4, 0xCC7A,
+ 0xB8F4, 0xC4FA, 0x99F4, 0xDCFA, 0x8BF4, 0xCDFA, 0xBBF4, 0x841A, 0x8C3A, 0x847A,
+ 0x9C7A, 0x8CFA, 0xBCFA, 0x85FA, 0x9DFA, 0xF520, 0xFD48, 0xDAC0, 0xF6B0, 0xFDAC,
+ 0xCA40, 0xF290, 0xED20, 0xFB48, 0xCD60, 0xF358, 0xBAC0, 0xEEB0, 0xFBAC, 0xC520,
+ 0xF148, 0x9A40, 0xE690, 0xF9A4, 0xDD20, 0xF748, 0xFDD2, 0xC6B0, 0xF1AC, 0x9D60,
+ 0xE758, 0xF9D6, 0xDEB0, 0xF7AC, 0xC290, 0x8D20, 0xE348, 0xCE90, 0xF3A4, 0xBD20,
+ 0xEF48, 0xFBD2, 0xC358, 0x8EB0, 0xE3AC, 0xCF58, 0xF3D6, 0xBEB0, 0xEFAC, 0xC148,
+ 0x8690, 0xE1A4, 0xC748, 0xF1D2, 0x9E90, 0xE7A4, 0xDF48, 0xF7D2, 0xC1AC, 0x8758,
+ 0xE1D6, 0xC7AC, 0x9F58, 0xE7D6, 0xDFAC, 0x8348, 0xC3A4, 0x8F48, 0xE3D2, 0xCFA4,
+ 0xBF48, 0xEFD2, 0xE960, 0xFA58, 0xD6C0, 0xF5B0, 0xFD6C, 0xD240, 0xF490, 0xFD24,
+ 0xEB20, 0xFAC8, 0x92C0, 0xE4B0, 0xF92C, 0xD960, 0xF658, 0xFD96, 0xCB60, 0xF2D8,
+ 0xB6C0, 0xC920, 0xF248, 0xB240, 0xEC90, 0xFB24, 0x9640, 0xE590, 0xF964, 0xDB20,
+ 0xF6C8, 0xFDB2, 0x8960, 0xE258, 0xCCB0, 0xF32C, 0xB960, 0xEE58, 0xFB96, 0xC5B0,
+ 0xF16C, 0x9B60, 0xC490, 0xF124, 0x9920, 0xE648, 0xF992, 0xDC90, 0xF724, 0x8B20,
+ 0xE2C8, 0xCD90, 0xF364, 0xBB20, 0xEEC8, 0xFBB2, 0x84B0, 0xE12C, 0xC658, 0xF196,
+ 0x9CB0, 0xE72C, 0xDE58, 0xF796, 0xC2D8, 0x8DB0, 0xC248, 0x8C90, 0xE324, 0xBDB0,
+ 0xCE48, 0xF392, 0xBC90, 0xEF24, 0x8590, 0xE164, 0xC6C8, 0xF1B2, 0x9D90, 0xE764,
+ 0xDEC8, 0xF7B2, 0x8258, 0xC32C, 0x8E58, 0xE396, 0xCF2C, 0xBE58, 0xEF96, 0xC16C,
+ 0x86D8, 0xC124, 0x8648, 0xE192, 0x9ED8, 0xC724, 0x9E48, 0xE792, 0xDF24, 0x82C8,
+ 0xC364, 0x8EC8, 0xE3B2, 0xCF64, 0xBEC8, 0xEFB2, 0x812C, 0xC196, 0x872C, 0xC796,
+ 0x9F2C, 0x836C, 0x8324, 0x8F6C, 0xC392, 0x8F24, 0xBF6C, 0xCF92, 0x8164, 0xC1B2,
+ 0x8764, 0xC7B2, 0x9F64, 0xDFB2, 0xA2C0, 0xE8B0, 0xFA2C, 0xD360, 0xF4D8, 0xFD36,
+ 0xD120, 0xF448, 0xFD12, 0xAEC0, 0xEBB0, 0xFAEC, 0xA640, 0xE990, 0xFA64, 0xD720,
+ 0xF5C8, 0xFD72, 0x9160, 0xE458, 0xF916, 0xD8B0, 0xF62C, 0xC9B0, 0xF26C, 0xB360,
+ 0xC890, 0xF224, 0xB120, 0xEC48, 0xFB12, 0x9760, 0xE5D8, 0xF976, 0x9320, 0xE4C8,
+ 0xF932, 0xD990, 0xF664, 0xCB90, 0xF2E4, 0xB720, 0xEDC8, 0xFB72, 0x88B0, 0xE22C,
+ 0xCC58, 0xF316, 0xB8B0, 0xEE2C, 0xC4D8, 0xF136, 0x99B0, 0xC448, 0xF112, 0x9890,
+ 0xE624, 0xDC48, 0xF712, 0x8BB0, 0xE2EC, 0x8990, 0xE264, 0xBBB0, 0xCCC8, 0xF332,
+ 0xB990, 0xEE64, 0xC5C8, 0xF172, 0x9B90, 0xE6E4, 0xDDC8, 0xF772, 0x8458, 0xE116,
+ 0xC62C, 0x9C58, 0xE716, 0xDE2C, 0xC26C, 0x8CD8, 0xC224, 0x8C48, 0xE312, 0xBCD8,
+ 0xCE24, 0xBC48, 0xEF12, 0x85D8, 0xE176, 0x84C8, 0xE132, 0x9DD8, 0xC664, 0x9CC8,
+ 0xE732, 0xDE64, 0xC2E4, 0x8DC8, 0xE372, 0xCEE4, 0xBDC8, 0xEF72, 0x822C, 0xC316,
+ 0x8E2C, 0xCF16, 0xC136, 0x866C, 0xC112, 0x8624, 0x9E6C, 0xC712, 0x9E24, 0x82EC,
+ 0x8264, 0x8EEC, 0xC332, 0x8E64, 0xBEEC, 0xCF32, 0xBE64, 0xC172, 0x86E4, 0xC772,
+ 0x9EE4, 0xDF72, 0x8116, 0x8716, 0x8336, 0x8312, 0x8F36, 0x8F12, 0x8176, 0x8132,
+ 0x8776, 0x8732, 0x9F76, 0x9F32, 0x8372, 0x8F72, 0xBF72, 0xA160, 0xE858, 0xFA16,
+ 0xD1B0, 0xF46C, 0xD090, 0xF424, 0xA760, 0xE9D8, 0xFA76, 0xA320, 0xE8C8, 0xFA32,
+ 0xD7B0, 0xF5EC, 0xD390, 0xF4E4, 0xAF20, 0xEBC8, 0xFAF2, 0x90B0, 0xE42C, 0xD858,
+ 0xF616, 0xC8D8, 0xF236, 0xB1B0, 0xC848, 0xF212, 0xB090, 0xEC24, 0x93B0, 0xE4EC,
+ 0x9190, 0xE464, 0xD8C8, 0xF632, 0xCBD8, 0xF2F6, 0xB7B0, 0xC9C8, 0xF272, 0xB390,
+ 0xECE4, 0x9790, 0xE5E4, 0xDBC8, 0xF6F2, 0x8858, 0xE216, 0xCC2C, 0xB858, 0xEE16,
+ 0xC46C, 0x98D8, 0xC424, 0x9848, 0xE612, 0xDC24, 0x89D8, 0xE276, 0x88C8, 0xE232,
+ 0xB9D8, 0xCC64, 0xB8C8, 0xEE32, 0xC5EC, 0x9BD8, 0xC4E4, 0x99C8, 0xE672, 0xDCE4,
+ 0x8BC8, 0xE2F2, 0xCDE4, 0xBBC8, 0xEEF2, 0x842C, 0xC616, 0x9C2C, 0xC236, 0x8C6C,
+ 0xC212, 0x8C24, 0xBC6C, 0xCE12, 0x84EC, 0x8464, 0x9CEC, 0xC632, 0x9C64, 0xDE32,
+ 0xC2F6, 0x8DEC, 0xC272, 0x8CE4, 0xBDEC, 0xCE72, 0xBCE4, 0x85E4, 0xC6F2, 0x9DE4,
+ 0xDEF2, 0x8216, 0x8E16, 0x8636, 0x8612, 0x9E36, 0x8276, 0x8232, 0x8E76, 0x8E32,
+ 0xBE76, 0x86F6, 0x8672, 0x9EF6, 0x9E72, 0x82F2, 0x8EF2, 0xBEF2, 0xA0B0, 0xE82C,
+ 0xD0D8, 0xF436, 0xD048, 0xF412, 0xA3B0, 0xE8EC, 0xA190, 0xE864, 0xD3D8, 0xF4F6,
+ 0xD1C8, 0xF472, 0xAFB0, 0xEBEC, 0xA790, 0xE9E4, 0xD7C8, 0xF5F2, 0x9058, 0xE416,
+ 0xD82C, 0xC86C, 0xB0D8, 0xC824, 0xB048, 0xEC12, 0x91D8, 0xE476, 0x90C8, 0xE432,
+ 0xD864, 0xC9EC, 0xB3D8, 0xC8E4, 0xB1C8, 0xEC72, 0x97D8, 0xE5F6, 0x93C8, 0xE4F2,
+ 0xD9E4, 0xCBE4, 0xB7C8, 0xEDF2, 0x882C, 0xCC16, 0xC436, 0x986C, 0xC412, 0x9824,
+ 0x88EC, 0x8864, 0xB8EC, 0xCC32, 0xB864, 0xC4F6, 0x99EC, 0xC472, 0x98E4, 0xDC72,
+ 0x8BEC, 0x89E4, 0xBBEC, 0xCCF2, 0xB9E4, 0xC5F2, 0x9BE4, 0xDDF2, 0x8416, 0x8C36,
+ 0x8C12, 0x8476, 0x8432, 0x9C76, 0x9C32, 0x8CF6, 0x8C72, 0xBCF6, 0xBC72, 0x85F6,
+ 0x84F2, 0x9DF6, 0x9CF2, 0x8DF2, 0xBDF2, 0xA058, 0xE816, 0xD06C, 0xD024, 0xA1D8,
+ 0xE876, 0xA0C8, 0xE832, 0xD1EC, 0xD0E4, 0xA7D8, 0xE9F6, 0xA3C8, 0xE8F2, 0xD7EC,
+ 0xD3E4, 0x902C, 0xC836, 0xB06C, 0xC812, 0x90EC, 0x9064, 0xD832, 0xC8F6, 0xB1EC,
+ 0xC872, 0xB0E4, 0x93EC, 0x91E4, 0xD8F2, 0xCBF6, 0xB7EC, 0xC9F2, 0xB3E4, 0x8816,
+ 0x9836, 0x8876, 0x8832, 0xB876, 0x98F6, 0x9872, 0x89F6, 0x88F2, 0xB9F6, 0xB8F2,
+ 0x9BF6, 0x99F2, 0xEA60, 0xFA98, 0xD440, 0xF510, 0xFD44, 0xED70, 0xFB5C, 0x94C0,
+ 0xE530, 0xF94C, 0xDA60, 0xF698, 0xFDA6, 0xCA20, 0xF288, 0xB440, 0xED10, 0xFB44,
+ 0x9AE0, 0xE6B8, 0xF9AE, 0xDD70, 0xF75C, 0x8A60, 0xE298, 0xCD30, 0xF34C, 0xBA60,
+ 0xEE98, 0xFBA6, 0xC510, 0xF144, 0x9A20, 0xE688, 0xF9A2, 0xDD10, 0xF744, 0x8D70,
+ 0xE35C, 0xCEB8, 0xF3AE, 0xBD70, 0xEF5C, 0x8530, 0xE14C, 0xC698, 0xF1A6, 0x9D30,
+ 0xE74C, 0xDE98, 0xF7A6, 0xC288, 0x8D10, 0xE344, 0xCE88, 0xF3A2, 0xBD10, 0xEF44,
+ 0x86B8, 0xE1AE, 0xC75C, 0x9EB8, 0xE7AE, 0xDF5C, 0x8298, 0xC34C, 0x8E98, 0xE3A6,
+ 0xCF4C, 0xBE98, 0xEFA6, 0xC144, 0x8688, 0xE1A2, 0xC744, 0x9E88, 0xE7A2, 0xDF44,
+ 0x835C, 0xC3AE, 0x8F5C, 0xCFAE, 0xBF5C, 0x814C, 0xC1A6, 0x874C, 0xC7A6, 0x9F4C,
+ 0xDFA6, 0x8344, 0xC3A2, 0x8F44, 0xCFA2, 0xBF44, 0xD2E0, 0xF4B8, 0xFD2E, 0xADC0,
+ 0xEB70, 0xFADC, 0xA4C0, 0xE930, 0xFA4C, 0xD660, 0xF598, 0xFD66, 0xD220, 0xF488,
+ 0xFD22, 0xAC40, 0xEB10, 0xFAC4, 0xC970, 0xF25C, 0xB2E0, 0xECB8, 0xFB2E, 0x96E0,
+ 0xE5B8, 0xF96E, 0x9260, 0xE498, 0xF926, 0xD930, 0xF64C, 0xCB30, 0xF2CC, 0xB660,
+ 0xC910, 0xF244, 0xB220, 0xEC88, 0xFB22, 0x9620, 0xE588, 0xF962, 0xDB10, 0xF6C4,
+ 0xC4B8, 0xF12E, 0x9970, 0xE65C, 0xDCB8, 0xF72E, 0x8B70, 0xE2DC, 0x8930, 0xE24C,
+ 0xBB70, 0xCC98, 0xF326, 0xB930, 0xEE4C, 0xC598, 0xF166, 0x9B30, 0xC488, 0xF122,
+ 0x9910, 0xE644, 0xDC88, 0xF722, 0x8B10, 0xE2C4, 0xCD88, 0xF362, 0xBB10, 0xEEC4,
+ 0xC25C, 0x8CB8, 0xE32E, 0xCE5C, 0xBCB8, 0xEF2E, 0x85B8, 0xE16E, 0x8498, 0xE126,
+ 0x9DB8, 0xC64C, 0x9C98, 0xE726, 0xDE4C, 0xC2CC, 0x8D98, 0xC244, 0x8C88, 0xE322,
+ 0xBD98, 0xCE44, 0xBC88, 0xEF22, 0x8588, 0xE162, 0xC6C4, 0x9D88, 0xE762, 0xDEC4,
+ 0xC12E, 0x865C, 0xC72E, 0x9E5C, 0xDF2E, 0x82DC, 0x824C, 0x8EDC, 0xC326, 0x8E4C,
+ 0xBEDC, 0xCF26, 0xBE4C, 0xC166, 0x86CC, 0xC122, 0x8644, 0x9ECC, 0xC722, 0x9E44,
+ 0xDF22, 0x82C4, 0xC362, 0x8EC4, 0xCF62, 0xBEC4, 0x832E, 0x8F2E, 0x816E, 0x8126,
+ 0x876E, 0x8726, 0x9F6E, 0x9F26, 0x8366, 0x8322, 0x8F66, 0x8F22, 0xBF66, 0x8162,
+ 0x8762, 0x9F62, 0xD170, 0xF45C, 0xA6E0, 0xE9B8, 0xFA6E, 0xA260, 0xE898, 0xFA26,
+ 0xD770, 0xF5DC, 0xD330, 0xF4CC, 0xD110, 0xF444, 0xAE60, 0xEB98, 0xFAE6, 0xA620,
+ 0xE988, 0xFA62, 0xD710, 0xF5C4, 0xC8B8, 0xF22E, 0xB170, 0xEC5C, 0x9370, 0xE4DC,
+ 0x9130, 0xE44C, 0xD898, 0xF626, 0xCBB8, 0xF2EE, 0xB770, 0xC998, 0xF266, 0xB330,
+ 0xC888, 0xF222, 0xB110, 0xEC44, 0x9730, 0xE5CC, 0x9310, 0xE4C4, 0xD988, 0xF662,
+ 0xCB88, 0xF2E2, 0xB710, 0xEDC4, 0xC45C, 0x98B8, 0xE62E, 0xDC5C, 0x89B8, 0xE26E,
+ 0x8898, 0xE226, 0xB9B8, 0xCC4C, 0xB898, 0xEE26, 0xC5DC, 0x9BB8, 0xC4CC, 0x9998,
+ 0xC444, 0x9888, 0xE622, 0xDC44, 0x8B98, 0xE2E6, 0x8988, 0xE262, 0xBB98, 0xCCC4,
+ 0xB988, 0xEE62, 0xC5C4, 0x9B88, 0xE6E2, 0xDDC4, 0xC22E, 0x8C5C, 0xCE2E, 0xBC5C,
+ 0x84DC, 0x844C, 0x9CDC, 0xC626, 0x9C4C, 0xDE26, 0xC2EE, 0x8DDC, 0xC266, 0x8CCC,
+ 0xC222, 0xBDDC, 0x8C44, 0xBCCC, 0xCE22, 0xBC44, 0x85CC, 0x84C4, 0x9DCC, 0xC662,
+ 0x9CC4, 0xDE62, 0xC2E2, 0x8DC4, 0xCEE2, 0xBDC4, 0x862E, 0x9E2E, 0x826E, 0x8226,
+ 0x8E6E, 0x8E26, 0xBE6E, 0x86EE, 0x8666, 0x9EEE, 0x8622, 0x9E66, 0x9E22, 0x82E6,
+ 0x8262, 0x8EE6, 0x8E62, 0xBEE6, 0xBE62, 0x86E2, 0x9EE2, 0xD0B8, 0xF42E, 0xA370,
+ 0xE8DC, 0xA130, 0xE84C, 0xD3B8, 0xF4EE, 0xD198, 0xF466, 0xD088, 0xF422, 0xAF70,
+ 0xEBDC, 0xA730, 0xE9CC, 0xA310, 0xE8C4, 0xD798, 0xF5E6, 0xD388, 0xF4E2, 0xAF10,
+ 0xEBC4, 0xC85C, 0xB0B8, 0xEC2E, 0x91B8, 0xE46E, 0x9098, 0xE426, 0xD84C, 0xC9DC,
+ 0xB3B8, 0xC8CC, 0xB198, 0xC844, 0xB088, 0xEC22, 0x97B8, 0xE5EE, 0x9398, 0xE4E6,
+ 0x9188, 0xE462, 0xD8C4, 0xCBCC, 0xB798, 0xC9C4, 0xB388, 0xECE2, 0x9788, 0xE5E2,
+ 0xDBC4, 0xC42E, 0x985C, 0xDC2E, 0x88DC, 0x884C, 0xB8DC, 0xCC26, 0xB84C, 0xC4EE,
+ 0x99DC, 0xC466, 0x98CC, 0xC422, 0x9844, 0xDC22, 0x8BDC, 0x89CC, 0xBBDC, 0x88C4,
+ 0xB9CC, 0xCC62, 0xB8C4, 0xC5E6, 0x9BCC, 0xC4E2, 0x99C4, 0xDCE2, 0x8BC4, 0xCDE2,
+ 0xBBC4, 0x8C2E, 0x846E, 0x8426, 0x9C6E, 0x9C26, 0x8CEE, 0x8C66, 0xBCEE, 0x8C22,
+ 0xBC66, 0x85EE, 0x84E6, 0x9DEE, 0x8462, 0x9CE6, 0x9C62, 0x8DE6, 0x8CE2, 0xBDE6,
+ 0xBCE2, 0x85E2, 0x9DE2, 0xD05C, 0xA1B8, 0xE86E, 0xA098, 0xE826, 0xD1DC, 0xD0CC,
+ 0xD044, 0xA7B8, 0xE9EE, 0xA398, 0xE8E6, 0xA188, 0xE862, 0xD7DC, 0xD3CC, 0xD1C4,
+ 0xAF98, 0xEBE6, 0xA788, 0xE9E2, 0xC82E, 0xB05C, 0x90DC, 0x904C, 0xD826, 0xC8EE,
+ 0xB1DC, 0xC866, 0xB0CC, 0xC822, 0xB044, 0x93DC, 0x91CC, 0x90C4, 0xD862, 0xCBEE,
+ 0xB7DC, 0xC9E6, 0xB3CC, 0xC8E2, 0xB1C4, 0x97CC, 0x93C4, 0xD9E2, 0x982E, 0x886E,
+ 0x8826, 0xB86E, 0x98EE, 0x9866, 0x9822, 0x89EE, 0x88E6, 0xB9EE, 0x8862, 0xB8E6,
+ 0xB862, 0x9BEE, 0x99E6, 0x98E2, 0x8BE6, 0x89E2, 0xBBE6, 0xB9E2, 0xD02E, 0xA0DC,
+ 0xA04C, 0xD0EE, 0xD066, 0xD022, 0xA3DC, 0xA1CC, 0xA0C4, 0xD3EE, 0xD1E6, 0xD0E2,
+ 0xAFDC, 0xA7CC, 0xA3C4, 0x906E, 0x9026, 0xB0EE, 0xB066, 0x91EE, 0x90E6, 0x9062,
+ 0xB3EE, 0xB1E6, 0xB0E2, 0x97EE, 0x93E6, 0x91E2, 0xD4E0, 0xF538, 0xFD4E, 0xA8C0,
+ 0xEA30, 0xFA8C, 0xD420, 0xF508, 0xFD42, 0xDAF0, 0xF6BC, 0xCA70, 0xF29C, 0xB4E0,
+ 0xED38, 0xFB4E, 0x9460, 0xE518, 0xF946, 0xDA30, 0xF68C, 0xCA10, 0xF284, 0xB420,
+ 0xED08, 0xFB42, 0xCD78, 0xF35E, 0xBAF0, 0xEEBC, 0xC538, 0xF14E, 0x9A70, 0xE69C,
+ 0xDD38, 0xF74E, 0x8A30, 0xE28C, 0xCD18, 0xF346, 0xBA30, 0xEE8C, 0xC508, 0xF142,
+ 0x9A10, 0xE684, 0xDD08, 0xF742, 0xC6BC, 0x9D78, 0xE75E, 0xDEBC, 0xC29C, 0x8D38,
+ 0xE34E, 0xCE9C, 0xBD38, 0xEF4E, 0x8518, 0xE146, 0xC68C, 0x9D18, 0xE746, 0xDE8C,
+ 0xC284, 0x8D08, 0xE342, 0xCE84, 0xBD08, 0xEF42, 0xC35E, 0x8EBC, 0xCF5E, 0xBEBC,
+ 0xC14E, 0x869C, 0xC74E, 0x9E9C, 0xDF4E, 0x828C, 0xC346, 0x8E8C, 0xCF46, 0xBE8C,
+ 0xC142, 0x8684, 0xC742, 0x9E84, 0xDF42, 0x875E, 0x9F5E, 0x834E, 0x8F4E, 0xBF4E,
+ 0x8146, 0x8746, 0x9F46, 0x8342, 0x8F42, 0xBF42, 0xE978, 0xFA5E, 0xD6F0, 0xF5BC,
+ 0xD270, 0xF49C, 0xACE0, 0xEB38, 0xFACE, 0xA460, 0xE918, 0xFA46, 0xD630, 0xF58C,
+ 0xD210, 0xF484, 0xAC20, 0xEB08, 0xFAC2, 0x92F0, 0xE4BC, 0xD978, 0xF65E, 0xCB78,
+ 0xF2DE, 0xB6F0, 0xC938, 0xF24E, 0xB270, 0xEC9C, 0x9670, 0xE59C, 0x9230, 0xE48C,
+ 0xD918, 0xF646, 0xCB18, 0xF2C6, 0xB630, 0xC908, 0xF242, 0xB210, 0xEC84, 0x9610,
+ 0xE584, 0xDB08, 0xF6C2, 0x8978, 0xE25E, 0xCCBC, 0xB978, 0xEE5E, 0xC5BC, 0x9B78,
+ 0xC49C, 0x9938, 0xE64E, 0xDC9C, 0x8B38, 0xE2CE, 0x8918, 0xE246, 0xBB38, 0xCC8C,
+ 0xB918, 0xEE46, 0xC58C, 0x9B18, 0xC484, 0x9908, 0xE642, 0xDC84, 0x8B08, 0xE2C2,
+ 0xCD84, 0xBB08, 0xEEC2, 0x84BC, 0xC65E, 0x9CBC, 0xDE5E, 0xC2DE, 0x8DBC, 0xC24E,
+ 0x8C9C, 0xBDBC, 0xCE4E, 0xBC9C, 0x859C, 0x848C, 0x9D9C, 0xC646, 0x9C8C, 0xDE46,
+ 0xC2C6, 0x8D8C, 0xC242, 0x8C84, 0xBD8C, 0xCE42, 0xBC84, 0x8584, 0xC6C2, 0x9D84,
+ 0xDEC2, 0x825E, 0x8E5E, 0xBE5E, 0x86DE, 0x864E, 0x9EDE, 0x9E4E, 0x82CE, 0x8246,
+ 0x8ECE, 0x8E46, 0xBECE, 0xBE46, 0x86C6, 0x8642, 0x9EC6, 0x9E42, 0x82C2, 0x8EC2,
+ 0xBEC2, 0xA2F0, 0xE8BC, 0xD378, 0xF4DE, 0xD138, 0xF44E, 0xAEF0, 0xEBBC, 0xA670,
+ 0xE99C, 0xA230, 0xE88C, 0xD738, 0xF5CE, 0xD318, 0xF4C6, 0xD108, 0xF442, 0xAE30,
+ 0xEB8C, 0xA610, 0xE984, 0xD708, 0xF5C2, 0x9178, 0xE45E, 0xD8BC, 0xC9BC, 0xB378,
+ 0xC89C, 0xB138, 0xEC4E, 0x9778, 0xE5DE, 0x9338, 0xE4CE, 0x9118, 0xE446, 0xD88C,
+ 0xCB9C, 0xB738, 0xC98C, 0xB318, 0xC884, 0xB108, 0xEC42, 0x9718, 0xE5C6, 0x9308,
+ 0xE4C2, 0xD984, 0xCB84, 0xB708, 0xEDC2, 0x88BC, 0xCC5E, 0xB8BC, 0xC4DE, 0x99BC,
+ 0xC44E, 0x989C, 0xDC4E, 0x8BBC, 0x899C, 0xBBBC, 0x888C, 0xB99C, 0xCC46, 0xB88C,
+ 0xC5CE, 0x9B9C, 0xC4C6, 0x998C, 0xC442, 0x9884, 0xDC42, 0x8B8C, 0x8984, 0xBB8C,
+ 0xCCC2, 0xB984, 0xC5C2, 0x9B84, 0xDDC2, 0x845E, 0x9C5E, 0x8CDE, 0x8C4E, 0xBCDE,
+ 0xBC4E, 0x85DE, 0x84CE, 0x9DDE, 0x8446, 0x9CCE, 0x9C46, 0x8DCE, 0x8CC6, 0xBDCE,
+ 0x8C42, 0xBCC6, 0xBC42, 0x85C6, 0x84C2, 0x9DC6, 0x9CC2, 0x8DC2, 0xBDC2, 0xA178,
+ 0xE85E, 0xD1BC, 0xD09C, 0xA778, 0xE9DE, 0xA338, 0xE8CE, 0xA118, 0xE846, 0xD7BC,
+ 0xD39C, 0xD18C, 0xD084, 0xAF38, 0xEBCE, 0xA718, 0xE9C6, 0xA308, 0xE8C2, 0xD78C,
+ 0xD384, 0x90BC, 0xD85E, 0xC8DE, 0xB1BC, 0xC84E, 0xB09C, 0x93BC, 0x919C, 0x908C,
+ 0xD846, 0xCBDE, 0xB7BC, 0xC9CE, 0xB39C, 0xC8C6, 0xB18C, 0xC842, 0xB084, 0x979C,
+ 0x938C, 0x9184, 0xD8C2, 0xCBC6, 0xB78C, 0xC9C2, 0xB384, 0x885E, 0xB85E, 0x98DE,
+ 0x984E, 0x89DE, 0x88CE, 0xB9DE, 0x8846, 0xB8CE, 0xB846, 0x9BDE, 0x99CE, 0x98C6,
+ 0x9842, 0x8BCE, 0x89C6, 0xBBCE, 0x88C2, 0xB9C6, 0xB8C2, 0x9BC6, 0x99C2, 0xA0BC,
+ 0xD0DE, 0xD04E, 0xA3BC, 0xA19C, 0xA08C, 0xD3DE, 0xD1CE, 0xD0C6, 0xD042, 0xAFBC,
+ 0xA79C, 0xA38C, 0xA184, 0xD7CE, 0xD3C6, 0xD1C2, 0x905E, 0xB0DE, 0xB04E, 0x91DE,
+ 0x90CE, 0x9046, 0xB3DE, 0xB1CE, 0xB0C6, 0xB042, 0x97DE, 0x93CE, 0x91C6, 0x90C2,
+ 0xB7CE, 0xB3C6, 0xB1C2, 0xA05E, 0xA1DE, 0xA0CE, 0xA046, 0xA7DE, 0xA3CE, 0xA1C6,
+ 0xA0C2, 0xA9E0, 0xEA78, 0xFA9E, 0xD470, 0xF51C, 0xA860, 0xEA18, 0xFA86, 0xD410,
+ 0xF504, 0xED7C, 0x94F0, 0xE53C, 0xDA78, 0xF69E, 0xCA38, 0xF28E, 0xB470, 0xED1C,
+ 0x9430, 0xE50C, 0xDA18, 0xF686, 0xCA08, 0xF282, 0xB410, 0xED04, 0x9AF8, 0xE6BE,
+ 0xDD7C, 0x8A78, 0xE29E, 0xCD3C, 0xBA78, 0xEE9E, 0xC51C, 0x9A38, 0xE68E, 0xDD1C,
+ 0x8A18, 0xE286, 0xCD0C, 0xBA18, 0xEE86, 0xC504, 0x9A08, 0xE682, 0xDD04, 0x8D7C,
+ 0xCEBE, 0xBD7C, 0x853C, 0xC69E, 0x9D3C, 0xDE9E, 0xC28E, 0x8D1C, 0xCE8E, 0xBD1C,
+ 0x850C, 0xC686, 0x9D0C, 0xDE86, 0xC282, 0x8D04, 0xCE82, 0xBD04, 0x86BE, 0x9EBE,
+ 0x829E, 0x8E9E, 0xBE9E, 0x868E, 0x9E8E, 0x8286, 0x8E86, 0xBE86, 0x8682, 0x9E82,
+ 0xD2F8, 0xF4BE, 0xADF0, 0xEB7C, 0xA4F0, 0xE93C, 0xD678, 0xF59E, 0xD238, 0xF48E,
+ 0xAC70, 0xEB1C, 0xA430, 0xE90C, 0xD618, 0xF586, 0xD208, 0xF482, 0xAC10, 0xEB04,
+ 0xC97C, 0xB2F8, 0xECBE, 0x96F8, 0xE5BE, 0x9278, 0xE49E, 0xD93C, 0xCB3C, 0xB678,
+ 0xC91C, 0xB238, 0xEC8E, 0x9638, 0xE58E, 0x9218, 0xE486, 0xD90C, 0xCB0C, 0xB618,
+ 0xC904, 0xB208, 0xEC82, 0x9608, 0xE582, 0xDB04, 0xC4BE, 0x997C, 0xDCBE, 0x8B7C,
+ 0x893C, 0xBB7C, 0xCC9E, 0xB93C, 0xC59E, 0x9B3C, 0xC48E, 0x991C, 0xDC8E, 0x8B1C,
+ 0x890C, 0xBB1C, 0xCC86, 0xB90C, 0xC586, 0x9B0C, 0xC482, 0x9904, 0xDC82, 0x8B04,
+ 0xCD82, 0xBB04, 0x8CBE, 0xBCBE, 0x85BE, 0x849E, 0x9DBE, 0x9C9E, 0x8D9E, 0x8C8E,
+ 0xBD9E, 0xBC8E, 0x858E, 0x8486, 0x9D8E, 0x9C86, 0x8D86, 0x8C82, 0xBD86, 0xBC82,
+ 0x8582, 0x9D82, 0xD17C, 0xA6F8, 0xE9BE, 0xA278, 0xE89E, 0xD77C, 0xD33C, 0xD11C,
+ 0xAE78, 0xEB9E, 0xA638, 0xE98E, 0xA218, 0xE886, 0xD71C, 0xD30C, 0xD104, 0xAE18,
+ 0xEB86, 0xA608, 0xE982, 0xC8BE, 0xB17C, 0x937C, 0x913C, 0xD89E, 0xCBBE, 0xB77C,
+ 0xC99E, 0xB33C, 0xC88E, 0xB11C, 0x973C, 0x931C, 0x910C, 0xD886, 0xCB8E, 0xB71C,
+ 0xC986, 0xB30C, 0xC882, 0xB104, 0x970C, 0x9304, 0xD982, 0x98BE, 0x89BE, 0x889E,
+ 0xB9BE, 0xB89E, 0x9BBE, 0x999E, 0x988E, 0x8B9E, 0x898E, 0xBB9E, 0x8886, 0xB98E,
+ 0xB886, 0x9B8E, 0x9986, 0x9882, 0x8B86, 0x8982, 0xBB86, 0xB982, 0xD0BE, 0xA37C,
+ 0xA13C, 0xD3BE, 0xD19E, 0xD08E, 0xAF7C, 0xA73C, 0xA31C, 0xA10C, 0xD79E, 0xD38E,
+ 0xD186, 0xD082, 0xAF1C, 0xA70C, 0xA304, 0xB0BE, 0x91BE, 0x909E, 0xB3BE, 0xB19E,
+ 0xB08E, 0x97BE, 0x939E, 0x918E, 0x9086, 0xB79E, 0xB38E, 0xB186, 0xB082, 0x978E,
+ 0x9386, 0x9182, 0xA1BE, 0xA09E, 0xA7BE, 0xA39E, 0xA18E, 0xA086, 0xAF9E, 0xA78E,
+ 0xA386, 0xA182, 0xD4F8, 0xF53E, 0xA8F0, 0xEA3C, 0xD438, 0xF50E, 0xA830, 0xEA0C,
+ 0xD408, 0xF502, 0xDAFC, 0xCA7C, 0xB4F8, 0xED3E, 0x9478, 0xE51E, 0xDA3C, 0xCA1C,
+ 0xB438, 0xED0E, 0x9418, 0xE506, 0xDA0C, 0xCA04, 0xB408, 0xED02, 0xCD7E, 0xBAFC,
+ 0xC53E, 0x9A7C, 0xDD3E, 0x8A3C, 0xCD1E, 0xBA3C, 0xC50E, 0x9A1C, 0xDD0E, 0x8A0C,
+ 0xCD06, 0xBA0C, 0xC502, 0x9A04, 0xDD02, 0x9D7E, 0x8D3E, 0xBD3E, 0x851E, 0x9D1E,
+ 0x8D0E, 0xBD0E, 0x8506, 0x9D06, 0x8D02, 0xBD02, 0xE97E, 0xD6FC, 0xD27C, 0xACF8,
+ 0xEB3E, 0xA478, 0xE91E, 0xD63C, 0xD21C, 0xAC38, 0xEB0E, 0xA418, 0xE906, 0xD60C,
+ 0xD204, 0x92FC, 0xD97E, 0xCB7E, 0xB6FC, 0xC93E, 0xB27C, 0x967C, 0x923C, 0xD91E,
+ 0xCB1E, 0xB63C, 0xC90E, 0xB21C, 0x961C, 0x920C, 0xD906, 0xCB06, 0xB60C, 0xC902,
+ 0xB204, 0x897E, 0xB97E, 0x9B7E, 0x993E, 0x8B3E, 0x891E, 0xBB3E, 0xB91E, 0x9B1E,
+ 0x990E, 0x8B0E, 0x8906, 0xBB0E, 0xB906, 0x9B06, 0x9902, 0xA2FC, 0xD37E, 0xD13E,
+ 0xAEFC
+};
diff --git a/backend/common.c b/backend/common.c
index 72cc3ca..f295099 100644
--- a/backend/common.c
+++ b/backend/common.c
@@ -2,7 +2,7 @@
/*
libzint - the open source barcode library
- Copyright (C) 2008 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -28,359 +28,473 @@
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-*/
-#include <string.h>
+ */
+/* vim: set ts=4 sw=4 et : */
#include <stdio.h>
-#include <stdlib.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
#include "common.h"
-int ustrlen(const unsigned char data[]) {
- /* Local replacement for strlen() with unsigned char strings */
- int i;
- for (i=0;data[i];i++);
-
- return i;
+/* Converts a character 0-9 to its equivalent integer value */
+INTERNAL int ctoi(const char source) {
+ if ((source >= '0') && (source <= '9'))
+ return (source - '0');
+ if ((source >= 'A') && (source <= 'F'))
+ return (source - 'A' + 10);
+ if ((source >= 'a') && (source <= 'f'))
+ return (source - 'a' + 10);
+ return -1;
}
-void ustrcpy(unsigned char target[],const unsigned char source[]) {
- /* Local replacement for strcpy() with unsigned char strings */
- int i, len;
+/* Convert an integer value to a string representing its binary equivalent */
+INTERNAL void bin_append(const int arg, const int length, char *binary) {
+ size_t posn = strlen(binary);
- len = ustrlen(source);
- for(i = 0; i < len; i++) {
- target[i] = source[i];
- }
- target[i] = '\0';
+ bin_append_posn(arg, length, binary, posn);
+
+ binary[posn + length] = '\0';
}
-void concat(char dest[],const char source[])
-{ /* Concatinates dest[] with the contents of source[], copying /0 as well */
- unsigned int i, j, n;
+/* Convert an integer value to a string representing its binary equivalent at a set position */
+INTERNAL void bin_append_posn(const int arg, const int length, char *binary, size_t posn) {
+ int i;
+ int start;
- j = strlen(dest);
- n = strlen(source);
- for(i = 0; i <= n; i++) {
- dest[i + j] = source[i]; }
-}
+ start = 0x01 << (length - 1);
-void uconcat(unsigned char dest[], const unsigned char source[])
-{ /* Concatinates dest[] with the contents of source[], copying /0 as well */
- unsigned int i, j;
+ for (i = 0; i < length; i++) {
+ binary[posn + i] = '0';
+ if (arg & (start >> i)) {
+ binary[posn + i] = '1';
+ }
+ }
+}
- j = ustrlen(dest);
- for(i = 0; i <= ustrlen(source); i++) {
- dest[i + j] = source[i]; }
+/* Converts an integer value to its hexadecimal character */
+INTERNAL char itoc(const int source) {
+ if ((source >= 0) && (source <= 9)) {
+ return ('0' + source);
+ } else {
+ return ('A' + (source - 10));
+ }
}
+/* Converts lower case characters to upper case in a string source[] */
+INTERNAL void to_upper(unsigned char source[]) {
+ size_t i, src_len = ustrlen(source);
-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);
+ for (i = 0; i < src_len; i++) {
+ if ((source[i] >= 'a') && (source[i] <= 'z')) {
+ source [i] = (source[i] - 'a') + 'A';
+ }
+ }
}
-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)); }
+/* Verifies that a string only uses valid characters */
+INTERNAL int is_sane(const char test_string[], const unsigned char source[], const size_t length) {
+ unsigned int j;
+ size_t i, lt = strlen(test_string);
+
+ for (i = 0; i < length; i++) {
+ unsigned int latch = FALSE;
+ for (j = 0; j < lt; j++) {
+ if (source[i] == test_string[j]) {
+ latch = TRUE;
+ break;
+ }
+ }
+ if (!(latch)) {
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ }
+
+ return 0;
}
-void to_upper(unsigned char source[])
-{ /* Converts lower case characters to upper case in a string source[] */
- unsigned int i, src_len = ustrlen(source);
+/* Replaces huge switch statements for looking up in tables */
+INTERNAL void lookup(const char set_string[], const char *table[], const char data, char dest[]) {
+ size_t i, n = strlen(set_string);
- for (i = 0; i < src_len; i++) {
- if ((source[i] >= 'a') && (source[i] <= 'z')) {
- source [i] = (source[i] - 'a') + 'A'; }
- }
+ for (i = 0; i < n; i++) {
+ if (data == set_string[i]) {
+ strcat(dest, table[i]);
+ }
+ }
}
-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;
+/* Returns the position of data in set_string */
+INTERNAL int posn(const char set_string[], const char data) {
+ int i, n = (int)strlen(set_string);
+
+ for (i = 0; i < n; i++) {
+ if (data == set_string[i]) {
+ return i;
+ }
+ }
+ return -1;
}
-int posn(char set_string[], char data)
-{ /* Returns the position of data in set_string */
- unsigned int i, n = strlen(set_string);
+/* Returns the number of times a character occurs in a string */
+INTERNAL int ustrchr_cnt(const unsigned char string[], const size_t length, const unsigned char c) {
+ int count = 0;
+ unsigned int i;
+ for (i = 0; i < length; i++) {
+ if (string[i] == c) {
+ count++;
+ }
+ }
+ return count;
+}
- for(i = 0; i < n; i++) {
- if (data == set_string[i]) { return i; } }
- return 0;
+/* Return true (1) if a module is dark/black/colour, otherwise false (0) */
+INTERNAL int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord) {
+ if (symbol->symbology == BARCODE_ULTRA) {
+ return symbol->encoded_data[y_coord][x_coord];
+ } else {
+ return (symbol->encoded_data[y_coord][x_coord / 8] >> (x_coord % 8)) & 1;
+ }
}
-void lookup(char set_string[],const char *table[], char data, char dest[])
-{ /* Replaces huge switch statements for looking up in tables */
- unsigned int i, n = strlen(set_string);
+/* Set a module to dark/black */
+INTERNAL void set_module(struct zint_symbol *symbol, const int y_coord, const int x_coord) {
+ symbol->encoded_data[y_coord][x_coord / 8] |= 1 << (x_coord % 8);
+}
- for(i = 0; i < n; i++) {
- if (data == set_string[i]) { concat(dest, table[i]); } }
+/* Set a module to a colour */
+INTERNAL void set_module_colour(struct zint_symbol *symbol, const int y_coord, const int x_coord, const int colour) {
+ symbol->encoded_data[y_coord][x_coord] = colour;
}
-int module_is_set(struct zint_symbol *symbol, int y_coord, int x_coord)
-{
- return (symbol->encoded_data[y_coord][x_coord / 7] >> (x_coord % 7)) & 1;
-#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
+/* Set (or unset) a module to white */
+INTERNAL void unset_module(struct zint_symbol *symbol, const int y_coord, const int x_coord) {
+ symbol->encoded_data[y_coord][x_coord / 8] &= ~(1 << (x_coord % 8));
}
-void set_module(struct zint_symbol *symbol, int y_coord, int x_coord)
-{
- 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
+/* Expands from a width pattern to a bit pattern */
+INTERNAL void expand(struct zint_symbol *symbol, const char data[]) {
+
+ size_t 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++;
+ }
+
+ latch = (latch == '1' ? '0' : '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;
}
-void unset_module(struct zint_symbol *symbol, int y_coord, int x_coord)
-{
- 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
+/* Indicates which symbologies can have row binding
+ * Note: if change this must also change version in frontend/main.c */
+INTERNAL int is_stackable(const int symbology) {
+ if (symbology < BARCODE_PDF417) {
+ return 1;
+ }
+
+ switch (symbology) {
+ case BARCODE_CODE128B:
+ case BARCODE_ISBNX:
+ case BARCODE_EAN14:
+ case BARCODE_NVE18:
+ case BARCODE_KOREAPOST:
+ case BARCODE_PLESSEY:
+ case BARCODE_TELEPEN_NUM:
+ case BARCODE_ITF14:
+ case BARCODE_CODE32:
+ case BARCODE_CODABLOCKF:
+ case BARCODE_HIBC_BLOCKF:
+ return 1;
+ }
+
+ return 0;
}
-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++;
- }
-
- latch = (latch == '1' ? '0' : '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;
+/* Indicates which symbols can have addon (EAN-2 and EAN-5) */
+INTERNAL int is_extendable(const int symbology) {
+ if (symbology == BARCODE_EANX || symbology == BARCODE_EANX_CHK) {
+ return 1;
+ }
+ if (symbology == BARCODE_UPCA || symbology == BARCODE_UPCA_CHK) {
+ return 1;
+ }
+ if (symbology == BARCODE_UPCE || symbology == BARCODE_UPCE_CHK) {
+ 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 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;
+/* Indicates which symbols can have composite 2D component data */
+INTERNAL int is_composite(int symbology) {
+ return symbology >= BARCODE_EANX_CC && symbology <= BARCODE_RSS_EXPSTACK_CC;
}
-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;
+INTERNAL int istwodigits(const unsigned char source[], const int length, const int position) {
+ if ((position + 1 < length) && (source[position] >= '0') && (source[position] <= '9')
+ && (source[position + 1] >= '0') && (source[position + 1] <= '9')) {
+ 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;
+/* State machine to decode UTF-8 to Unicode codepoints (state 0 means done, state 12 means error) */
+INTERNAL unsigned int decode_utf8(unsigned int* state, unsigned int* codep, const unsigned char byte) {
+ /*
+ Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
+ modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+ See https://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
+ */
+
+ static const unsigned char utf8d[] = {
+ /* The first part of the table maps bytes to character classes that
+ * reduce the size of the transition table and create bitmasks. */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 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,2,2,2,2,
+ 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
+
+ /* The second part is a transition table that maps a combination
+ * of a state of the automaton and a character class to a state. */
+ 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
+ 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
+ 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
+ 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
+ 12,36,12,12,12,12,12,12,12,12,12,12,
+ };
+
+ unsigned int type = utf8d[byte];
+
+ *codep = *state != 0 ? (byte & 0x3fu) | (*codep << 6) : (0xff >> type) & byte;
+
+ *state = utf8d[256 + *state + type];
+
+ return *state;
}
-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;
+/* Convert UTF-8 to Unicode. If `disallow_4byte` unset, allow all values (UTF-32).
+ * If `disallow_4byte` set, only allow codepoints <= U+FFFF (ie four-byte sequences not allowed) (UTF-16, no surrogates) */
+INTERNAL int utf8_to_unicode(struct zint_symbol *symbol, const unsigned char source[], unsigned int vals[], size_t *length, int disallow_4byte) {
+ size_t bpos;
+ int jpos;
+ unsigned int codepoint, state = 0;
+
+ bpos = 0;
+ jpos = 0;
+
+ while (bpos < *length) {
+ do {
+ decode_utf8(&state, &codepoint, source[bpos++]);
+ } while (bpos < *length && state != 0 && state != 12);
+
+ if (state != 0) {
+ strcpy(symbol->errtxt, "240: Corrupt Unicode data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ if (disallow_4byte && codepoint > 0xffff) {
+ strcpy(symbol->errtxt, "242: Unicode sequences of more than 3 bytes not supported");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ vals[jpos] = codepoint;
+ jpos++;
+ }
+
+ *length = jpos;
+
+ 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;
+/* Enforce minimum permissable height of rows */
+INTERNAL void set_minimum_height(struct zint_symbol *symbol, const int min_height) {
+ int fixed_height = 0;
+ int zero_count = 0;
+ int i;
+
+ for (i = 0; i < symbol->rows; i++) {
+ fixed_height += symbol->row_height[i];
+
+ if (symbol->row_height[i] == 0) {
+ zero_count++;
+ }
+ }
+
+ if (zero_count > 0) {
+ if (((symbol->height - fixed_height) / zero_count) < min_height) {
+ for (i = 0; i < symbol->rows; i++) {
+ if (symbol->row_height[i] == 0) {
+ symbol->row_height[i] = min_height;
+ }
+ }
+ }
+ }
}
-int latin1_process(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;
- if (length && *length) {
- 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) {
- return ERROR_INVALID_DATA;
- }
- i = next;
- } while(i < *length);
- preprocessed[j] = '\0';
- *length = j;
- }
-
- return 0;
+/* Calculate optimized encoding modes. Adapted from Project Nayuki */
+INTERNAL void pn_define_mode(char* mode, const unsigned int data[], const size_t length, const int debug,
+ unsigned int state[], const char mode_types[], const int num_modes, pn_head_costs head_costs, pn_switch_cost switch_cost, pn_eod_cost eod_cost, pn_cur_cost cur_cost) {
+ /*
+ * Copyright (c) Project Nayuki. (MIT License)
+ * https://www.nayuki.io/page/qr-code-generator-library
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ * - The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ */
+ int i, j, k, cm_i;
+ unsigned int min_cost;
+ char cur_mode;
+#ifndef _MSC_VER
+ unsigned int prev_costs[num_modes];
+ char char_modes[length * num_modes];
+ unsigned int cur_costs[num_modes];
+#else
+ unsigned int* prev_costs;
+ char* char_modes;
+ unsigned int* cur_costs;
+ prev_costs = (unsigned int*) _alloca(num_modes * sizeof(unsigned int));
+ char_modes = (char*) _alloca(length * num_modes);
+ cur_costs = (unsigned int*) _alloca(num_modes * sizeof(unsigned int));
+#endif
+
+ /* char_modes[i * num_modes + j] represents the mode to encode the code point at index i such that the final
+ * segment ends in mode_types[j] and the total number of bits is minimized over all possible choices */
+ memset(char_modes, 0, length * num_modes);
+
+ /* At the beginning of each iteration of the loop below, prev_costs[j] is the minimum number of 1/6 (1/XX_MULT)
+ * bits needed to encode the entire string prefix of length i, and end in mode_types[j] */
+ memcpy(prev_costs, (*head_costs)(state), num_modes * sizeof(unsigned int));
+
+ /* Calculate costs using dynamic programming */
+ for (i = 0, cm_i = 0; i < (int) length; i++, cm_i += num_modes) {
+ memset(cur_costs, 0, num_modes * sizeof(unsigned int));
+
+ (*cur_cost)(state, data, length, i, char_modes, prev_costs, cur_costs);
+
+ if (eod_cost && i == (int) length - 1) { /* Add end of data costs if last character */
+ for (j = 0; j < num_modes; j++) {
+ if (char_modes[cm_i + j]) {
+ cur_costs[j] += (*eod_cost)(state, j);
+ }
+ }
+ }
+
+ /* Start new segment at the end to switch modes */
+ for (j = 0; j < num_modes; j++) { /* To mode */
+ for (k = 0; k < num_modes; k++) { /* From mode */
+ if (j != k && char_modes[cm_i + k]) {
+ unsigned int new_cost = cur_costs[k] + (*switch_cost)(state, k, j);
+ if (!char_modes[cm_i + j] || new_cost < cur_costs[j]) {
+ cur_costs[j] = new_cost;
+ char_modes[cm_i + j] = mode_types[k];
+ }
+ }
+ }
+ }
+
+ memcpy(prev_costs, cur_costs, num_modes * sizeof(unsigned int));
+ }
+
+ /* Find optimal ending mode */
+ min_cost = prev_costs[0];
+ cur_mode = mode_types[0];
+ for (i = 1; i < num_modes; i++) {
+ if (prev_costs[i] < min_cost) {
+ min_cost = prev_costs[i];
+ cur_mode = mode_types[i];
+ }
+ }
+
+ /* Get optimal mode for each code point by tracing backwards */
+ for (i = length - 1, cm_i = i * num_modes; i >= 0; i--, cm_i -= num_modes) {
+ j = strchr(mode_types, cur_mode) - mode_types;
+ cur_mode = char_modes[cm_i + j];
+ mode[i] = cur_mode;
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf(" Mode: %.*s\n", (int)length, mode);
+ }
}
-int utf8toutf16(struct zint_symbol *symbol, unsigned char source[], int vals[], int *length)
-{
- int bpos, jpos, error_number;
- int next;
-
- bpos = 0;
- jpos = 0;
- error_number = 0;
- next = 0;
-
- do {
- if(source[bpos] <= 0x7f) {
- /* 1 byte mode (7-bit ASCII) */
- vals[jpos] = source[bpos];
- next = bpos + 1;
- jpos++;
- } else {
- if((source[bpos] >= 0x80) && (source[bpos] <= 0xbf)) {
- strcpy(symbol->errtxt, "Corrupt Unicode data");
- return ERROR_INVALID_DATA;
- }
- if((source[bpos] >= 0xc0) && (source[bpos] <= 0xc1)) {
- strcpy(symbol->errtxt, "Overlong encoding not supported");
- return ERROR_INVALID_DATA;
- }
-
- if((source[bpos] >= 0xc2) && (source[bpos] <= 0xdf)) {
- /* 2 byte mode */
- vals[jpos] = ((source[bpos] & 0x1f) << 6) + (source[bpos + 1] & 0x3f);
- next = bpos + 2;
- jpos++;
- } else
- 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 ++;
- } else
- 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;
+#ifdef ZINT_TEST
+/* Dumps hex-formatted codewords in symbol->errtxt (for use in testing) */
+void debug_test_codeword_dump(struct zint_symbol *symbol, unsigned char* codewords, int length) {
+ int i, max = length, cnt_len = 0;
+ if (length > 30) { /* 30*3 < errtxt 92 (100 - "Warning ") chars */
+ sprintf(symbol->errtxt, "(%d) ", length); /* Place the number of codewords at the front */
+ cnt_len = strlen(symbol->errtxt);
+ max = 30 - (cnt_len + 2) / 3;
+ }
+ for (i = 0; i < max; i++) {
+ sprintf(symbol->errtxt + cnt_len + i * 3, "%02X ", codewords[i]);
+ }
+ symbol->errtxt[strlen(symbol->errtxt) - 1] = '\0'; /* Zap last space */
}
+void debug_test_codeword_dump_int(struct zint_symbol *symbol, int* codewords, int length) {
+ int i, max = 0, cnt_len, errtxt_len;
+ char temp[20];
+ errtxt_len = sprintf(symbol->errtxt, "(%d) ", length); /* Place the number of codewords at the front */
+ for (i = 0, cnt_len = errtxt_len; i < length; i++) {
+ cnt_len += sprintf(temp, "%d ", codewords[i]);
+ if (cnt_len > 92) {
+ break;
+ }
+ max++;
+ }
+ for (i = 0; i < max; i++) {
+ errtxt_len += sprintf(symbol->errtxt + errtxt_len, "%d ", codewords[i]);
+ }
+ symbol->errtxt[strlen(symbol->errtxt) - 1] = '\0'; /* Zap last space */
+}
+#endif
diff --git a/backend/common.h b/backend/common.h
index d7fead9..649eaeb 100644
--- a/backend/common.h
+++ b/backend/common.h
@@ -2,7 +2,7 @@
/*
libzint - the open source barcode library
- Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -28,52 +28,83 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
/* Used in some logic */
#ifndef __COMMON_H
#define __COMMON_H
#ifndef FALSE
-#define FALSE 0
+#define FALSE 0
#endif
#ifndef TRUE
-#define TRUE 1
+#define TRUE 1
#endif
/* The most commonly used set */
-#define NEON "0123456789"
+#define NEON "0123456789"
#include "zint.h"
+#include <stdlib.h>
+#include <string.h>
+
+/* Helpers to cast away char pointer signedness */
+#define ustrlen(source) strlen((const char *) (source))
+#define ustrcpy(target, source) strcpy((char *) (target), (const char *) (source))
+#define ustrcat(target, source) strcat((char *) (target), (const char *) (source))
+
+#if defined(__GNUC__) && !defined(_WIN32) && !defined(ZINT_TEST)
+#define INTERNAL __attribute__ ((visibility ("hidden")))
+#else
+#define INTERNAL
+#endif
+
+#if defined(ZINT_TEST)
+#define STATIC_UNLESS_ZINT_TEST
+#else
+#define STATIC_UNLESS_ZINT_TEST static
+#endif
#ifdef __cplusplus
-extern "C"
-{
+extern "C" {
#endif /* __cplusplus */
-extern int ustrlen(const unsigned char source[]);
-extern void ustrcpy(unsigned char target[], const unsigned char source[]);
-extern void concat(char dest[], const char source[]);
-extern void uconcat(unsigned char dest[], const 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[],const 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(unsigned char source[], unsigned char preprocessed[], int *length);
-extern int utf8toutf16(struct zint_symbol *symbol, unsigned char source[], int vals[], int *length);
+ INTERNAL int ctoi(const char source);
+ INTERNAL char itoc(const int source);
+ INTERNAL void to_upper(unsigned char source[]);
+ INTERNAL int is_sane(const char test_string[], const unsigned char source[], const size_t length);
+ INTERNAL void lookup(const char set_string[], const char *table[], const char data, char dest[]);
+ INTERNAL void bin_append(const int arg, const int length, char *binary);
+ INTERNAL void bin_append_posn(const int arg, const int length, char *binary, size_t posn);
+ INTERNAL int posn(const char set_string[], const char data);
+ INTERNAL int ustrchr_cnt(const unsigned char string[], const size_t length, const unsigned char c);
+ INTERNAL int module_is_set(const struct zint_symbol *symbol, const int y_coord, const int x_coord);
+ INTERNAL void set_module(struct zint_symbol *symbol, const int y_coord, const int x_coord);
+ INTERNAL void set_module_colour(struct zint_symbol *symbol, const int y_coord, const int x_coord, const int colour);
+ INTERNAL void unset_module(struct zint_symbol *symbol, const int y_coord, const int x_coord);
+ INTERNAL void expand(struct zint_symbol *symbol, const char data[]);
+ INTERNAL int is_stackable(const int symbology);
+ INTERNAL int is_extendable(const int symbology);
+ INTERNAL int is_composite(const int symbology);
+ INTERNAL int istwodigits(const unsigned char source[], int length, const int position);
+ INTERNAL unsigned int decode_utf8(unsigned int* state, unsigned int* codep, const unsigned char byte);
+ INTERNAL int utf8_to_unicode(struct zint_symbol *symbol, const unsigned char source[], unsigned int vals[], size_t *length, int disallow_4byte);
+ INTERNAL void set_minimum_height(struct zint_symbol *symbol, const int min_height);
+
+ typedef unsigned int* (*pn_head_costs)(unsigned int state[]);
+ typedef unsigned int (*pn_switch_cost)(unsigned int state[], const int k, const int j);
+ typedef unsigned int (*pn_eod_cost)(unsigned int state[], const int k);
+ typedef void (*pn_cur_cost)(unsigned int state[], const unsigned int data[], const size_t length, const int i, char* char_modes, unsigned int prev_costs[], unsigned int cur_costs[]);
+ INTERNAL void pn_define_mode(char* mode, const unsigned int data[], const size_t length, const int debug,
+ unsigned int state[], const char mode_types[], const int num_modes, pn_head_costs head_costs, pn_switch_cost switch_cost, pn_eod_cost eod_cost, pn_cur_cost cur_cost);
+
+ #ifdef ZINT_TEST
+ void debug_test_codeword_dump(struct zint_symbol *symbol, unsigned char* codewords, int length);
+ void debug_test_codeword_dump_int(struct zint_symbol *symbol, int* codewords, int length);
+ #endif
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/backend/composite.c b/backend/composite.c
new file mode 100644
index 0000000..1184965
--- /dev/null
+++ b/backend/composite.c
@@ -0,0 +1,1668 @@
+/* composite.c - Handles GS1 Composite Symbols */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/* 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <math.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+#include "common.h"
+#include "composite.h"
+#include "pdf417.h"
+#include "gs1.h"
+#include "general_field.h"
+
+#define UINT unsigned short
+
+INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int length);
+INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length);
+INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[]);
+INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int length);
+INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length);
+INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length);
+
+static UINT pwr928[69][7];
+
+static int _min(int first, int second) {
+
+ if (first <= second)
+ return first;
+ else
+ return second;
+}
+
+/* gets bit in bitString at bitPos */
+static int getBit(UINT *bitStr, int bitPos) {
+ return !!(bitStr[bitPos >> 4] & (0x8000 >> (bitPos & 15)));
+}
+
+/* initialize pwr928 encoding table */
+static 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 */
+static int encode928(UINT bitString[], UINT codeWords[], int bitLng) {
+ int i, j, b, cwNdx, cwLng;
+ for (cwNdx = cwLng = b = 0; b < bitLng; b += 69, cwNdx += 7) {
+ int bitCnt = _min(bitLng - b, 69);
+ int cwCnt;
+ 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);
+}
+
+/* CC-A 2D component */
+static int cc_a(struct zint_symbol *symbol, char source[], int cc_width) {
+ int i, 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 loop;
+ UINT codeWords[28];
+ UINT bitStr[13];
+ char 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 = (int)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++) {
+ int strpos = segment * 16;
+ for (i = 0; i < 16; i++) {
+ if (local_source[strpos + i] == '1') {
+ bitStr[segment] += (0x8000 >> i);
+ }
+ }
+ }
+
+ 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;
+ }
+ 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(pattern, "");
+ 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 */
+ if (cc_width != 3) {
+ bin_append(rap_side[LeftRAP - 1], 10, pattern);
+ }
+ bin_append(pdf_bitpattern[offset + dummy[1]], 16, pattern);
+ strcat(pattern, "0");
+ if (cc_width == 3) {
+ bin_append(rap_centre[CentreRAP - 1], 10, pattern);
+ }
+ if (cc_width >= 2) {
+ bin_append(pdf_bitpattern[offset + dummy[2]], 16, pattern);
+ strcat(pattern, "0");
+ }
+ if (cc_width == 4) {
+ bin_append(rap_centre[CentreRAP - 1], 10, pattern);
+ }
+ if (cc_width >= 3) {
+ bin_append(pdf_bitpattern[offset + dummy[3]], 16, pattern);
+ strcat(pattern, "0");
+ }
+ if (cc_width == 4) {
+ bin_append(pdf_bitpattern[offset + dummy[4]], 16, pattern);
+ strcat(pattern, "0");
+ }
+ bin_append(rap_side[RightRAP - 1], 10, pattern);
+ strcat(pattern, "1"); /* stop */
+
+ /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */
+ for (loop = 0; loop < (int) strlen(pattern); loop++) {
+ if (pattern[loop] == '1') {
+ set_module(symbol, i, loop);
+ }
+ }
+ symbol->row_height[i] = 2;
+ symbol->rows++;
+ symbol->width = strlen(pattern);
+
+ /* 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;
+}
+
+/* CC-B 2D component */
+static int cc_b(struct zint_symbol *symbol, char source[], int cc_width) {
+ int length, i;
+#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, p, longueur, mccorrection[50], offset;
+ int total, dummy[5];
+ char pattern[580];
+ int variant, LeftRAPStart, CentreRAPStart, RightRAPStart, StartCluster;
+ int LeftRAP, CentreRAP, RightRAP, Cluster, loop;
+
+ length = strlen(source) / 8;
+
+ for (i = 0; i < length; i++) {
+ int binloc = i * 8;
+
+ data_string[i] = 0;
+ for (p = 0; p < 8; p++) {
+ if (source[binloc + p] == '1') {
+ data_string[i] += (0x80 >> p);
+ }
+ }
+ }
+
+
+ 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);
+
+ /* 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--;
+ assert(variant >= 0);
+ 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;
+ }
+ 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(pattern, "");
+ 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 */
+ bin_append(rap_side[LeftRAP - 1], 10, pattern);
+ bin_append(pdf_bitpattern[offset + dummy[1]], 16, pattern);
+ strcat(pattern, "0");
+ if (cc_width == 3) {
+ bin_append(rap_centre[CentreRAP - 1], 10, pattern);
+ }
+ if (cc_width >= 2) {
+ bin_append(pdf_bitpattern[offset + dummy[2]], 16, pattern);
+ strcat(pattern, "0");
+ }
+ if (cc_width == 4) {
+ bin_append(rap_centre[CentreRAP - 1], 10, pattern);
+ }
+ if (cc_width >= 3) {
+ bin_append(pdf_bitpattern[offset + dummy[3]], 16, pattern);
+ strcat(pattern, "0");
+ }
+ if (cc_width == 4) {
+ bin_append(pdf_bitpattern[offset + dummy[4]], 16, pattern);
+ strcat(pattern, "0");
+ }
+ bin_append(rap_side[RightRAP - 1], 10, pattern);
+ strcat(pattern, "1"); /* stop */
+
+ /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */
+ for (loop = 0; loop < (int) strlen(pattern); loop++) {
+ if (pattern[loop] == '1') {
+ set_module(symbol, i, loop);
+ }
+ }
+ symbol->row_height[i] = 2;
+ symbol->width = strlen(pattern);
+
+ /* 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;
+}
+
+/* CC-C 2D component - byte compressed PDF417 */
+static int cc_c(struct zint_symbol *symbol, char source[], int cc_width, int ecc_level) {
+ int length, i, p;
+#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 pattern[580];
+
+ length = strlen(source) / 8;
+
+ for (i = 0; i < length; i++) {
+ int binloc = i * 8;
+
+ data_string[i] = 0;
+ for (p = 0; p < 8; p++) {
+ if (source[binloc + p] == '1') {
+ data_string[i] += (0x80 >> p);
+ }
+ }
+ }
+
+ mclength = 0;
+
+ chainemc[mclength] = 0; /* space for length descriptor */
+ mclength++;
+ chainemc[mclength] = 920; /* CC-C identifier */
+ mclength++;
+
+ byteprocess(chainemc, &mclength, data_string, 0, length);
+
+ 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;
+ }
+ 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) {
+ case 0:
+ dummy[0] = k + c1;
+ dummy[cc_width + 1] = k + c3;
+ offset = 0; /* cluster(0) */
+ break;
+ case 1:
+ dummy[0] = k + c2;
+ dummy[cc_width + 1] = k + c1;
+ offset = 929; /* cluster(3) */
+ break;
+ case 2:
+ dummy[0] = k + c3;
+ dummy[cc_width + 1] = k + c2;
+ offset = 1858; /* cluster(6) */
+ break;
+ }
+ strcpy(pattern, "");
+ bin_append(0x1FEA8, 17, pattern); /* Row start */
+
+ for (j = 0; j <= cc_width + 1; j++) {
+ bin_append(pdf_bitpattern[offset + dummy[j]], 16, pattern);
+ strcat(pattern, "0");
+ }
+ bin_append(0x3FA29, 18, pattern); /* Row Stop */
+
+ for (loop = 0; loop < (int) strlen(pattern); loop++) {
+ if (pattern[loop] == '1') {
+ set_module(symbol, i, loop);
+ }
+ }
+ symbol->row_height[i] = 3;
+ }
+ symbol->rows = (mclength / cc_width);
+ symbol->width = (int)strlen(pattern);
+
+ return 0;
+}
+
+static int calc_padding_cca(int binary_length, int cc_width) {
+ int target_bitsize = 0;
+
+ switch (cc_width) {
+ case 2:
+ 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) {
+ 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) {
+ 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;
+ }
+
+ return target_bitsize;
+}
+
+static int calc_padding_ccb(int binary_length, int cc_width) {
+ int target_bitsize = 0;
+
+ switch (cc_width) {
+ case 2:
+ 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) {
+ 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) {
+ 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;
+ }
+
+ return target_bitsize;
+}
+
+static int calc_padding_ccc(int binary_length, int *cc_width, int lin_width, int *ecc) {
+ int target_bitsize = 0;
+ 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;
+
+ /* Recommended minimum ecc levels ISO/IEC 1543:2015 (PDF417) Annex E Table E.1,
+ restricted by CC-C codeword max 900 (30 cols * 30 rows), GS1 General Specifications 19.1 5.9.2.3 */
+ if (codewords_used <= 40) {
+ ecc_level = 2;
+ } else if (codewords_used <= 160) {
+ ecc_level = 3;
+ } else if (codewords_used <= 320) {
+ ecc_level = 4;
+ } else if (codewords_used <= 833) { /* 900 - 3 - 64 */
+ ecc_level = 5;
+ } else if (codewords_used <= 865) { /* 900 - 3 - 32 */
+ ecc_level = 4; /* Not recommended but allow to meet advertised "up to 2361 digits" (allows max 2372) */
+ } else {
+ return 0;
+ }
+ *(ecc) = ecc_level;
+ ecc_codewords = 1 << (ecc_level + 1);
+
+ codewords_used += ecc_codewords;
+ codewords_used += 3;
+
+ *(cc_width) = (lin_width - 53) / 17; // -53 = (6 left quiet zone + 10 right quiet zone - (17 * 3 + 18))
+ if (*(cc_width) > 30) {
+ *(cc_width) = 30;
+ }
+ rows = ceil((double) codewords_used / *(cc_width));
+ /* stop the symbol from becoming too high */
+ while (rows > 30 && *(cc_width) < 30) {
+ *(cc_width) = *(cc_width) + 1;
+ rows = ceil((double) codewords_used / *(cc_width));
+ }
+
+ if (rows > 30) {
+ return 0;
+ }
+ if (rows < 3) {
+ rows = 3;
+ }
+
+ 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;
+
+ return target_bitsize;
+}
+
+static 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, alpha_pad;
+ int i, j, ai_crop, ai_crop_posn, fnc1_latch;
+ int ai90_mode, last_digit, remainder, binary_length;
+ int mode;
+ int source_len = strlen(source);
+#ifndef _MSC_VER
+ char general_field[source_len + 1];
+#else
+ char* general_field = (char*) _alloca(source_len + 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;
+ target_bitsize = 0;
+ mode = NUMERIC;
+
+ if ((source[0] == '1') && ((source[1] == '0') || (source[1] == '1') || (source[1] == '7'))) {
+ /* 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) {
+ strcat(binary_string, "0");
+ }
+
+ if (encoding_method == 2) {
+ /* Encoding Method field "10" - date and lot number */
+
+ strcat(binary_string, "10");
+
+ if (source[1] == '0') {
+ /* No date data */
+ strcat(binary_string, "11");
+ read_posn = 2;
+ } else {
+ long int group_val;
+ /* Production Date (11) or Expiration Date (17) */
+ char date_str[4];
+ 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);
+
+ bin_append(group_val, 16, binary_string);
+
+ if (source[1] == '1') {
+ /* Production Date AI 11 */
+ strcat(binary_string, "0");
+ } else {
+ /* Expiration Date AI 17 */
+ strcat(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 if (source[read_posn]) {
+ /* ISO/IEC 24723:2010 5.3.1 "If a lot number does not directly follow the date element string, a FNC1 is encoded following the date element string ..." */
+ fnc1_latch = 1;
+ } else {
+ /* "... even if no more data follows the date element string" */
+ /* So still need FNC1 character but can't do single FNC1 in numeric mode, so insert alphanumeric latch "0000" and alphanumeric FNC1 "01111"
+ (this implementation detail taken from BWIPP https://github.com/bwipp/postscriptbarcode Copyright (c) 2004-2019 Terry Burton) */
+ strcat(binary_string, "000001111");
+ /* Note an alphanumeric FNC1 is also a numeric latch, so now in numeric mode */
+ }
+ }
+ }
+
+ if (encoding_method == 3) {
+ /* Encodation Method field of "11" - AI 90 */
+#ifndef _MSC_VER
+ char ninety[source_len + 1];
+#else
+ char* ninety = (char*) _alloca(source_len + 1);
+#endif
+ int ninety_len, alpha, alphanum, numeric, test1, test2, test3;
+
+ /* "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.3.2) */
+
+ memset(ninety, 0, source_len + 1);
+ i = 0;
+ do {
+ ninety[i] = source[i + 2];
+ i++;
+ } while ((source_len > i + 2) && ('[' != source[i + 2]));
+ ninety[i] = '\0';
+ ninety_len = strlen(ninety);
+
+ /* Find out if the AI 90 data is alphabetic or numeric or both */
+
+ alpha = 0;
+ alphanum = 0;
+ numeric = 0;
+
+ for (i = 0; i < ninety_len; i++) {
+
+ if ((ninety[i] >= 'A') && (ninety[i] <= 'Z')) {
+ /* Character is alphabetic */
+ alpha += 1;
+ } else if ((ninety[i] >= '0') && (ninety[i] <= '9')) {
+ /* Character is numeric */
+ numeric += 1;
+ } else {
+ alphanum += 1;
+ }
+ }
+
+ /* 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)) {
+ int next_ai_posn;
+ char numeric_part[4];
+ int numeric_value;
+ int table3_letter;
+ /* Encodation method "11" can be used */
+ strcat(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 && alpha > numeric) {
+ /* Alphabetic mode */
+ strcat(binary_string, "11");
+ ai90_mode = 2;
+ } else if (alphanum == 0 && alpha == 0) {
+ /* Numeric mode */
+ strcat(binary_string, "10");
+ ai90_mode = 3;
+ } else {
+ /* Alphanumeric mode */
+ strcat(binary_string, "0");
+ ai90_mode = 1;
+ mode = ALPHA;
+ }
+
+ next_ai_posn = 2 + ninety_len;
+
+ if (source[next_ai_posn] == '[') {
+ /* There are more AIs afterwards */
+ if ((source[next_ai_posn + 1] == '2') && (source[next_ai_posn + 2] == '1')) {
+ /* AI 21 follows */
+ ai_crop = 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 = 3;
+ }
+ }
+
+ switch (ai_crop) {
+ case 0: strcat(binary_string, "0");
+ break;
+ case 1: strcat(binary_string, "10");
+ ai_crop_posn = next_ai_posn + 1;
+ break;
+ case 3: strcat(binary_string, "11");
+ ai_crop_posn = next_ai_posn + 1;
+ 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) {
+ table3_letter = posn("BDHIJKLNPQRSTVWZ", ninety[test1]);
+ }
+
+ if (table3_letter != -1) {
+ /* Encoding can be done according to 5.3.2 c) 2) */
+ /* five bit binary string representing value before letter */
+ bin_append(numeric_value, 5, binary_string);
+
+ /* followed by four bit representation of letter from Table 3 */
+ bin_append(table3_letter, 4, binary_string);
+ } else {
+ /* Encoding is done according to 5.3.2 c) 3) */
+ bin_append(31, 5, binary_string);
+ /* ten bit representation of number */
+ bin_append(numeric_value, 10, binary_string);
+
+ /* five bit representation of ASCII character */
+ bin_append(ninety[test1] - 65, 5, binary_string);
+ }
+
+ read_posn = test1 + 3;
+
+ /* Do Alpha mode encoding of the rest of the AI 90 data field here */
+ if (ai90_mode == 2) {
+ /* Alpha encodation (section 5.3.3) */
+ do {
+ if ((source[read_posn] >= 'A') && (source[read_posn] <= 'Z')) {
+ bin_append(source[read_posn] - 65, 5, binary_string);
+
+ } else if ((source[read_posn] >= '0') && (source[read_posn] <= '9')) {
+ bin_append(source[read_posn] + 4, 6, binary_string);
+
+ } else if (source[read_posn] == '[') {
+ bin_append(31, 5, binary_string);
+ }
+
+ read_posn++;
+ } while ((source[read_posn - 1] != '[') && (source[read_posn - 1] != '\0'));
+ alpha_pad = 1; /* This is overwritten if a general field is encoded */
+ }
+
+ } else {
+ /* Use general field encodation instead */
+ strcat(binary_string, "0");
+ read_posn = 0;
+ }
+ }
+
+ /* 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 < source_len; i++) {
+ /* Skip "[21" or "[8004" AIs if encodation method "11" used */
+ if (i == ai_crop_posn) {
+ i += ai_crop;
+ } else {
+ general_field[j] = source[i];
+ j++;
+ }
+ }
+ general_field[j] = '\0';
+
+ if (strlen(general_field) != 0) {
+ alpha_pad = 0;
+ }
+
+ if (!general_field_encode(general_field, &mode, &last_digit, binary_string)) {
+ /* Invalid characters in input data */
+ strcpy(symbol->errtxt, "441: Invalid characters in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ binary_length = (int)strlen(binary_string);
+ switch (cc_mode) {
+ case 1:
+ target_bitsize = calc_padding_cca(binary_length, *(cc_width));
+ break;
+ case 2:
+ target_bitsize = calc_padding_ccb(binary_length, *(cc_width));
+ break;
+ case 3:
+ target_bitsize = calc_padding_ccc(binary_length, cc_width, lin_width, ecc);
+ break;
+ }
+
+ if (target_bitsize == 0) {
+ strcpy(symbol->errtxt, "442: Input too long for selected 2d component");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ remainder = target_bitsize - binary_length;
+
+ if (last_digit) {
+ /* There is still one more numeric digit to encode */
+
+ if ((remainder >= 4) && (remainder <= 6)) {
+ /* ISO/IEC 24723:2010 5.4.1 c) 2) "If four to six bits remain, add 1 to the digit value and encode the result in the next four bits. ..." */
+ bin_append(ctoi(last_digit) + 1, 4, binary_string);
+ if (remainder > 4) {
+ /* "... The fifth and sixth bits, if present, shall be “0â€s." (Covered by adding truncated alphanumeric latch below but do explicitly anyway) */
+ bin_append(0, remainder - 4, binary_string);
+ }
+ } else {
+ bin_append((11 * ctoi(last_digit)) + 18, 7, binary_string);
+ /* This may push the symbol up to the next size */
+ }
+ }
+
+ if (strlen(binary_string) > 11805) { /* (2361 * 5) */
+ strcpy(symbol->errtxt, "443: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ binary_length = (int)strlen(binary_string);
+ switch (cc_mode) {
+ case 1:
+ target_bitsize = calc_padding_cca(binary_length, *(cc_width));
+ break;
+ case 2:
+ target_bitsize = calc_padding_ccb(binary_length, *(cc_width));
+ break;
+ case 3:
+ target_bitsize = calc_padding_ccc(binary_length, cc_width, lin_width, ecc);
+ break;
+ }
+
+ if (target_bitsize == 0) {
+ strcpy(symbol->errtxt, "444: Input too long for selected 2d component");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ if (binary_length < target_bitsize) {
+ /* Now add padding to binary string */
+ if (alpha_pad == 1) {
+ strcat(binary_string, "11111");
+ alpha_pad = 0;
+ /* Extra FNC1 character required after Alpha encodation (section 5.3.3) */
+ }
+
+ if (mode == NUMERIC) {
+ strcat(binary_string, "0000");
+ }
+
+ while (strlen(binary_string) < (unsigned int) target_bitsize) {
+ strcat(binary_string, "00100");
+ }
+
+ if (strlen(binary_string) > (unsigned int) target_bitsize) {
+ binary_string[target_bitsize] = '\0';
+ }
+ }
+
+ return 0;
+}
+
+static int linear_dummy_run(unsigned char *source, int length) {
+ struct zint_symbol *dummy;
+ int error_number;
+ int linear_width;
+
+ dummy = ZBarcode_Create();
+ dummy->symbology = BARCODE_EAN128_CC;
+ dummy->option_1 = 3;
+ error_number = ean_128(dummy, source, length);
+ linear_width = dummy->width;
+ ZBarcode_Delete(dummy);
+
+ if (error_number == 0) {
+ return linear_width;
+ } else {
+ return 0;
+ }
+}
+
+INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int length) {
+ int error_number, cc_mode, cc_width, ecc_level;
+ int j, i, k;
+ unsigned int bs = 13 * length + 500 + 1; /* Allow for 8 bits + 5-bit latch per char + 500 bits overhead/padding */
+#ifndef _MSC_VER
+ char binary_string[bs];
+#else
+ char* binary_string = (char*) _alloca(bs);
+#endif
+ unsigned int pri_len;
+ struct zint_symbol *linear;
+ int top_shift, bottom_shift;
+ int linear_width = 0;
+
+ /* Perform sanity checks on input options first */
+ error_number = 0;
+ pri_len = (int)strlen(symbol->primary);
+ if (pri_len == 0) {
+ strcpy(symbol->errtxt, "445: No primary (linear) message in 2D composite");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ if (length > 2990) {
+ strcpy(symbol->errtxt, "446: 2D component input data too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ 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, "447: Invalid mode (CC-C only valid with GS1-128 linear component)");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ if (symbol->symbology == BARCODE_EAN128_CC) {
+ /* Do a test run of encoding the linear component to establish its width */
+ linear_width = linear_dummy_run((unsigned char *) symbol->primary, pri_len);
+ if (linear_width == 0) {
+ strcpy(symbol->errtxt, "448: Invalid data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ }
+
+ switch (symbol->symbology) {
+ /* Determine width of 2D component according to ISO/IEC 24723 Table 1 */
+ case BARCODE_EANX_CC:
+ cc_width = 0;
+ if (pri_len < 20) {
+ int padded_pri_len;
+ char padded_pri[20];
+ padded_pri[0] = '\0';
+ ean_leading_zeroes(symbol, (unsigned char*) symbol->primary, (unsigned char*) padded_pri);
+ padded_pri_len = strlen(padded_pri);
+ if (padded_pri_len <= 7) { /* EAN-8 */
+ cc_width = 3;
+ } else {
+ switch (padded_pri_len) {
+ 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;
+ }
+ }
+ }
+ if (cc_width == 0) {
+ strcpy(symbol->errtxt, "449: Invalid length EAN input in linear component");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ 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, (char *) source, binary_string, cc_mode, &cc_width, &ecc_level, linear_width);
+ if (i == ZINT_ERROR_TOO_LONG) {
+ cc_mode = 2;
+ memset(binary_string, 0, bs);
+ } else if (i != 0) {
+ return i;
+ }
+ }
+
+ if (cc_mode == 2) {
+ /* If the data didn't fit into CC-A it is recalculated for CC-B */
+ i = cc_binary_string(symbol, (char *) source, binary_string, cc_mode, &cc_width, &ecc_level, linear_width);
+ if (i == ZINT_ERROR_TOO_LONG) {
+ if (symbol->symbology != BARCODE_EAN128_CC) {
+ return ZINT_ERROR_TOO_LONG;
+ }
+ cc_mode = 3;
+ memset(binary_string, 0, bs);
+ } else if (i != 0) {
+ return i;
+ }
+ }
+
+ 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, (char *) source, binary_string, cc_mode, &cc_width, &ecc_level, linear_width);
+ if (i != 0) {
+ return i;
+ }
+ }
+
+ 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 ZINT_ERROR_ENCODING_PROBLEM;
+ }
+
+ /* 2D component done, now calculate linear component */
+ linear = ZBarcode_Create(); /* Symbol contains the 2D component and Linear contains the rest */
+
+ 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);
+ strcat(symbol->errtxt, " in linear component ");
+ ZBarcode_Delete(linear);
+ return error_number;
+ }
+
+ /* 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 (ustrlen(linear->text)) { /* Use zero-padded length */
+ case 8: /* EAN-8 */
+ case 11: /* EAN-8 + 2 */
+ case 14: /* EAN-8 + 5 */
+ if (cc_mode == 1) {
+ bottom_shift = 3;
+ } else {
+ bottom_shift = 13;
+ }
+ break;
+ case 13: /* EAN-13 */
+ case 16: /* EAN-13 + 2 */
+ case 19: /* EAN-13 + 5 */
+ bottom_shift = 2;
+ break;
+ }
+ break;
+ case BARCODE_EAN128_CC: if (cc_mode == 3) {
+ bottom_shift = 7;
+ } else {
+ /* ISO/IEC 24723:2010 12.3 g) "GS1-128 components linked to the right quiet zone of the CC-A or CC-B: the CC-A or CC-B component is
+ aligned with the last space module of one of the rightmost symbol characters of the linear component. To
+ calculate the target Code 128 symbol character position for alignment, number the positions from right to
+ left (0 is the Stop character, 1 is the Check character, etc.), and then Position = (total number of Code 128 symbol characters – 9) div 2"
+ */
+ int num_symbols = (linear_width - 2) / 11;
+ int position = (num_symbols - 9) / 2;
+ int calc_shift = linear->width - position * 11 - 1 - symbol->width; /* Less 1 to align with last space module */
+ if (position) {
+ calc_shift -= 2; /* Less additional stop modules */
+ }
+ if (calc_shift > 0) {
+ top_shift = calc_shift;
+ } else if (calc_shift < 0) {
+ bottom_shift = -calc_shift;
+ }
+ }
+ break;
+ case BARCODE_RSS14_CC: bottom_shift = 4;
+ break;
+ case BARCODE_RSS_LTD_CC:
+ if (cc_mode == 1) {
+ top_shift = 1;
+ } else {
+ 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)) {
+ 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)) {
+ 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 + top_shift) {
+ symbol->width = linear->width + bottom_shift;
+ } else if ((symbol->width + top_shift) > linear->width + bottom_shift) {
+ 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 0000000..6195d29
--- /dev/null
+++ b/backend/composite.h
@@ -0,0 +1,67 @@
+/* composite.c - Tables for UCC.EAN Composite Symbols */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/* CC-A component coefficients from ISO/IEC 24728:2006 Annex F */
+static const unsigned short 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 const char 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 const char 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, 26, 14, 9,
+ 19, 33, 12, 40, 46, 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
index 50f1653..71f5a75 100644
--- a/backend/dllversion.c
+++ b/backend/dllversion.c
@@ -18,14 +18,14 @@ HRESULT DllGetVersion (DLLVERSIONINFO2* pdvi)
{
if (!pdvi || (sizeof(*pdvi) != pdvi->info1.cbSize))
return (E_INVALIDARG);
-
+
pdvi->info1.dwMajorVersion = 2;
- pdvi->info1.dwMinorVersion = 4;
- pdvi->info1.dwBuildNumber = 2;
+ pdvi->info1.dwMinorVersion = 8;
+ pdvi->info1.dwBuildNumber = 1;
pdvi->info1.dwPlatformID = DLLVER_PLATFORM_WINDOWS;
if (sizeof(DLLVERSIONINFO2) == pdvi->info1.cbSize)
- pdvi->ullVersion = MAKEDLLVERULL(2, 4, 2, 0);
-
+ pdvi->ullVersion = MAKEDLLVERULL(2, 8, 1, 0);
+
return S_OK;
}
#endif /* _WIN32 */
diff --git a/backend/dmatrix.c b/backend/dmatrix.c
new file mode 100644
index 0000000..212eb6d
--- /dev/null
+++ b/backend/dmatrix.c
@@ -0,0 +1,1342 @@
+/* dmatrix.c Handles Data Matrix ECC 200 symbols */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2009-2017 Robin Stuart <rstuart114@gmail.com>
+
+ 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 <stefan@datenfreihafen.org>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <assert.h>
+#include <math.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+/* ceilf (C99) not before MSVC++2013 (C++ 12.0) */
+#if _MSC_VER < 1800
+#define ceilf ceil
+#endif
+#endif
+#include "common.h"
+#include "reedsol.h"
+#include "dmatrix.h"
+
+/* Annex M placement alorithm low level */
+static void ecc200placementbit(int *array, const int NR, const int NC, int r, int c, const int p, const char b) {
+ if (r < 0) {
+ r += NR;
+ c += 4 - ((NR + 4) % 8);
+ }
+ if (c < 0) {
+ c += NC;
+ r += 4 - ((NC + 4) % 8);
+ }
+ // Necessary for 26x32,26x40,26x48,36x120,36x144,72x120,72x144
+ if (r >= NR) {
+#ifdef DEBUG
+ fprintf(stderr, "r >= NR:%i,%i at r=%i->", p, b, r);
+#endif
+ r -= NR;
+#ifdef DEBUG
+ fprintf(stderr, "%i,c=%i\n", r, c);
+#endif
+ }
+#ifdef DEBUG
+ if (0 != array[r * NC + c]) {
+ int a = array[r * NC + c];
+ fprintf(stderr, "Double:%i,%i->%i,%i at r=%i,c=%i\n", a >> 3, a & 7, p, b, r, c);
+ return;
+ }
+#endif
+ // Check index limits
+ assert(r < NR);
+ assert(c < NC);
+ // Check double-assignment
+ assert(0 == array[r * NC + c]);
+ array[r * NC + c] = (p << 3) + b;
+}
+
+static void ecc200placementblock(int *array, const int NR, const int NC, const int r,
+ const int c, const 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, const int NR, const int NC, const 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, const int NR, const int NC, const 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, const int NR, const int NC, const 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, const int NR, const int NC, const 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, const int NR, const 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, const int bytes, const int datablock, const int rsblock, const int skew) {
+ int blocks = (bytes + 2) / datablock, b;
+ int n;
+ rs_init_gf(0x12d);
+ rs_init_code(rsblock, 1);
+ for (b = 0; b < blocks; b++) {
+ unsigned char buf[256], ecc[256];
+ int 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) {
+ if (skew) {
+ /* Rotate ecc data to make 144x144 size symbols acceptable */
+ /* See http://groups.google.com/group/postscriptbarcode/msg/5ae8fda7757477da */
+ if (b < 8) {
+ binary[bytes + n + 2] = ecc[p--];
+ } else {
+ binary[bytes + n - 8] = ecc[p--];
+ }
+ } else {
+ binary[bytes + n] = ecc[p--];
+ }
+ }
+ }
+ rs_free();
+}
+
+/* Return true (1) if a character is valid in X12 set */
+static int isX12(const int source) {
+
+ switch(source) {
+ case 13: // CR
+ case 42: // *
+ case 62: // >
+ case 32: // space
+ return 1;
+ }
+
+ if ((source >= '0') && (source <= '9')) {
+ return 1;
+ }
+ if ((source >= 'A') && (source <= 'Z')) {
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Insert a character into the middle of a string at position posn */
+static void dminsert(char binary_string[], const int posn, const char newbit) {
+ int i, end;
+
+ end = (int) strlen(binary_string);
+ for (i = end + 1; i > posn; i--) {
+ binary_string[i] = binary_string[i - 1];
+ }
+ binary_string[posn] = newbit;
+}
+
+static void insert_value(unsigned char binary_stream[], const int posn, const int streamlen, const int newbit) {
+ int i;
+
+ for(i = (int)streamlen; i > posn; i--) {
+ binary_stream[i] = binary_stream[i - 1];
+ }
+ binary_stream[posn] = (unsigned char) newbit;
+}
+
+static int p_r_6_2_1(const unsigned char inputData[], const size_t position, const size_t sourcelen) {
+ /* Annex P section (r)(6)(ii)(I)
+ "If one of the three X12 terminator/separator characters first
+ occurs in the yet to be processed data before a non-X12 character..."
+ */
+
+ size_t i;
+ size_t nonX12Position = 0;
+ size_t specialX12Position = 0;
+ int retval = 0;
+
+ for (i = position; i < sourcelen; i++) {
+ if (nonX12Position == 0) {
+ if (isX12(inputData[i]) != 1) {
+ nonX12Position = i;
+ }
+ }
+
+ if (specialX12Position == 0) {
+ if ((inputData[i] == (char) 13) ||
+ (inputData[i] == '*') ||
+ (inputData[i] == '>')) {
+ specialX12Position = i;
+ }
+ }
+ }
+
+ if ((nonX12Position != 0) && (specialX12Position != 0)) {
+ if (specialX12Position < nonX12Position) {
+ retval = 1;
+ }
+ }
+
+ return retval;
+}
+
+/* 'look ahead test' from Annex P */
+static int look_ahead_test(const unsigned char inputData[], const size_t sourcelen, const size_t position, const int current_mode, const int gs1) {
+ float ascii_count, c40_count, text_count, x12_count, edf_count, b256_count, best_count;
+ const float stiction = (1.0F / 24.0F); // smallest change to act on, to get around floating point inaccuracies
+ int best_scheme;
+ size_t sp;
+
+ best_scheme = DM_NULL;
+
+ /* step (j) */
+ if (current_mode == DM_ASCII) {
+ ascii_count = 0.0F;
+ c40_count = 1.0F;
+ text_count = 1.0F;
+ x12_count = 1.0F;
+ edf_count = 1.0F;
+ b256_count = 1.25F;
+ } else {
+ ascii_count = 1.0F;
+ c40_count = 2.0F;
+ text_count = 2.0F;
+ x12_count = 2.0F;
+ edf_count = 2.0F;
+ b256_count = 2.25F;
+ }
+
+ switch (current_mode) {
+ case DM_C40: c40_count = 0.0F;
+ break;
+ case DM_TEXT: text_count = 0.0F;
+ break;
+ case DM_X12: x12_count = 0.0F;
+ break;
+ case DM_EDIFACT: edf_count = 0.0F;
+ break;
+ case DM_BASE256: b256_count = 0.0F;
+ break;
+ }
+
+ sp = position;
+
+ do {
+ if (sp == sourcelen) {
+ /* At the end of data ... step (k) */
+ ascii_count = ceilf(ascii_count);
+ b256_count = ceilf(b256_count);
+ edf_count = ceilf(edf_count);
+ text_count = ceilf(text_count);
+ x12_count = ceilf(x12_count);
+ c40_count = ceilf(c40_count);
+
+ best_count = c40_count;
+ best_scheme = DM_C40; // (k)(7)
+
+ if (x12_count < (best_count - stiction)) {
+ best_count = x12_count;
+ best_scheme = DM_X12; // (k)(6)
+ }
+
+ if (text_count < (best_count - stiction)) {
+ best_count = text_count;
+ best_scheme = DM_TEXT; // (k)(5)
+ }
+
+ if (edf_count < (best_count - stiction)) {
+ best_count = edf_count;
+ best_scheme = DM_EDIFACT; // (k)(4)
+ }
+
+ if (b256_count < (best_count - stiction)) {
+ best_count = b256_count;
+ best_scheme = DM_BASE256; // (k)(3)
+ }
+
+ if (ascii_count <= (best_count + stiction)) {
+ best_scheme = DM_ASCII; // (k)(2)
+ }
+ } else {
+
+ /* ascii ... step (l) */
+ if ((inputData[sp] >= '0') && (inputData[sp] <= '9')) {
+ ascii_count += 0.5F; // (l)(1)
+ } else {
+ if (inputData[sp] > 127) {
+ ascii_count = ceilf(ascii_count) + 2.0F; // (l)(2)
+ } else {
+ ascii_count = ceilf(ascii_count) + 1.0F; // (l)(3)
+ }
+ }
+
+ /* c40 ... step (m) */
+ if ((inputData[sp] == ' ') ||
+ (((inputData[sp] >= '0') && (inputData[sp] <= '9')) ||
+ ((inputData[sp] >= 'A') && (inputData[sp] <= 'Z')))) {
+ c40_count += (2.0F / 3.0F); // (m)(1)
+ } else {
+ if (inputData[sp] > 127) {
+ c40_count += (8.0F / 3.0F); // (m)(2)
+ } else {
+ c40_count += (4.0F / 3.0F); // (m)(3)
+ }
+ }
+
+ /* text ... step (n) */
+ if ((inputData[sp] == ' ') ||
+ (((inputData[sp] >= '0') && (inputData[sp] <= '9')) ||
+ ((inputData[sp] >= 'a') && (inputData[sp] <= 'z')))) {
+ text_count += (2.0F / 3.0F); // (n)(1)
+ } else {
+ if (inputData[sp] > 127) {
+ text_count += (8.0F / 3.0F); // (n)(2)
+ } else {
+ text_count += (4.0F / 3.0F); // (n)(3)
+ }
+ }
+
+ /* x12 ... step (o) */
+ if (isX12(inputData[sp])) {
+ x12_count += (2.0F / 3.0F); // (o)(1)
+ } else {
+ if (inputData[sp] > 127) {
+ x12_count += (13.0F / 3.0F); // (o)(2)
+ } else {
+ x12_count += (10.0F / 3.0F); // (o)(3)
+ }
+ }
+
+ /* edifact ... step (p) */
+ if ((inputData[sp] >= ' ') && (inputData[sp] <= '^')) {
+ edf_count += (3.0F / 4.0F); // (p)(1)
+ } else {
+ if (inputData[sp] > 127) {
+ edf_count += 17.0F; // (p)(2) > Value changed from ISO
+ } else {
+ edf_count += 13.0F; // (p)(3) > Value changed from ISO
+ }
+ }
+ if (gs1 && (inputData[sp] == '[')) {
+ /* fnc1 and gs have the same weight of 13.0f */
+ edf_count += 13.0F; // > Value changed from ISO
+ }
+
+ /* base 256 ... step (q) */
+ if ((gs1 == 1) && (inputData[sp] == '[')) {
+ /* FNC1 separator */
+ b256_count += 4.0F; // (q)(1)
+ } else {
+ b256_count += 1.0F; // (q)(2)
+ }
+ }
+
+
+ if (sp > (position + 3)) {
+ /* 4 data characters processed ... step (r) */
+
+ /* step (r)(6) */
+ if (((c40_count + 1.0F) < (ascii_count - stiction)) &&
+ ((c40_count + 1.0F) < (b256_count - stiction)) &&
+ ((c40_count + 1.0F) < (edf_count - stiction)) &&
+ ((c40_count + 1.0F) < (text_count - stiction))) {
+
+ if (c40_count < (x12_count - stiction)) {
+ best_scheme = DM_C40;
+ }
+
+ if ((c40_count >= (x12_count - stiction))
+ && (c40_count <= (x12_count + stiction))) {
+ if (p_r_6_2_1(inputData, sp, sourcelen) == 1) {
+ // Test (r)(6)(ii)(i)
+ best_scheme = DM_X12;
+ } else {
+ best_scheme = DM_C40;
+ }
+ }
+ }
+
+ /* step (r)(5) */
+ if (((x12_count + 1.0F) < (ascii_count - stiction)) &&
+ ((x12_count + 1.0F) < (b256_count - stiction)) &&
+ ((x12_count + 1.0F) < (edf_count - stiction)) &&
+ ((x12_count + 1.0F) < (text_count - stiction)) &&
+ ((x12_count + 1.0F) < (c40_count - stiction))) {
+ best_scheme = DM_X12;
+ }
+
+ /* step (r)(4) */
+ if (((text_count + 1.0F) < (ascii_count - stiction)) &&
+ ((text_count + 1.0F) < (b256_count - stiction)) &&
+ ((text_count + 1.0F) < (edf_count - stiction)) &&
+ ((text_count + 1.0F) < (x12_count - stiction)) &&
+ ((text_count + 1.0F) < (c40_count - stiction))) {
+ best_scheme = DM_TEXT;
+ }
+
+ /* step (r)(3) */
+ if (((edf_count + 1.0F) < (ascii_count - stiction)) &&
+ ((edf_count + 1.0F) < (b256_count - stiction)) &&
+ ((edf_count + 1.0F) < (text_count - stiction)) &&
+ ((edf_count + 1.0F) < (x12_count - stiction)) &&
+ ((edf_count + 1.0F) < (c40_count - stiction))) {
+ best_scheme = DM_EDIFACT;
+ }
+
+ /* step (r)(2) */
+ if (((b256_count + 1.0F) <= (ascii_count + stiction)) ||
+ (((b256_count + 1.0F) < (edf_count - stiction)) &&
+ ((b256_count + 1.0F) < (text_count - stiction)) &&
+ ((b256_count + 1.0F) < (x12_count - stiction)) &&
+ ((b256_count + 1.0F) < (c40_count - stiction)))) {
+ best_scheme = DM_BASE256;
+ }
+
+ /* step (r)(1) */
+ if (((ascii_count + 1.0F) <= (b256_count + stiction)) &&
+ ((ascii_count + 1.0F) <= (edf_count + stiction)) &&
+ ((ascii_count + 1.0F) <= (text_count + stiction)) &&
+ ((ascii_count + 1.0F) <= (x12_count + stiction)) &&
+ ((ascii_count + 1.0F) <= (c40_count + stiction))) {
+ best_scheme = DM_ASCII;
+ }
+ }
+
+ sp++;
+ } while (best_scheme == DM_NULL); // step (s)
+
+ return best_scheme;
+}
+
+/* Encodes data using ASCII, C40, Text, X12, EDIFACT or Base 256 modes as appropriate
+ Supports encoding FNC1 in supporting systems */
+static int dm200encode(struct zint_symbol *symbol, const unsigned char source[], unsigned char target[], int *last_mode, size_t *length_p, int process_buffer[], int *process_p, int *binlen_p) {
+
+ size_t sp;
+ int tp, i, gs1;
+ int current_mode, next_mode;
+ size_t inputlen = *length_p;
+ int debug = symbol->debug;
+#ifndef _MSC_VER
+ char binary[2 * inputlen + 1 + 4 + 1]; /* Allow for GS1/READER_INIT, ECI and nul chars overhead */
+#else
+ char* binary = (char*) _alloca(2 * inputlen + 1 + 4 + 1);
+#endif
+
+ sp = 0;
+ tp = 0;
+ memset(process_buffer, 0, 8);
+ *process_p = 0;
+ strcpy(binary, "");
+
+ /* step (a) */
+ current_mode = DM_ASCII;
+ next_mode = DM_ASCII;
+
+ /* gs1 flag values: 0: no gs1, 1: gs1 with FNC1 serparator, 2: GS separator */
+ if ((symbol->input_mode & 0x07) == GS1_MODE) {
+ if (symbol->output_options & GS1_GS_SEPARATOR) {
+ gs1 = 2;
+ } else {
+ gs1 = 1;
+ }
+ } else {
+ gs1 = 0;
+ }
+
+ if (gs1) {
+ target[tp] = 232;
+ tp++;
+ strcat(binary, " ");
+ if (debug) printf("FN1 ");
+ } /* FNC1 */
+
+ if (symbol->output_options & READER_INIT) {
+ if (gs1) {
+ strcpy(symbol->errtxt, "521: Cannot encode in GS1 mode and Reader Initialisation at the same time");
+ return ZINT_ERROR_INVALID_OPTION;
+ } else {
+ target[tp] = 234;
+ tp++; /* Reader Programming */
+ strcat(binary, " ");
+ if (debug) printf("RP ");
+ }
+ }
+
+ if (symbol->eci > 0) {
+ /* Encode ECI numbers according to Table 6 */
+ target[tp] = 241; /* ECI Character */
+ tp++;
+ if (symbol->eci <= 126) {
+ target[tp] = (unsigned char) symbol->eci + 1;
+ tp++;
+ strcat(binary, " ");
+ }
+ if ((symbol->eci >= 127) && (symbol->eci <= 16382)) {
+ target[tp] = (unsigned char) ((symbol->eci - 127) / 254) + 128;
+ tp++;
+ target[tp] = (unsigned char) ((symbol->eci - 127) % 254) + 1;
+ tp++;
+ strcat(binary, " ");
+ }
+ if (symbol->eci >= 16383) {
+ target[tp] = (unsigned char) ((symbol->eci - 16383) / 64516) + 192;
+ tp++;
+ target[tp] = (unsigned char) (((symbol->eci - 16383) / 254) % 254) + 1;
+ tp++;
+ target[tp] = (unsigned char) ((symbol->eci - 16383) % 254) + 1;
+ tp++;
+ strcat(binary, " ");
+ }
+ if (debug) printf("ECI %d ", symbol->eci + 1);
+ }
+
+ /* Check for Macro05/Macro06 */
+ /* "[)>[RS]05[GS]...[RS][EOT]" -> CW 236 */
+ /* "[)>[RS]06[GS]...[RS][EOT]" -> CW 237 */
+ if (tp == 0 && sp == 0 && inputlen >= 9
+ && source[0] == '[' && source[1] == ')' && source[2] == '>'
+ && source[3] == '\x1e' && source[4] == '0'
+ && (source[5] == '5' || source[5] == '6')
+ && source[6] == '\x1d'
+ && source[inputlen - 2] == '\x1e' && source[inputlen - 1] == '\x04') {
+ /* Output macro Codeword */
+ if (source[5] == '5') {
+ target[tp] = 236;
+ if (debug) printf("Macro05 ");
+ } else {
+ target[tp] = 237;
+ if (debug) printf("Macro06 ");
+ }
+ tp++;
+ strcat(binary, " ");
+ /* Remove macro characters from input string */
+ sp = 7;
+ inputlen -= 2;
+ *length_p -= 2;
+ }
+
+
+ while (sp < inputlen) {
+
+ current_mode = next_mode;
+
+ /* step (b) - ASCII encodation */
+ if (current_mode == DM_ASCII) {
+ next_mode = DM_ASCII;
+
+ if (istwodigits(source, inputlen, sp)) {
+ target[tp] = (unsigned char) ((10 * ctoi(source[sp])) + ctoi(source[sp + 1]) + 130);
+ if (debug) printf("N%d ", target[tp] - 130);
+ tp++;
+ strcat(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++;
+ strcat(binary, " ");
+ if (debug) printf("C40 ");
+ break;
+ case DM_TEXT: target[tp] = 239;
+ tp++;
+ strcat(binary, " ");
+ if (debug) printf("TEX ");
+ break;
+ case DM_X12: target[tp] = 238;
+ tp++;
+ strcat(binary, " ");
+ if (debug) printf("X12 ");
+ break;
+ case DM_EDIFACT: target[tp] = 240;
+ tp++;
+ strcat(binary, " ");
+ if (debug) printf("EDI ");
+ break;
+ case DM_BASE256: target[tp] = 231;
+ tp++;
+ strcat(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++;
+ strcat(binary, " ");
+ } else {
+ if (gs1 && (source[sp] == '[')) {
+ if (gs1==2) {
+ target[tp] = 29+1; /* GS */
+ if (debug) printf("GS ");
+ } else {
+ target[tp] = 232; /* FNC1 */
+ if (debug) printf("FN1 ");
+ }
+ } else {
+ target[tp] = source[sp] + 1;
+ if (debug) printf("A%02X ", target[tp] - 1);
+ }
+ tp++;
+ strcat(binary, " ");
+ }
+ sp++;
+ }
+ }
+
+ }
+
+ /* step (c) C40 encodation */
+ if (current_mode == DM_C40) {
+
+ next_mode = DM_C40;
+ if (*process_p == 0) {
+ next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
+ }
+
+ if (next_mode != DM_C40) {
+ target[tp] = 254;
+ tp++;
+ strcat(binary, " "); /* Unlatch */
+ next_mode = DM_ASCII;
+ if (debug) printf("ASC ");
+ } else {
+ int shift_set, value;
+ if (source[sp] > 127) {
+ process_buffer[*process_p] = 1;
+ (*process_p)++;
+ process_buffer[*process_p] = 30;
+ (*process_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] == '[')) {
+ if (gs1 == 2) {
+ shift_set = c40_shift[29];
+ value = c40_value[29]; /* GS */
+ } else {
+ shift_set = 2;
+ value = 27; /* FNC1 */
+ }
+ }
+
+ if (shift_set != 0) {
+ process_buffer[*process_p] = shift_set - 1;
+ (*process_p)++;
+ }
+ process_buffer[*process_p] = value;
+ (*process_p)++;
+
+ while (*process_p >= 3) {
+ int iv;
+
+ iv = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + (process_buffer[2]) + 1;
+ target[tp] = (unsigned char) (iv / 256);
+ tp++;
+ target[tp] = iv % 256;
+ tp++;
+ strcat(binary, " ");
+ if (debug) printf("[%d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2]);
+
+ process_buffer[0] = process_buffer[3];
+ process_buffer[1] = process_buffer[4];
+ process_buffer[2] = process_buffer[5];
+ process_buffer[3] = 0;
+ process_buffer[4] = 0;
+ process_buffer[5] = 0;
+ *process_p -= 3;
+ }
+ sp++;
+ }
+ }
+
+ /* step (d) Text encodation */
+ if (current_mode == DM_TEXT) {
+
+ next_mode = DM_TEXT;
+ if (*process_p == 0) {
+ next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
+ }
+
+ if (next_mode != DM_TEXT) {
+ target[tp] = 254;
+ tp++;
+ strcat(binary, " "); /* Unlatch */
+ next_mode = DM_ASCII;
+ if (debug) printf("ASC ");
+ } else {
+ int shift_set, value;
+ if (source[sp] > 127) {
+ process_buffer[*process_p] = 1;
+ (*process_p)++;
+ process_buffer[*process_p] = 30;
+ (*process_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] == '[')) {
+ if (gs1 == 2) {
+ shift_set = text_shift[29];
+ value = text_value[29]; /* GS */
+ } else {
+ shift_set = 2;
+ value = 27; /* FNC1 */
+ }
+ }
+
+ if (shift_set != 0) {
+ process_buffer[*process_p] = shift_set - 1;
+ (*process_p)++;
+ }
+ process_buffer[*process_p] = value;
+ (*process_p)++;
+
+ while (*process_p >= 3) {
+ int iv;
+
+ iv = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + (process_buffer[2]) + 1;
+ target[tp] = (unsigned char) (iv / 256);
+ tp++;
+ target[tp] = iv % 256;
+ tp++;
+ strcat(binary, " ");
+ if (debug) printf("[%d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2]);
+
+ process_buffer[0] = process_buffer[3];
+ process_buffer[1] = process_buffer[4];
+ process_buffer[2] = process_buffer[5];
+ process_buffer[3] = 0;
+ process_buffer[4] = 0;
+ process_buffer[5] = 0;
+ *process_p -= 3;
+ }
+ sp++;
+ }
+ }
+
+ /* step (e) X12 encodation */
+ if (current_mode == DM_X12) {
+
+ next_mode = DM_X12;
+ if (*process_p == 0) {
+ next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
+ }
+
+ if (next_mode != DM_X12) {
+ target[tp] = 254;
+ tp++;
+ strcat(binary, " "); /* Unlatch */
+ next_mode = DM_ASCII;
+ if (debug) printf("ASC ");
+ } else {
+ int value = 0;
+ 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;
+ }
+
+ process_buffer[*process_p] = value;
+ (*process_p)++;
+
+ while (*process_p >= 3) {
+ int iv;
+
+ iv = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + (process_buffer[2]) + 1;
+ target[tp] = (unsigned char) (iv / 256);
+ tp++;
+ target[tp] = iv % 256;
+ tp++;
+ strcat(binary, " ");
+ if (debug) printf("[%d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2]);
+
+ process_buffer[0] = process_buffer[3];
+ process_buffer[1] = process_buffer[4];
+ process_buffer[2] = process_buffer[5];
+ process_buffer[3] = 0;
+ process_buffer[4] = 0;
+ process_buffer[5] = 0;
+ *process_p -= 3;
+ }
+ sp++;
+ }
+ }
+
+ /* step (f) EDIFACT encodation */
+ if (current_mode == DM_EDIFACT) {
+
+ next_mode = DM_EDIFACT;
+ if (*process_p == 3) {
+ next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
+ }
+
+ if (next_mode != DM_EDIFACT) {
+ process_buffer[*process_p] = 31;
+ (*process_p)++;
+ next_mode = DM_ASCII;
+ } else {
+ int value = source[sp];
+
+ if (source[sp] >= 64) { // '@'
+ value -= 64;
+ }
+
+ process_buffer[*process_p] = value;
+ (*process_p)++;
+ sp++;
+ }
+
+ while (*process_p >= 4) {
+ target[tp] = (unsigned char) ((process_buffer[0] << 2) + ((process_buffer[1] & 0x30) >> 4));
+ tp++;
+ target[tp] = ((process_buffer[1] & 0x0f) << 4) + ((process_buffer[2] & 0x3c) >> 2);
+ tp++;
+ target[tp] = (unsigned char) (((process_buffer[2] & 0x03) << 6) + process_buffer[3]);
+ tp++;
+ strcat(binary, " ");
+ if (debug) printf("[%d %d %d %d] ", process_buffer[0], process_buffer[1], process_buffer[2], process_buffer[3]);
+
+ process_buffer[0] = process_buffer[4];
+ process_buffer[1] = process_buffer[5];
+ process_buffer[2] = process_buffer[6];
+ process_buffer[3] = process_buffer[7];
+ process_buffer[4] = 0;
+ process_buffer[5] = 0;
+ process_buffer[6] = 0;
+ process_buffer[7] = 0;
+ *process_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++;
+ strcat(binary, "b");
+ } else {
+ next_mode = DM_ASCII;
+ if (debug) printf("ASC ");
+ }
+ }
+
+ if (tp > 1558) {
+ strcpy(symbol->errtxt, "520: Data too long to fit in symbol");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ } /* while */
+
+ /* Add length and randomising algorithm to b256 */
+ i = 0;
+ while (i < tp) {
+ if (binary[i] == 'b') {
+ if ((i == 0) || (binary[i - 1] != 'b')) {
+ /* start of binary data */
+ int binary_count; /* length of b256 data */
+
+ for (binary_count = 0; binary_count + i < tp && 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] = (unsigned char) (temp);
+ } else {
+ target[i] = (unsigned char) (temp - 256);
+ }
+ }
+ }
+
+ *(last_mode) = current_mode;
+ *binlen_p = tp;
+ return 0;
+}
+
+static int dm200encode_remainder(unsigned char target[], int target_length, const unsigned char source[], const size_t inputlen, const int last_mode, const int process_buffer[], const int process_p, const int symbols_left) {
+ int debug = 0;
+
+ switch (last_mode) {
+ case DM_C40:
+ case DM_TEXT:
+ if (process_p == 1) // 1 data character left to encode.
+ {
+ if (symbols_left > 1) {
+ target[target_length] = 254;
+ target_length++; // Unlatch and encode remaining data in ascii.
+ }
+ target[target_length] = source[inputlen - 1] + 1;
+ target_length++;
+ } else if (process_p == 2) // 2 data characters left to encode.
+ {
+ // Pad with shift 1 value (0) and encode as double.
+ int intValue = (1600 * process_buffer[0]) + (40 * process_buffer[1]) + 1; // ie (0 + 1).
+ target[target_length] = (unsigned char) (intValue / 256);
+ target_length++;
+ target[target_length] = (unsigned char) (intValue % 256);
+ target_length++;
+ if (symbols_left > 2) {
+ target[target_length] = 254; // Unlatch
+ target_length++;
+ }
+ } else {
+ if (symbols_left > 0) {
+ target[target_length] = 254; // Unlatch
+ target_length++;
+ }
+ }
+ break;
+
+ case DM_X12:
+ if ((symbols_left == process_p) && (process_p == 1)) {
+ // Unlatch not required!
+ target[target_length] = source[inputlen - 1] + 1;
+ target_length++;
+ } else {
+ target[target_length] = (254);
+ target_length++; // Unlatch.
+
+ if (process_p == 1) {
+ target[target_length] = source[inputlen - 1] + 1;
+ target_length++;
+ }
+
+ if (process_p == 2) {
+ target[target_length] = source[inputlen - 2] + 1;
+ target_length++;
+ target[target_length] = source[inputlen - 1] + 1;
+ target_length++;
+ }
+ }
+ break;
+
+ case DM_EDIFACT:
+ if (symbols_left <= 2) // Unlatch not required!
+ {
+ if (process_p == 1) {
+ target[target_length] = source[inputlen - 1] + 1;
+ target_length++;
+ }
+
+ if (process_p == 2) {
+ target[target_length] = source[inputlen - 2] + 1;
+ target_length++;
+ target[target_length] = source[inputlen - 1] + 1;
+ target_length++;
+ }
+ } else {
+ // Append edifact unlatch value (31) and empty buffer
+ if (process_p == 0) {
+ target[target_length] = (unsigned char) (31 << 2);
+ target_length++;
+ }
+
+ if (process_p == 1) {
+ target[target_length] = (unsigned char) ((process_buffer[0] << 2) + ((31 & 0x30) >> 4));
+ target_length++;
+ target[target_length] = (unsigned char) ((31 & 0x0f) << 4);
+ target_length++;
+ }
+
+ if (process_p == 2) {
+ target[target_length] = (unsigned char) ((process_buffer[0] << 2) + ((process_buffer[1] & 0x30) >> 4));
+ target_length++;
+ target[target_length] = (unsigned char) (((process_buffer[1] & 0x0f) << 4) + ((31 & 0x3c) >> 2));
+ target_length++;
+ target[target_length] = (unsigned char) (((31 & 0x03) << 6));
+ target_length++;
+ }
+
+ if (process_p == 3) {
+ target[target_length] = (unsigned char) ((process_buffer[0] << 2) + ((process_buffer[1] & 0x30) >> 4));
+ target_length++;
+ target[target_length] = (unsigned char) (((process_buffer[1] & 0x0f) << 4) + ((process_buffer[2] & 0x3c) >> 2));
+ target_length++;
+ target[target_length] = (unsigned char) (((process_buffer[2] & 0x03) << 6) + 31);
+ target_length++;
+ }
+ }
+ break;
+ }
+
+ if (debug) {
+ int i;
+ printf("\n\n");
+ for (i = 0; i < target_length; i++)
+ printf("%03d ", target[i]);
+
+ printf("\n");
+ }
+
+ return target_length;
+}
+
+/* add pad bits */
+static void add_tail(unsigned char target[], int tp, const int tail_length) {
+ int i, prn, temp;
+
+ 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] = (unsigned char) (temp);
+ tp++;
+ } else {
+ target[tp] = (unsigned char) (temp - 254);
+ tp++;
+ }
+ }
+ }
+}
+
+static int data_matrix_200(struct zint_symbol *symbol,const unsigned char source[], const size_t in_length) {
+ int i, skew = 0;
+ size_t inputlen = in_length;
+ unsigned char binary[2200];
+ int binlen;
+ int process_buffer[8]; /* holds remaining data to finalised */
+ int process_p; /* number of characters left to finalise */
+ int symbolsize, optionsize, calcsize;
+ int taillength, error_number = 0;
+ int H, W, FH, FW, datablock, bytes, rsblock;
+ int last_mode = DM_ASCII;
+ int symbols_left;
+
+ /* inputlen may be decremented by 2 if macro character is used */
+ error_number = dm200encode(symbol, source, binary, &last_mode, &inputlen, process_buffer, &process_p, &binlen);
+ if (error_number != 0) {
+ return error_number;
+ }
+
+ if ((symbol->option_2 >= 1) && (symbol->option_2 <= DMSIZESCOUNT)) {
+ optionsize = intsymbol[symbol->option_2 - 1];
+ } else {
+ optionsize = -1;
+ }
+
+ calcsize = DMSIZESCOUNT - 1;
+ for (i = DMSIZESCOUNT - 1; i > -1; i--) {
+ if (matrixbytes[i] >= (binlen + process_p)) {
+ // Allow for the remaining data characters
+ calcsize = i;
+ }
+ }
+
+ if (optionsize == -1) {
+ // We are in automatic size mode as the exact symbol size was not given
+ // Now check the detailed search options square only or no dmre
+ if (symbol->option_3 == DM_SQUARE) {
+ /* Skip rectangular symbols in square only mode */
+ while (matrixH[calcsize] != matrixW[calcsize]) {
+ calcsize++;
+ }
+ } else if (symbol->option_3 != DM_DMRE) {
+ /* Skip DMRE symbols in no dmre mode */
+ while (isDMRE[calcsize]) {
+ calcsize++;
+ }
+ }
+ symbolsize = calcsize;
+ } else {
+ // The symbol size was given by --ver (option_2)
+ // Thus check if the data fits into this symbol size and use this size
+ if (calcsize > optionsize) {
+ strcpy(symbol->errtxt, "522: Input too long for selected symbol size");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ symbolsize = optionsize;
+ }
+
+ // Now we know the symbol size we can handle the remaining data in the process buffer.
+ symbols_left = matrixbytes[symbolsize] - binlen;
+ binlen = dm200encode_remainder(binary, binlen, source, inputlen, last_mode, process_buffer, process_p, symbols_left);
+
+ if (binlen > matrixbytes[symbolsize]) {
+ strcpy(symbol->errtxt, "523: Data too long to fit in symbol");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ 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);
+ }
+
+ // ecc code
+ if (symbolsize == INTSYMBOL144) {
+ skew = 1;
+ }
+ ecc200(binary, bytes, datablock, rsblock, skew);
+ // Print Codewords
+#ifdef DEBUG
+ {
+ int CWCount;
+ int posCur;
+ if (skew)
+ CWCount = 1558 + 620;
+ else
+ CWCount = bytes + rsblock * (bytes / datablock);
+ printf("Codewords (%i):", CWCount);
+ for (posCur = 0; posCur < CWCount; posCur++)
+ printf(" %3i", binary[posCur]);
+ puts("\n");
+ }
+#endif
+ { // placement
+ int x, y, NC, NR, *places;
+ unsigned char *grid;
+ 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;
+ }
+#ifdef DEBUG
+ // Print position matrix as in standard
+ for (y = NR - 1; y >= 0; y--) {
+ for (x = 0; x < NC; x++) {
+ int v;
+ if (x != 0)
+ fprintf(stderr, "|");
+ v = places[(NR - y - 1) * NC + x];
+ fprintf(stderr, "%3d.%2d", (v >> 3), 8 - (v & 7));
+ }
+ fprintf(stderr, "\n");
+ }
+#endif
+ 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;
+}
+
+INTERNAL int dmatrix(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length) {
+ int error_number;
+
+ if (symbol->option_1 <= 1) {
+ /* ECC 200 */
+ error_number = data_matrix_200(symbol, source, in_length);
+ } else {
+ /* ECC 000 - 140 */
+ strcpy(symbol->errtxt, "524: Older Data Matrix standards are no longer supported");
+ error_number = ZINT_ERROR_INVALID_OPTION;
+ }
+
+ return error_number;
+}
diff --git a/backend/dmatrix.h b/backend/dmatrix.h
new file mode 100644
index 0000000..ef39825
--- /dev/null
+++ b/backend/dmatrix.h
@@ -0,0 +1,248 @@
+/* dmatrix.h - Handles Data Matrix ECC 200 */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2009-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/*
+ Containes Extended Rectangular Data Matrix (DMRE)
+ See http://www.dmre.info for information
+ Contact: harald.oehlmann@eurodatacouncil.org
+ */
+
+#ifndef __DMATRIX_H
+#define __DMATRIX_H
+
+#define MAXBARCODE 3116
+
+#define DM_NULL 0
+#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 const char 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 const char 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 const char 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 const char 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
+};
+
+// Position in option array [symbol option value - 1]
+// The position in the option array is by increasing total data codewords with square first
+// The last comment value is the total data codewords value.
+// The index of this array is the --vers parameter value -1 and is given as first comment value
+
+static const unsigned short int intsymbol[] = {
+/* Standard DM */
+ 0, /* 1: 10x10 , 3*/ 1, /* 2: 12x12 , 5*/ 3, /* 3: 14x14 , 8*/ 5, /* 4: 16x16 , 12*/
+ 7, /* 5: 18x18 , 18*/ 9, /* 6: 20x20 , 22*/ 12, /* 7: 22x22 , 30*/ 15, /* 8: 24x24 , 36*/
+ 18, /* 9: 26x26 , 44*/ 23, /* 10: 32x32 , 62*/ 31, /* 11: 36x36 , 86*/ 34, /* 12: 40x40 ,114*/
+ 36, /* 13: 44x44 ,144*/ 37, /* 14: 48x48 ,174*/ 38, /* 15: 52x52 ,204*/ 39, /* 16: 64x64 ,280*/
+ 40, /* 17: 72x72 ,368*/ 41, /* 18: 80x80 ,456*/ 42, /* 19: 88x88 ,576*/ 43, /* 20: 96x96 ,696*/
+ 44, /* 21:104x104,816*/ 45, /* 22:120x120,1050*/46, /* 23:132x132,1304*/47, /* 24:144x144,1558*/
+ 2, /* 25: 8x18 , 5*/ 4, /* 26: 8x32 , 10*/ 6, /* 27: 12x26 , 16*/ 10, /* 28: 12x36 , 22*/
+ 13, /* 29: 16x36 , 32*/ 20, /* 30: 16x48 , 49*/
+/* DMRE */
+ 8, /* 31: 8x48 , 18*/ 11, /* 32: 8x64 , 24*/ 14, /* 33: 8x80 , 32*/ 16, /* 34: 8x96 , 38*/
+ 21, /* 35: 8x120, 49*/ 25, /* 36: 8x144, 63*/ 17, /* 37: 12x64 , 43*/ 26, /* 38: 12x88 , 64*/
+ 24, /* 39: 16x64 , 62*/ 19, /* 40: 20x36 , 44*/ 22, /* 41: 20x44 , 56*/ 30, /* 42: 20x64 , 84*/
+ 28, /* 43: 22x48 , 72*/ 29, /* 44: 24x48 , 80*/ 33, /* 45: 24x64 ,108*/ 27, /* 46: 26x40 , 70*/
+ 32, /* 47: 26x48 , 90*/ 35, /* 48: 26x64 ,118*/
+ 0
+};
+
+// Number of DM Sizes
+#define DMSIZESCOUNT 48
+// Number of 144x144 for special interlace
+#define INTSYMBOL144 47
+
+// Is the current code a DMRE code ?
+// This is the case, if intsymbol index >= 30
+
+static const char isDMRE[] = {
+ /* 0*/ 0, /* 10x10, 3*/ 0, /* 12x12 , 5*/ 0, /* 8x18 , 5*/ 0, /* 14x14 , 8*/
+ /* 4*/ 0, /* 8x32 , 10*/ 0, /* 16x16 , 12*/ 0, /* 12x26 , 16*/ 0, /* 18x18 , 18*/
+ /* 8*/ 1, /* 8x48 , 18*/ 0, /* 20x20 , 22*/ 0, /* 12x36 , 22*/ 1, /* 8x64 , 24*/
+ /*12*/ 0, /* 22x22 , 30*/ 0, /* 16x36 , 32*/ 1, /* 8x80 , 32*/ 0, /* 24x24 , 36*/
+ /*16*/ 1, /* 8x96 , 38*/ 1, /* 12x64 , 43*/ 0, /* 26x26 , 44*/ 1, /* 20x36 , 44*/
+ /*20*/ 0, /* 16x48 , 49*/ 1, /* 8x120, 49*/ 1, /* 20x44 , 56*/ 0, /* 32x32 , 62*/
+ /*24*/ 1, /* 16x64 , 62*/ 1, /* 8x144, 63*/ 1, /* 12x88 , 64*/ 1, /* 26x40 , 70*/
+ /*28*/ 1, /* 22x48 , 72*/ 1, /* 24x48 , 80*/ 1, /* 20x64 , 84*/ 0, /* 36x36 , 86*/
+ /*32*/ 1, /* 26x48 , 90*/ 1, /* 24x64 ,108*/ 0, /* 40x40 ,114*/ 1, /* 26x64 ,118*/
+ /*36*/ 0, /* 44x44 ,144*/ 0, /* 48x48 ,174*/ 0, /* 52x52 ,204*/ 0, /* 64x64 ,280*/
+ /*40*/ 0, /* 72x72 ,368*/ 0, /* 80x80 ,456*/ 0, /* 88x88 ,576*/ 0, /* 96x96 ,696*/
+ /*44*/ 0, /*104x104,816*/ 0, /*120x120,1050*/0, /*132x132,1304*/0 /*144x144,1558*/
+};
+
+// Horizontal matrix size
+
+static const unsigned short int matrixH[] = {
+ /* 0*/ 10, /* 10x10 , 3*/ 12, /* 12x12 , 5 */ 8, /* 8x18 , 5*/ 14, /* 14x14 , 8*/
+ /* 4*/ 8, /* 8x32 , 10*/ 16, /* 16x16 , 12*/ 12, /* 12x26 , 16*/ 18, /* 18x18 , 18*/
+ /* 8*/ 8, /* 8x48 , 18*/ 20, /* 20x20 , 22*/ 12, /* 12x36 , 22*/ 8, /* 8x64 , 24*/
+ /*12*/ 22, /* 22x22 , 30*/ 16, /* 16x36 , 32*/ 8, /* 8x80 , 32*/ 24, /* 24x24 , 36*/
+ /*16*/ 8, /* 8x96 , 38*/ 12, /* 12x64 , 43*/ 26, /* 26x26 , 44*/ 20, /* 20x36 , 44*/
+ /*20*/ 16, /* 16x48 , 49*/ 8, /* 8x120, 49*/ 20, /* 20x44 , 56*/ 32, /* 32x32 , 62*/
+ /*24*/ 16, /* 16x64 , 62*/ 8, /* 8x144, 63*/ 12, /* 12x88 , 64*/ 26, /* 26x40 , 70*/
+ /*28*/ 22, /* 22x48 , 72*/ 24, /* 24x48 , 80*/ 20, /* 20x64 , 84*/ 36, /* 36x36 , 86*/
+ /*32*/ 26, /* 26x48 , 90*/ 24, /* 24x64 ,108*/ 40, /* 40x40 ,114*/ 26, /* 26x64 ,118*/
+ /*36*/ 44, /* 44x44 ,144*/ 48, /* 48x48 ,174*/ 52, /* 52x52 ,204*/ 64, /* 64x64 ,280*/
+ /*40*/ 72, /* 72x72 ,368*/ 80, /* 80x80 ,456*/ 88, /* 88x88 ,576*/ 96, /* 96x96 ,696*/
+ /*44*/104, /*104x104,816*/ 120,/*120x120,1050*/132,/*132x132,1304*/144 /*144x144,1558*/
+};
+
+// Vertical matrix sizes
+
+static const unsigned short int matrixW[] = {
+ /* 0*/ 10, /* 10x10 */ 12, /* 12x12 */ 18, /* 8x18 */ 14, /* 14x14 */
+ /* 4*/ 32, /* 8x32 */ 16, /* 16x16 */ 26, /* 12x26 */ 18, /* 18x18 */
+ /* 8*/ 48, /* 8x48 */ 20, /* 20x20 */ 36, /* 12x36 */ 64, /* 8x64 */
+ /*12*/ 22, /* 22x22 */ 36, /* 16x36 */ 80, /* 8x80 */ 24, /* 24x24 */
+ /*16*/ 96, /* 8x96 */ 64, /* 12x64 */ 26, /* 26x26 */ 36, /* 20x36 */
+ /*20*/ 48, /* 16x48 */120, /* 8x120*/ 44, /* 20x44 */ 32, /* 32x32 */
+ /*24*/ 64, /* 16x64 */144, /* 8x144*/ 88, /* 12x88 */ 40, /* 26x40 */
+ /*28*/ 48, /* 22x48 */ 48, /* 24x48 */ 64, /* 20x64 */ 36, /* 36x36 */
+ /*32*/ 48, /* 26x48 */ 64, /* 24x64 */ 40, /* 40x40 */ 64, /* 26x64 */
+ /*36*/ 44, /* 44x44 */ 48, /* 48x48 */ 52, /* 52x52 */ 64, /* 64x64 */
+ /*40*/ 72, /* 72x72 */ 80, /* 80x80 */ 88, /* 88x88 */ 96, /* 96x96 */
+ /*44*/104, /*104x104*/120, /*120x120*/ 132, /*132x132*/144 /*144x144*/
+
+};
+
+// Horizontal submodule size (including subfinder)
+
+static const unsigned short int matrixFH[] = {
+ /* 0*/ 10, /* 10x10 */ 12, /* 12x12 */ 8, /* 8x18 */ 14, /* 14x14 */
+ /* 4*/ 8, /* 8x32 */ 16, /* 16x16 */ 12, /* 12x26 */ 18, /* 18x18 */
+ /* 8*/ 8, /* 8x48 */ 20, /* 20x20 */ 12, /* 12x36 */ 8, /* 8x64 */
+ /*12*/ 22, /* 22x22 */ 16, /* 16x36 */ 8, /* 8x80 */ 24, /* 24x24 */
+ /*16*/ 8, /* 8x96 */ 12, /* 12x64 */ 26, /* 26x26 */ 20, /* 20x36 */
+ /*20*/ 16, /* 16x48 */ 8, /* 8x120*/ 20, /* 20x44 */ 16, /* 32x32 */
+ /*24*/ 16, /* 16x64 */ 8, /* 8x144*/ 12, /* 12x88 */ 26, /* 26x40 */
+ /*28*/ 22, /* 22x48 */ 24, /* 24x48 */ 20, /* 20x64 */ 18, /* 36x36 */
+ /*32*/ 26, /* 26x48 */ 24, /* 24x64 */ 20, /* 40x40 */ 26, /* 26x64 */
+ /*36*/ 22, /* 44x44 */ 24, /* 48x48 */ 26, /* 52x52 */ 16, /* 64x64 */
+ /*40*/ 18, /* 72x72 */ 20, /* 80x80 */ 22, /* 88x88 */ 24, /* 96x96 */
+ /*44*/ 26, /*104x104*/ 20, /*120x120*/ 22, /*132x132*/ 24 /*144x144*/
+};
+
+// Vertical submodule size (including subfinder)
+
+static const unsigned short int matrixFW[] = {
+ /* 0*/ 10, /* 10x10 */ 12, /* 12x12 */ 18, /* 8x18 */ 14, /* 14x14 */
+ /* 4*/ 16, /* 8x32 */ 16, /* 16x16 */ 26, /* 12x26 */ 18, /* 18x18 */
+ /* 8*/ 24, /* 8x48 */ 20, /* 20x20 */ 18, /* 12x36 */ 16, /* 8x64 */
+ /*12*/ 22, /* 22x22 */ 18, /* 16x36 */ 20, /* 8x80 */ 24, /* 24x24 */
+ /*16*/ 24, /* 8x96 */ 16, /* 12x64 */ 26, /* 26x26 */ 18, /* 20x36 */
+ /*20*/ 24, /* 16x48 */ 20, /* 8x120*/ 22, /* 20x44 */ 16, /* 32x32 */
+ /*24*/ 16, /* 16x64 */ 24, /* 8x144*/ 22, /* 12x88 */ 20, /* 26x40 */
+ /*28*/ 24, /* 22x48 */ 24, /* 24x48 */ 16, /* 20x64 */ 18, /* 36x36 */
+ /*32*/ 24, /* 26x48 */ 16, /* 24x64 */ 20, /* 40x40 */ 16, /* 26x64 */
+ /*36*/ 22, /* 44x44 */ 24, /* 48x48 */ 26, /* 52x52 */ 16, /* 64x64 */
+ /*40*/ 18, /* 72x72 */ 20, /* 80x80 */ 22, /* 88x88 */ 24, /* 96x96 */
+ /*44*/ 26, /*104x104*/ 20, /*120x120*/ 22, /*132x132*/ 24 /*144x144*/
+};
+
+// Total Data Codewords
+
+static const unsigned short int matrixbytes[] = {
+ /* 0*/ 3, /* 10x10 */ 5, /* 12x12 */ 5, /* 8x18 */ 8, /* 14x14 */
+ /* 4*/ 10, /* 8x32 */ 12, /* 16x16 */ 16, /* 12x26 */ 18, /* 18x18 */
+ /* 8*/ 18, /* 8x48 */ 22, /* 20x20 */ 22, /* 12x36 */ 24, /* 8x64 */
+ /*12*/ 30, /* 22x22 */ 32, /* 16x36 */ 32, /* 8x80 */ 36, /* 24x24 */
+ /*16*/ 38, /* 8x96 */ 43, /* 12x64 */ 44, /* 26x26 */ 44, /* 20x36 */
+ /*20*/ 49, /* 16x48 */ 49, /* 8x120*/ 56, /* 20x44 */ 62, /* 32x32 */
+ /*24*/ 62, /* 16x64 */ 63, /* 8x144*/ 64, /* 12x88 */ 70, /* 26x40 */
+ /*28*/ 72, /* 22x48 */ 80, /* 24x48 */ 84, /* 20x64 */ 86, /* 36x36 */
+ /*32*/ 90, /* 26x48 */ 108, /* 24x64 */ 114, /* 40x40 */ 118, /* 26x64 */
+ /*36*/ 144, /* 44x44 */ 174, /* 48x48 */ 204, /* 52x52 */ 280, /* 64x64 */
+ /*40*/ 368, /* 72x72 */ 456, /* 80x80 */ 576, /* 88x88 */ 696, /* 96x96 */
+ /*44*/ 816, /*104x104*/1050, /*120x120*/1304, /*132x132*/1558 /*144x144*/
+};
+
+// Data Codewords per RS-Block
+
+static const unsigned short int matrixdatablock[] = {
+ /* 0*/ 3, /* 10x10 */ 5, /* 12x12 */ 5, /* 8x18 */ 8, /* 14x14 */
+ /* 4*/ 10, /* 8x32 */ 12, /* 16x16 */ 16, /* 12x26 */ 18, /* 18x18 */
+ /* 8*/ 18, /* 8x48 */ 22, /* 20x20 */ 22, /* 12x36 */ 24, /* 8x64 */
+ /*12*/ 30, /* 22x22 */ 32, /* 16x36 */ 32, /* 8x80 */ 36, /* 24x24 */
+ /*16*/ 38, /* 8x96 */ 43, /* 12x64 */ 44, /* 26x26 */ 44, /* 20x36 */
+ /*20*/ 49, /* 16x48 */ 49, /* 8x120*/ 56, /* 20x44 */ 62, /* 32x32 */
+ /*24*/ 62, /* 16x64 */ 63, /* 8x144*/ 64, /* 12x88 */ 70, /* 26x40 */
+ /*28*/ 72, /* 22x48 */ 80, /* 24x48 */ 84, /* 20x64 */ 86, /* 36x36 */
+ /*32*/ 90, /* 26x48 */ 108, /* 24x64 */ 114, /* 40x40 */ 118, /* 26x64 */
+ /*36*/ 144, /* 44x44 */ 174, /* 48x48 */ 102, /* 52x52 */ 140, /* 64x64 */
+ /*40*/ 92, /* 72x72 */ 114, /* 80x80 */ 144, /* 88x88 */ 174, /* 96x96 */
+ /*44*/ 136, /*104x104*/ 175, /*120x120*/ 163, /*132x132*/ 156 /* 144x144*/
+};
+
+// ECC Codewords per RS-Block
+
+static const unsigned short int matrixrsblock[] = {
+ /* 0*/ 5, /* 10x10 */ 7, /* 12x12 */ 7, /* 8x18 */ 10, /* 14x14 */
+ /* 4*/ 11, /* 8x32 */ 12, /* 16x16 */ 14, /* 12x26 */ 14, /* 18x18 */
+ /* 8*/ 15, /* 8x48 */ 18, /* 20x20 */ 18, /* 12x36 */ 18, /* 8x64 */
+ /*12*/ 20, /* 22x22 */ 24, /* 16x36 */ 22, /* 8x80 */ 24, /* 24x24 */
+ /*16*/ 28, /* 8x96 */ 27, /* 12x64 */ 28, /* 26x26 */ 28, /* 20x36 */
+ /*20*/ 28, /* 16x48 */ 32, /* 8x120*/ 34, /* 20x44 */ 36, /* 32x32 */
+ /*24*/ 36, /* 16x64 */ 36, /* 8x144*/ 36, /* 12x88 */ 38, /* 26x40 */
+ /*28*/ 38, /* 22x48 */ 41, /* 24x48 */ 42, /* 20x64 */ 42, /* 36x36 */
+ /*32*/ 42, /* 26x48 */ 46, /* 24x64 */ 48, /* 40x40 */ 50, /* 26x64 */
+ /*36*/ 56, /* 44x44 */ 68, /* 48x48 */ 42, /* 52x52 */ 56, /* 64x64 */
+ /*40*/ 36, /* 72x72 */ 48, /* 80x80 */ 56, /* 88x88 */ 68, /* 96x96 */
+ /*44*/ 56, /*104x104*/ 68, /*120x120*/ 62, /*132x132*/ 62 /*144x144*/
+};
+
+#endif /* __DMATRIX_H */
diff --git a/backend/dotcode.c b/backend/dotcode.c
new file mode 100644
index 0000000..78f3914
--- /dev/null
+++ b/backend/dotcode.c
@@ -0,0 +1,1569 @@
+/* dotcode.c - Handles DotCode */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2017-2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/*
+ * Attempts to encode DotCode according to (AIMD013) ISS DotCode Rev. 4.0, DRAFT 0.15, TSC Pre-PR #5, dated May 28, 2019
+ * Incorporating suggestions from Terry Burton at BWIPP
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#ifndef _MSC_VER
+#include <stdint.h>
+#else
+#include "ms_stdint.h"
+#include <malloc.h>
+#endif
+#include "common.h"
+#include "gs1.h"
+
+#define GF 113
+#define PM 3
+#define SCORE_UNLIT_EDGE -99999
+
+/* DotCode symbol character dot patterns, from Annex C */
+static const unsigned short int dot_patterns[113] = {
+ 0x155, 0x0ab, 0x0ad, 0x0b5, 0x0d5, 0x156, 0x15a, 0x16a, 0x1aa, 0x0ae,
+ 0x0b6, 0x0ba, 0x0d6, 0x0da, 0x0ea, 0x12b, 0x12d, 0x135, 0x14b, 0x14d,
+ 0x153, 0x159, 0x165, 0x169, 0x195, 0x1a5, 0x1a9, 0x057, 0x05b, 0x05d,
+ 0x06b, 0x06d, 0x075, 0x097, 0x09b, 0x09d, 0x0a7, 0x0b3, 0x0b9, 0x0cb,
+ 0x0cd, 0x0d3, 0x0d9, 0x0e5, 0x0e9, 0x12e, 0x136, 0x13a, 0x14e, 0x15c,
+ 0x166, 0x16c, 0x172, 0x174, 0x196, 0x19a, 0x1a6, 0x1ac, 0x1b2, 0x1b4,
+ 0x1ca, 0x1d2, 0x1d4, 0x05e, 0x06e, 0x076, 0x07a, 0x09e, 0x0bc, 0x0ce,
+ 0x0dc, 0x0e6, 0x0ec, 0x0f2, 0x0f4, 0x117, 0x11b, 0x11d, 0x127, 0x133,
+ 0x139, 0x147, 0x163, 0x171, 0x18b, 0x18d, 0x193, 0x199, 0x1a3, 0x1b1,
+ 0x1c5, 0x1c9, 0x1d1, 0x02f, 0x037, 0x03b, 0x03d, 0x04f, 0x067, 0x073,
+ 0x079, 0x08f, 0x0c7, 0x0e3, 0x0f1, 0x11e, 0x13c, 0x178, 0x18e, 0x19c,
+ 0x1b8, 0x1c6, 0x1cc
+};
+
+// Printed() routine from Annex A adapted to char array of ASCII 1's and 0's
+static int get_dot(char Dots[], const int Hgt, const int Wid, const int x, const int y) {
+ int retval = 0;
+
+ if ((x >= 0) && (x < Wid) && (y >= 0) && (y < Hgt)) {
+ if (Dots[(y * Wid) + x] == '1') {
+ retval = 1;
+ }
+ }
+
+ return retval;
+}
+
+static int clr_col(char *Dots, const int Hgt, const int Wid, const int x) {
+ int y;
+ for (y = x & 1; y < Hgt; y += 2) {
+ if (get_dot(Dots, Hgt, Wid, x, y)) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static int clr_row(char *Dots, const int Hgt, const int Wid, const int y) {
+ int x;
+ for (x = y & 1; x < Wid; x += 2) {
+ if (get_dot(Dots, Hgt, Wid, x, y)) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+// calc penalty for empty interior columns
+static int col_penalty(char *Dots, int Hgt, int Wid) {
+ int x, penalty = 0, penalty_local = 0;
+
+ for (x = 1; x < Wid - 1; x++) {
+ if (clr_col(Dots, Hgt, Wid, x)) {
+ if (penalty_local == 0) {
+ penalty_local = Hgt;
+ } else {
+ penalty_local *= Hgt;
+ }
+ } else {
+ if (penalty_local) {
+ penalty += penalty_local;
+ penalty_local = 0;
+ }
+ }
+ }
+
+ return penalty + penalty_local;
+}
+
+// calc penalty for empty interior rows
+static int row_penalty(char *Dots, int Hgt, int Wid) {
+ int y, penalty = 0, penalty_local = 0;
+
+ for (y = 1; y < Hgt - 1; y++) {
+ if (clr_row(Dots, Hgt, Wid, y)) {
+ if (penalty_local == 0) {
+ penalty_local = Wid;
+ } else {
+ penalty_local *= Wid;
+ }
+ } else {
+ if (penalty_local) {
+ penalty += penalty_local;
+ penalty_local = 0;
+ }
+ }
+ }
+
+ return penalty + penalty_local;
+}
+
+/* Dot pattern scoring routine from Annex A */
+static int score_array(char Dots[], int Hgt, int Wid) {
+ int x, y, worstedge, first, last, sum;
+ int penalty = 0;
+
+ // first, guard against "pathelogical" gaps in the array
+ // subtract a penalty score for empty rows/columns from total code score for each mask,
+ // where the penalty is Sum(N ^ n), where N is the number of positions in a column/row,
+ // and n is the number of consecutive empty rows/columns
+ penalty = row_penalty(Dots, Hgt, Wid) + col_penalty(Dots, Hgt, Wid);
+
+ sum = 0;
+ first = -1;
+ last = -1;
+
+ // across the top edge, count printed dots and measure their extent
+ for (x = 0; x < Wid; x += 2) {
+ if (get_dot(Dots, Hgt, Wid, x, 0)) {
+ if (first < 0) {
+ first = x;
+ }
+ last = x;
+ sum++;
+ }
+ }
+ if (sum == 0) {
+ return SCORE_UNLIT_EDGE; // guard against empty top edge
+ }
+
+ worstedge = sum + last - first;
+ worstedge *= Hgt;
+
+ sum = 0;
+ first = -1;
+ last = -1;
+
+ // across the bottom edge, ditto
+ for (x = Wid & 1; x < Wid; x += 2) {
+ if (get_dot(Dots, Hgt, Wid, x, Hgt - 1)) {
+ if (first < 0) {
+ first = x;
+ }
+ last = x;
+ sum++;
+ }
+ }
+ if (sum == 0) {
+ return SCORE_UNLIT_EDGE; // guard against empty bottom edge
+ }
+
+ sum += last - first;
+ sum *= Hgt;
+ if (sum < worstedge) {
+ worstedge = sum;
+ }
+
+ sum = 0;
+ first = -1;
+ last = -1;
+
+ // down the left edge, ditto
+ for (y = 0; y < Hgt; y += 2) {
+ if (get_dot(Dots, Hgt, Wid, 0, y)) {
+ if (first < 0) {
+ first = y;
+ }
+ last = y;
+ sum++;
+ }
+ }
+ if (sum == 0) {
+ return SCORE_UNLIT_EDGE; // guard against empty left edge
+ }
+
+ sum += last - first;
+ sum *= Wid;
+ if (sum < worstedge) {
+ worstedge = sum;
+ }
+
+ sum = 0;
+ first = -1;
+ last = -1;
+
+ // down the right edge, ditto
+ for (y = Hgt & 1; y < Hgt; y += 2) {
+ if (get_dot(Dots, Hgt, Wid, Wid - 1, y)) {
+ if (first < 0) {
+ first = y;
+ }
+ last = y;
+ sum++;
+ }
+ }
+ if (sum == 0) {
+ return SCORE_UNLIT_EDGE; // guard against empty right edge
+ }
+
+ sum += last - first;
+ sum *= Wid;
+ if (sum < worstedge) {
+ worstedge = sum;
+ }
+
+ // throughout the array, count the # of unprinted 5-somes (cross patterns)
+ // plus the # of printed dots surrounded by 8 unprinted neighbors
+ sum = 0;
+ for (y = 0; y < Hgt; y++) {
+ for (x = y & 1; x < Wid; x += 2) {
+ if ((!get_dot(Dots, Hgt, Wid, x - 1, y - 1))
+ && (!get_dot(Dots, Hgt, Wid, x + 1, y - 1))
+ && (!get_dot(Dots, Hgt, Wid, x - 1, y + 1))
+ && (!get_dot(Dots, Hgt, Wid, x + 1, y + 1))
+ && ((!get_dot(Dots, Hgt, Wid, x, y))
+ || ((!get_dot(Dots, Hgt, Wid, x - 2, y))
+ && (!get_dot(Dots, Hgt, Wid, x, y - 2))
+ && (!get_dot(Dots, Hgt, Wid, x + 2, y))
+ && (!get_dot(Dots, Hgt, Wid, x, y + 2))))) {
+ sum++;
+ }
+ }
+ }
+
+ return (worstedge - sum * sum - penalty);
+}
+
+//-------------------------------------------------------------------------
+// "rsencode(nd,nc)" adds "nc" R-S check words to "nd" data words in wd[]
+// employing Galois Field GF, where GF is prime, with a prime modulus of PM
+//-------------------------------------------------------------------------
+
+static void rsencode(int nd, int nc, unsigned char *wd) {
+ // roots (antilogs): root[0] = 1; for (i = 1; i < GF - 1; i++) root[i] = (PM * root[i - 1]) % GF;
+ static int root[GF - 1] = {
+ 1, 3, 9, 27, 81, 17, 51, 40, 7, 21,
+ 63, 76, 2, 6, 18, 54, 49, 34, 102, 80,
+ 14, 42, 13, 39, 4, 12, 36, 108, 98, 68,
+ 91, 47, 28, 84, 26, 78, 8, 24, 72, 103,
+ 83, 23, 69, 94, 56, 55, 52, 43, 16, 48,
+ 31, 93, 53, 46, 25, 75, 112, 110, 104, 86,
+ 32, 96, 62, 73, 106, 92, 50, 37, 111, 107,
+ 95, 59, 64, 79, 11, 33, 99, 71, 100, 74,
+ 109, 101, 77, 5, 15, 45, 22, 66, 85, 29,
+ 87, 35, 105, 89, 41, 10, 30, 90, 44, 19,
+ 57, 58, 61, 70, 97, 65, 82, 20, 60, 67,
+ 88, 38
+ };
+ int i, j, k, nw, start, step, c[GF];
+
+ // Here we compute how many interleaved R-S blocks will be needed
+ nw = nd + nc;
+ step = (nw + GF - 2) / (GF - 1);
+
+ // ...& then for each such block:
+ for (start = 0; start < step; start++) {
+ int ND = (nd - start + step - 1) / step;
+ int NW = (nw - start + step - 1) / step;
+ int NC = NW - ND;
+
+ // first compute the generator polynomial "c" of order "NC":
+ memset(c, 0, GF * sizeof(int)); // Keep clang-tidy happy (as far as UndefinedBinaryOperatorResult warning below at least)
+
+ c[0] = 1;
+ for (i = 1; i <= NC; i++) {
+ for (j = NC; j >= 1; j--) {
+ c[j] = (GF + c[j] - (root[i] * c[j - 1]) % GF) % GF;
+ }
+ }
+
+ // & then compute the corresponding checkword values into wd[]
+ // ... (a) starting at wd[start] & (b) stepping by step
+ for (i = ND; i < NW; i++) {
+ wd[start + i * step] = 0;
+ }
+ for (i = 0; i < ND; i++) {
+ k = (wd[start + i * step] + wd[start + ND * step]) % GF; // NOLINT wd set 0..(nd - 1) and start + i * step <= nd - 1
+ for (j = 0; j < NC - 1; j++) {
+ wd[start + (ND + j) * step] = (GF - ((c[j + 1] * k) % GF) + wd[start + (ND + j + 1) * step]) % GF;
+ }
+ wd[start + (ND + NC - 1) * step] = (GF - ((c[NC] * k) % GF)) % GF;
+ }
+ for (i = ND; i < NW; i++) {
+ wd[start + i * step] = (GF - wd[start + i * step]) % GF;
+ }
+ }
+}
+
+/* Check if the next character is directly encodable in code set A (Annex F.II.D) */
+static int datum_a(const unsigned char source[], int position, int length) {
+ int retval = 0;
+
+ if (position < length) {
+ if (source[position] <= 95) {
+ retval = 1;
+ }
+ }
+
+ return retval;
+}
+
+/* Check if the next character is directly encodable in code set B (Annex F.II.D). Note changed to return 2 if CR/LF */
+static int datum_b(const unsigned char source[], int position, int length) {
+ int retval = 0;
+
+ if (position < length) {
+ if ((source[position] >= 32) && (source[position] <= 127)) {
+ retval = 1;
+ }
+
+ switch (source[position]) {
+ case 9: // HT
+ case 28: // FS
+ case 29: // GS
+ case 30: // RS
+ retval = 1;
+ }
+
+ if (position + 1 < length) {
+ if ((source[position] == 13) && (source[position + 1] == 10)) { // CRLF
+ retval = 2;
+ }
+ }
+ }
+
+ return retval;
+}
+
+/* Check if the next characters are directly encodable in code set C (Annex F.II.D) */
+static int datum_c(const unsigned char source[], int position, int length) {
+ int retval = 0;
+
+ if (position <= length - 2) {
+ if (((source[position] >= '0') && (source[position] <= '9'))
+ && ((source[position + 1] >= '0') && (source[position + 1] <= '9')))
+ retval = 1;
+ }
+
+ return retval;
+}
+
+/* Returns how many consecutive digits lie immediately ahead (Annex F.II.A) */
+static int n_digits(const unsigned char source[], int position, int length) {
+ int i;
+
+ for (i = position; ((source[i] >= '0') && (source[i] <= '9')) && (i < length); i++);
+
+ return i - position;
+}
+
+/* checks ahead for 10 or more digits starting "17xxxxxx10..." (Annex F.II.B) */
+static int seventeen_ten(const unsigned char source[], int position, int length) {
+ int found = 0;
+
+ if (n_digits(source, position, length) >= 10) {
+ if (((source[position] == '1') && (source[position + 1] == '7'))
+ && ((source[position + 8] == '1') && (source[position + 9] == '0'))) {
+ found = 1;
+ }
+ }
+
+ return found;
+}
+
+/* checks how many characters ahead can be reached while datum_c is true,
+ * returning the resulting number of codewords (Annex F.II.E)
+ */
+static int ahead_c(const unsigned char source[], int position, int length) {
+ int count = 0;
+ int i;
+
+ for (i = position; (i < length) && datum_c(source, i, length); i += 2) {
+ count++;
+ }
+
+ return count;
+}
+
+/* Annex F.II.F */
+static int try_c(const unsigned char source[], int position, int length) {
+ int retval = 0;
+
+ if (n_digits(source, position, length) > 0) {
+ if (ahead_c(source, position, length) > ahead_c(source, position + 1, length)) {
+ retval = ahead_c(source, position, length);
+ }
+ }
+
+ return retval;
+}
+
+/* Annex F.II.G */
+static int ahead_a(const unsigned char source[], int position, int length) {
+ int count = 0;
+ int i;
+
+ for (i = position; ((i < length) && datum_a(source, i, length))
+ && (try_c(source, i, length) < 2); i++) {
+ count++;
+ }
+
+ return count;
+}
+
+/* Annex F.II.H Note: changed to return number of chars encodable. Number of codewords returned in *p_nx. */
+static int ahead_b(const unsigned char source[], int position, int length, int *p_nx) {
+ int count = 0;
+ int i, incr;
+
+ for (i = position; (i < length) && (incr = datum_b(source, i, length))
+ && (try_c(source, i, length) < 2); i += incr) {
+ count++;
+ }
+
+ if (p_nx != NULL) {
+ *p_nx = count;
+ }
+
+ return i - position;
+}
+
+/* checks if the next character is in the range 128 to 255 (Annex F.II.I) */
+static int binary(const unsigned char source[], int length, int position) {
+ int retval = 0;
+
+ if (position < length && source[position] >= 128) {
+ retval = 1;
+ }
+
+ return retval;
+}
+
+/* Analyse input data stream and encode using algorithm from Annex F */
+static int dotcode_encode_message(struct zint_symbol *symbol, const unsigned char source[], int length, unsigned char *codeword_array, int *binary_finish) {
+ static char lead_specials[] = "\x09\x1C\x1D\x1E"; // HT, FS, GS, RS
+
+ int input_position, array_length, i;
+ char encoding_mode;
+ int inside_macro;
+ int debug = (symbol->debug & ZINT_DEBUG_PRINT);
+ int binary_buffer_size = 0;
+ int lawrencium[6]; // Reversed radix 103 values
+ int nx;
+
+#if defined(_MSC_VER) && _MSC_VER == 1200
+ uint64_t binary_buffer = 0;
+#else
+ uint64_t binary_buffer = 0ULL;
+#endif
+
+ input_position = 0;
+ array_length = 0;
+ encoding_mode = 'C';
+ inside_macro = 0;
+
+ if (symbol->output_options & READER_INIT) {
+ codeword_array[array_length] = 109; // FNC3
+ array_length++;
+ }
+
+ if ((symbol->input_mode & 0x07) != GS1_MODE) {
+ if (length > 2) {
+ if (((source[input_position] >= '0') && (source[input_position] <= '9')) &&
+ ((source[input_position + 1] >= '0') && (source[input_position + 1] <= '9'))) {
+ codeword_array[array_length] = 107; // FNC1
+ array_length++;
+ }
+ }
+ }
+
+ if (symbol->eci > 0) {
+ codeword_array[array_length] = 108; // FNC2
+ array_length++;
+ if (symbol->eci <= 39) {
+ codeword_array[array_length] = symbol->eci;
+ array_length++;
+ } else {
+ // the next three codewords valued A, B & C encode the ECI value of
+ // (A - 40) * 12769 + B * 113 + C + 40 (Section 5.2.1)
+ int a, b, c;
+ a = (symbol->eci - 40) / 12769;
+ b = ((symbol->eci - 40) - (12769 * a)) / 113;
+ c = (symbol->eci - 40) - (12769 * a) - (113 * b);
+
+ codeword_array[array_length] = a + 40;
+ array_length++;
+ codeword_array[array_length] = b;
+ array_length++;
+ codeword_array[array_length] = c;
+ array_length++;
+ }
+ }
+
+ // Prevent encodation as a macro if a special character is in first position
+ if (strchr(lead_specials, source[input_position]) != NULL) {
+ codeword_array[array_length] = 101; // Latch A
+ array_length++;
+ codeword_array[array_length] = source[input_position] + 64;
+ array_length++;
+ encoding_mode = 'A';
+ input_position++;
+ }
+
+ while (input_position < length) {
+ int done = 0;
+ /* Step A */
+ if ((input_position == length - 2) && (inside_macro != 0) && (inside_macro != 100)) {
+ // inside_macro only gets set to 97, 98 or 99 if the last two characters are RS/EOT
+ input_position += 2;
+ done = 1;
+ if (debug) {
+ printf("A ");
+ }
+ }
+
+ /* Step B */
+ if ((input_position == length - 1) && (inside_macro == 100)) {
+ // inside_macro only gets set to 100 if the last character is EOT
+ input_position++;
+ done = 1;
+ if (debug) {
+ printf("B ");
+ }
+ }
+
+ /* Step C1 */
+ if ((!done) && (encoding_mode == 'C')) {
+ if ((array_length == 0) && (length > 6)) {
+ if ((source[input_position] == '[')
+ && (source[input_position + 1] == ')')
+ && (source[input_position + 2] == '>')
+ && (source[input_position + 3] == 30) // RS
+ && (source[length - 1] == 4)) { // EOT
+
+
+ if ((source[input_position + 6] == 29) && (source[length - 2] == 30)) { // GS/RS
+ if ((source[input_position + 4] == '0') && (source[input_position + 5] == '5')) {
+ codeword_array[array_length] = 106; // Latch B
+ array_length++;
+ encoding_mode = 'B';
+ codeword_array[array_length] = 97; // Macro
+ array_length++;
+ input_position += 7;
+ inside_macro = 97;
+ done = 1;
+ if (debug) {
+ printf("C1/1 ");
+ }
+ }
+
+ if ((!done) && (source[input_position + 4] == '0') && (source[input_position + 5] == '6')) {
+ codeword_array[array_length] = 106; // Latch B
+ array_length++;
+ encoding_mode = 'B';
+ codeword_array[array_length] = 98; // Macro
+ array_length++;
+ input_position += 7;
+ inside_macro = 98;
+ done = 1;
+ if (debug) {
+ printf("C1/2 ");
+ }
+ }
+
+ if ((!done) && (source[input_position + 4] == '1') && (source[input_position + 5] == '2')) {
+ codeword_array[array_length] = 106; // Latch B
+ array_length++;
+ encoding_mode = 'B';
+ codeword_array[array_length] = 99; // Macro
+ array_length++;
+ input_position += 7;
+ inside_macro = 99;
+ done = 1;
+ if (debug) {
+ printf("C1/3 ");
+ }
+ }
+ }
+
+ if ((!done) && (source[input_position + 4] >= '0') && (source[input_position + 4] <= '9') &&
+ (source[input_position + 5] >= '0') && (source[input_position + 5] <= '9')) {
+ codeword_array[array_length] = 106; // Latch B
+ array_length++;
+ encoding_mode = 'B';
+ codeword_array[array_length] = 100; // Macro
+ array_length++;
+ input_position += 4;
+ inside_macro = 100;
+ done = 1;
+ if (debug) {
+ printf("C1/4 ");
+ }
+ }
+ }
+ }
+ }
+
+ /* Step C2 */
+ if ((!done) && (encoding_mode == 'C')) {
+ if (seventeen_ten(source, input_position, length)) {
+ codeword_array[array_length] = 100; // (17)...(10)
+ array_length++;
+ codeword_array[array_length] = ((source[input_position + 2] - '0') * 10) + (source[input_position + 3] - '0');
+ array_length++;
+ codeword_array[array_length] = ((source[input_position + 4] - '0') * 10) + (source[input_position + 5] - '0');
+ array_length++;
+ codeword_array[array_length] = ((source[input_position + 6] - '0') * 10) + (source[input_position + 7] - '0');
+ array_length++;
+ input_position += 10;
+ done = 1;
+ if (debug) {
+ printf("C2/1 ");
+ }
+ }
+ }
+
+ if ((!done) && (encoding_mode == 'C')) {
+ if (datum_c(source, input_position, length) || ((source[input_position] == '[') && ((symbol->input_mode & 0x07) == GS1_MODE))) {
+ if (source[input_position] == '[') {
+ codeword_array[array_length] = 107; // FNC1
+ input_position++;
+ } else {
+ codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0');
+ input_position += 2;
+ }
+ array_length++;
+ done = 1;
+ if (debug) {
+ printf("C2/2 ");
+ }
+ }
+ }
+
+ /* Step C3 */
+ if ((!done) && (encoding_mode == 'C')) {
+ if (binary(source, length, input_position)) {
+ if (n_digits(source, input_position + 1, length) > 0) {
+ if ((source[input_position] - 128) < 32) {
+ codeword_array[array_length] = 110; // Upper Shift A
+ array_length++;
+ codeword_array[array_length] = source[input_position] - 128 + 64;
+ array_length++;
+ } else {
+ codeword_array[array_length] = 111; // Upper Shift B
+ array_length++;
+ codeword_array[array_length] = source[input_position] - 128 - 32;
+ array_length++;
+ }
+ input_position++;
+ } else {
+ codeword_array[array_length] = 112; // Bin Latch
+ array_length++;
+ encoding_mode = 'X';
+ }
+ done = 1;
+ if (debug) {
+ printf("C3 ");
+ }
+ }
+ }
+
+ /* Step C4 */
+ if ((!done) && (encoding_mode == 'C')) {
+ int m = ahead_a(source, input_position, length);
+ int n = ahead_b(source, input_position, length, &nx);
+ if (m > n) {
+ codeword_array[array_length] = 101; // Latch A
+ array_length++;
+ encoding_mode = 'A';
+ } else {
+ if (nx >= 1 && nx <= 4) {
+ codeword_array[array_length] = 101 + nx; // nx Shift B
+ array_length++;
+
+ for (i = 0; i < nx; i++) {
+ if (source[input_position] >= 32) {
+ codeword_array[array_length] = source[input_position] - 32;
+ } else if (source[input_position] == 13) { // CR/LF
+ codeword_array[array_length] = 96;
+ input_position++;
+ } else {
+ switch(source[input_position]) {
+ case 9: codeword_array[array_length] = 97; break; // HT
+ case 28: codeword_array[array_length] = 98; break; // FS
+ case 29: codeword_array[array_length] = 99; break; // GS
+ case 30: codeword_array[array_length] = 100; break; // RS
+ }
+ }
+ array_length++;
+ input_position++;
+ }
+ } else {
+ codeword_array[array_length] = 106; // Latch B
+ array_length++;
+ encoding_mode = 'B';
+ }
+ }
+ done = 1;
+ if (debug) {
+ printf("C4 ");
+ }
+ }
+
+ /* Step D1 */
+ if ((!done) && (encoding_mode == 'B')) {
+ int n = try_c(source, input_position, length);
+
+ if (n >= 2) {
+ if (n <= 4) {
+ codeword_array[array_length] = 103 + (n - 2); // nx Shift C
+ array_length++;
+ for (i = 0; i < n; i++) {
+ codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0');
+ array_length++;
+ input_position += 2;
+ }
+ } else {
+ codeword_array[array_length] = 106; // Latch C
+ array_length++;
+ encoding_mode = 'C';
+ }
+ done = 1;
+ if (debug) {
+ printf("D1 ");
+ }
+ }
+ }
+
+ /* Step D2 */
+ if ((!done) && (encoding_mode == 'B')) {
+ if ((source[input_position] == '[') && ((symbol->input_mode & 0x07) == GS1_MODE)) {
+ codeword_array[array_length] = 107; // FNC1
+ array_length++;
+ input_position++;
+ done = 1;
+ if (debug) {
+ printf("D2/1 ");
+ }
+ } else {
+ if (datum_b(source, input_position, length)) {
+
+ if ((source[input_position] >= 32) && (source[input_position] <= 127)) {
+ codeword_array[array_length] = source[input_position] - 32;
+ done = 1;
+
+ } else if (source[input_position] == 13) {
+ /* CR/LF */
+ codeword_array[array_length] = 96;
+ input_position++;
+ done = 1;
+
+ } else if (input_position != 0) {
+ /* HT, FS, GS and RS in the first data position would be interpreted as a macro (see table 2) */
+ switch(source[input_position]) {
+ case 9: // HT
+ codeword_array[array_length] = 97;
+ break;
+ case 28: // FS
+ codeword_array[array_length] = 98;
+ break;
+ case 29: // GS
+ codeword_array[array_length] = 99;
+ break;
+ case 30: // RS
+ codeword_array[array_length] = 100;
+ break;
+ }
+ done = 1;
+ }
+
+ if (done == 1) {
+ array_length++;
+ input_position++;
+ if (debug) {
+ printf("D2/2 ");
+ }
+ }
+ }
+ }
+ }
+
+ /* Step D3 */
+ if ((!done) && (encoding_mode == 'B')) {
+ if (binary(source, length, input_position)) {
+ if (datum_b(source, input_position + 1, length)) {
+ if ((source[input_position] - 128) < 32) {
+ codeword_array[array_length] = 110; // Bin Shift A
+ array_length++;
+ codeword_array[array_length] = source[input_position] - 128 + 64;
+ array_length++;
+ } else {
+ codeword_array[array_length] = 111; // Bin Shift B
+ array_length++;
+ codeword_array[array_length] = source[input_position] - 128 - 32;
+ array_length++;
+ }
+ input_position++;
+ } else {
+ codeword_array[array_length] = 112; // Bin Latch
+ array_length++;
+ encoding_mode = 'X';
+ }
+ done = 1;
+ if (debug) {
+ printf("D3 ");
+ }
+ }
+ }
+
+ /* Step D4 */
+ if ((!done) && (encoding_mode == 'B')) {
+ if (ahead_a(source, input_position, length) == 1) {
+ codeword_array[array_length] = 101; // Shift A
+ array_length++;
+ if (source[input_position] < 32) {
+ codeword_array[array_length] = source[input_position] + 64;
+ } else {
+ codeword_array[array_length] = source[input_position] - 32;
+ }
+ array_length++;
+ input_position++;
+ } else {
+ codeword_array[array_length] = 102; // Latch A
+ array_length++;
+ encoding_mode = 'A';
+ }
+ done = 1;
+ if (debug) {
+ printf("D4 ");
+ }
+ }
+
+ /* Step E1 */
+ if ((!done) && (encoding_mode == 'A')) {
+ int n = try_c(source, input_position, length);
+ if (n >= 2) {
+ if (n <= 4) {
+ codeword_array[array_length] = 103 + (n - 2); // nx Shift C
+ array_length++;
+ for (i = 0; i < n; i++) {
+ codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0');
+ array_length++;
+ input_position += 2;
+ }
+ } else {
+ codeword_array[array_length] = 106; // Latch C
+ array_length++;
+ encoding_mode = 'C';
+ }
+ done = 1;
+ if (debug) {
+ printf("E1 ");
+ }
+ }
+ }
+
+ /* Step E2 */
+ if ((!done) && (encoding_mode == 'A')) {
+ if ((source[input_position] == '[') && ((symbol->input_mode & 0x07) == GS1_MODE)) {
+ // Note: this branch probably never reached as no reason to be in Code Set A for GS1 data
+ codeword_array[array_length] = 107; // FNC1
+ array_length++;
+ input_position++;
+ done = 1;
+ if (debug) {
+ printf("E2/1 ");
+ }
+ } else {
+ if (datum_a(source, input_position, length)) {
+ if (source[input_position] < 32) {
+ codeword_array[array_length] = source[input_position] + 64;
+ } else {
+ codeword_array[array_length] = source[input_position] - 32;
+ }
+ array_length++;
+ input_position++;
+ done = 1;
+ if (debug) {
+ printf("E2/2 ");
+ }
+ }
+ }
+ }
+
+ /* Step E3 */
+ if ((!done) && (encoding_mode == 'A')) {
+ if (binary(source, length, input_position)) {
+ if (datum_a(source, input_position + 1, length)) {
+ if ((source[input_position] - 128) < 32) {
+ codeword_array[array_length] = 110; // Bin Shift A
+ array_length++;
+ codeword_array[array_length] = source[input_position] - 128 + 64;
+ array_length++;
+ } else {
+ codeword_array[array_length] = 111; // Bin Shift B
+ array_length++;
+ codeword_array[array_length] = source[input_position] - 128 - 32;
+ array_length++;
+ }
+ input_position++;
+ } else {
+ codeword_array[array_length] = 112; // Bin Latch
+ array_length++;
+ encoding_mode = 'X';
+ }
+ done = 1;
+ if (debug) {
+ printf("E3 ");
+ }
+ }
+ }
+
+ /* Step E4 */
+ if ((!done) && (encoding_mode == 'A')) {
+ ahead_b(source, input_position, length, &nx);
+
+ if (nx >= 1 && nx <= 6) {
+ codeword_array[array_length] = 95 + nx; // nx Shift B
+ array_length++;
+ for (i = 0; i < nx; i++) {
+ if (source[input_position] >= 32) {
+ codeword_array[array_length] = source[input_position] - 32;
+ } else if (source[input_position] == 13) { // CR/LF
+ codeword_array[array_length] = 96;
+ input_position++;
+ } else {
+ switch(source[input_position]) {
+ case 9: codeword_array[array_length] = 97; break; // HT
+ case 28: codeword_array[array_length] = 98; break; // FS
+ case 29: codeword_array[array_length] = 99; break; // GS
+ case 30: codeword_array[array_length] = 100; break; // RS
+ }
+ }
+ array_length++;
+ input_position++;
+ }
+ } else {
+ codeword_array[array_length] = 102; // Latch B
+ array_length++;
+ encoding_mode = 'B';
+ }
+ done = 1;
+ if (debug) {
+ printf("E4 ");
+ }
+ }
+
+ /* Step F1 */
+ if ((!done) && (encoding_mode == 'X')) {
+ int n = try_c(source, input_position, length);
+
+ if (n >= 2) {
+ /* Empty binary buffer */
+ for (i = 0; i < (binary_buffer_size + 1); i++) {
+ lawrencium[i] = binary_buffer % 103;
+ binary_buffer /= 103;
+ }
+
+ for (i = 0; i < (binary_buffer_size + 1); i++) {
+ codeword_array[array_length] = lawrencium[binary_buffer_size - i];
+ array_length++;
+ }
+ binary_buffer = 0;
+ binary_buffer_size = 0;
+
+ if (n <= 7) {
+ codeword_array[array_length] = 101 + n; // Interrupt for nx Shift C
+ array_length++;
+ for (i = 0; i < n; i++) {
+ codeword_array[array_length] = ((source[input_position] - '0') * 10) + (source[input_position + 1] - '0');
+ array_length++;
+ input_position += 2;
+ }
+ } else {
+ codeword_array[array_length] = 111; // Terminate with Latch to C
+ array_length++;
+ encoding_mode = 'C';
+ }
+ done = 1;
+ if (debug) {
+ printf("F1 ");
+ }
+ }
+ }
+
+ /* Step F2 */
+ /* Section 5.2.1.1 para D.2.i states:
+ * "Groups of six codewords, each valued between 0 and 102, are radix converted from
+ * base 103 into five base 259 values..."
+ */
+ if ((!done) && (encoding_mode == 'X')) {
+ if (binary(source, length, input_position)
+ || binary(source, length, input_position + 1)
+ || binary(source, length, input_position + 2)
+ || binary(source, length, input_position + 3)) {
+ binary_buffer *= 259;
+ binary_buffer += source[input_position];
+ binary_buffer_size++;
+
+ if (binary_buffer_size == 5) {
+ for (i = 0; i < 6; i++) {
+ lawrencium[i] = binary_buffer % 103;
+ binary_buffer /= 103;
+ }
+
+ for (i = 0; i < 6; i++) {
+ codeword_array[array_length] = lawrencium[5 - i];
+ array_length++;
+ }
+ binary_buffer = 0;
+ binary_buffer_size = 0;
+ }
+ input_position++;
+ done = 1;
+ if (debug) {
+ printf("F2 ");
+ }
+ }
+ }
+
+ /* Step F3 */
+ if ((!done) && (encoding_mode == 'X')) {
+ /* Empty binary buffer */
+ for (i = 0; i < (binary_buffer_size + 1); i++) {
+ lawrencium[i] = binary_buffer % 103;
+ binary_buffer /= 103;
+ }
+
+ for (i = 0; i < (binary_buffer_size + 1); i++) {
+ codeword_array[array_length] = lawrencium[binary_buffer_size - i];
+ array_length++;
+ }
+ binary_buffer = 0;
+ binary_buffer_size = 0;
+
+ if (ahead_a(source, input_position, length) > ahead_b(source, input_position, length, NULL)) {
+ codeword_array[array_length] = 109; // Terminate with Latch to A
+ encoding_mode = 'A';
+ } else {
+ codeword_array[array_length] = 110; // Terminate with Latch to B
+ encoding_mode = 'B';
+ }
+ array_length++;
+ // done = 1 // As long as last branch not needed
+ if (debug) {
+ printf("F3 ");
+ }
+ }
+ }
+
+ if (encoding_mode == 'X') {
+ if (binary_buffer_size != 0) {
+ /* Empty binary buffer */
+ for (i = 0; i < (binary_buffer_size + 1); i++) {
+ lawrencium[i] = binary_buffer % 103;
+ binary_buffer /= 103;
+ }
+
+ for (i = 0; i < (binary_buffer_size + 1); i++) {
+ codeword_array[array_length] = lawrencium[binary_buffer_size - i];
+ array_length++;
+ }
+ }
+ *(binary_finish) = 1;
+ }
+
+ if (debug) {
+ printf("\n");
+ }
+
+ return array_length;
+}
+
+/* Convert codewords to binary data stream */
+static size_t make_dotstream(unsigned char masked_array[], int array_length, char dot_stream[]) {
+ int i;
+
+ dot_stream[0] = '\0';
+
+ /* Mask value is encoded as two dots */
+ bin_append(masked_array[0], 2, dot_stream);
+
+ /* The rest of the data uses 9-bit dot patterns from Annex C */
+ for (i = 1; i < array_length; i++) {
+ bin_append(dot_patterns[masked_array[i]], 9, dot_stream); // NOLINT masked_array values modulo 113 and fully set
+ }
+
+ return strlen(dot_stream);
+}
+
+/* Determines if a given dot is a reserved corner dot
+ * to be used by one of the last six bits
+ */
+static int is_corner(int column, int row, int width, int height) {
+ int corner = 0;
+
+ /* Top Left */
+ if ((column == 0) && (row == 0)) {
+ corner = 1;
+ }
+
+ /* Top Right */
+ if (height % 2) {
+ if (((column == width - 2) && (row == 0))
+ || ((column == width - 1) && (row == 1))) {
+ corner = 1;
+ }
+ } else {
+ if ((column == width - 1) && (row == 0)) {
+ corner = 1;
+ }
+ }
+
+ /* Bottom Left */
+ if (height % 2) {
+ if ((column == 0) && (row == height - 1)) {
+ corner = 1;
+ }
+ } else {
+ if (((column == 0) && (row == height - 2))
+ || ((column == 1) && (row == height - 1))) {
+ corner = 1;
+ }
+ }
+
+ /* Bottom Right */
+ if (((column == width - 2) && (row == height - 1))
+ || ((column == width - 1) && (row == height - 2))) {
+ corner = 1;
+ }
+
+ return corner;
+}
+
+/* Place the dots in the symbol*/
+static void fold_dotstream(char dot_stream[], int width, int height, char dot_array[]) {
+ int column, row;
+ int input_position = 0;
+
+ if (height % 2) {
+ /* Horizontal folding */
+ for (row = 0; row < height; row++) {
+ for (column = 0; column < width; column++) {
+ if (!((column + row) % 2)) {
+ if (is_corner(column, row, width, height)) {
+ dot_array[(row * width) + column] = 'C';
+ } else {
+ dot_array[((height - row - 1) * width) + column] = dot_stream[input_position];
+ input_position++;
+ }
+ } else {
+ dot_array[((height - row - 1) * width) + column] = ' '; // Non-data position
+ }
+ }
+ }
+
+ /* Corners */
+ dot_array[width - 2] = dot_stream[input_position];
+ input_position++;
+ dot_array[(height * width) - 2] = dot_stream[input_position];
+ input_position++;
+ dot_array[(width * 2) - 1] = dot_stream[input_position];
+ input_position++;
+ dot_array[((height - 1) * width) - 1] = dot_stream[input_position];
+ input_position++;
+ dot_array[0] = dot_stream[input_position];
+ input_position++;
+ dot_array[(height - 1) * width] = dot_stream[input_position];
+ } else {
+ /* Vertical folding */
+ for (column = 0; column < width; column++) {
+ for (row = 0; row < height; row++) {
+ if (!((column + row) % 2)) {
+ if (is_corner(column, row, width, height)) {
+ dot_array[(row * width) + column] = 'C';
+ } else {
+ dot_array[(row * width) + column] = dot_stream[input_position];
+ input_position++;
+ }
+ } else {
+ dot_array[(row * width) + column] = ' '; // Non-data position
+ }
+ }
+ }
+
+ /* Corners */
+ dot_array[((height - 1) * width) - 1] = dot_stream[input_position];
+ input_position++;
+ dot_array[(height - 2) * width] = dot_stream[input_position];
+ input_position++;
+ dot_array[(height * width) - 2] = dot_stream[input_position];
+ input_position++;
+ dot_array[((height - 1) * width) + 1] = dot_stream[input_position];
+ input_position++;
+ dot_array[width - 1] = dot_stream[input_position];
+ input_position++;
+ dot_array[0] = dot_stream[input_position];
+ }
+}
+
+static void apply_mask(int mask, int data_length, unsigned char *masked_codeword_array, unsigned char *codeword_array, int ecc_length) {
+ int weight = 0;
+ int j;
+
+ switch (mask) {
+ case 0:
+ masked_codeword_array[0] = 0;
+ for (j = 0; j < data_length; j++) {
+ masked_codeword_array[j + 1] = codeword_array[j];
+ }
+ break;
+ case 1:
+ masked_codeword_array[0] = 1;
+ for (j = 0; j < data_length; j++) {
+ masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113;
+ weight += 3;
+ }
+ break;
+ case 2:
+ masked_codeword_array[0] = 2;
+ for (j = 0; j < data_length; j++) {
+ masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113;
+ weight += 7;
+ }
+ break;
+ case 3:
+ masked_codeword_array[0] = 3;
+ for (j = 0; j < data_length; j++) {
+ masked_codeword_array[j + 1] = (weight + codeword_array[j]) % 113;
+ weight += 17;
+ }
+ break;
+ }
+
+ rsencode(data_length + 1, ecc_length, masked_codeword_array);
+}
+
+static void force_corners(int width, int height, char *dot_array) {
+ if (width % 2) {
+ // "Vertical" symbol
+ dot_array[0] = '1';
+ dot_array[width - 1] = '1';
+ dot_array[(height - 2) * width] = '1';
+ dot_array[((height - 1) * width) - 1] = '1';
+ dot_array[((height - 1) * width) + 1] = '1';
+ dot_array[(height * width) - 2] = '1';
+ } else {
+ // "Horizontal" symbol
+ dot_array[0] = '1';
+ dot_array[width - 2] = '1';
+ dot_array[(2 * width) - 1] = '1';
+ dot_array[((height - 1) * width) - 1] = '1';
+ dot_array[(height - 1) * width] = '1';
+ dot_array[(height * width) - 2] = '1';
+ }
+}
+
+INTERNAL int dotcode(struct zint_symbol *symbol, const unsigned char source[], int length) {
+ int i, j, k;
+ size_t jc, n_dots;
+ int data_length, ecc_length;
+ int min_dots, min_area;
+ int height, width;
+ int mask_score[8];
+ size_t dot_stream_length;
+ int high_score, best_mask;
+ int binary_finish = 0;
+ int debug = symbol->debug;
+ int padding_dots, is_first;
+ int codeword_array_len = length * 4 + 8; /* Allow up to 4 codewords per input + 2 (FNC) + 4 (ECI) + 2 (special char 1st position) */
+#ifdef _MSC_VER
+ unsigned char* masked_codeword_array;
+#endif
+
+#ifndef _MSC_VER
+ unsigned char codeword_array[codeword_array_len];
+#else
+ char* dot_stream;
+ char* dot_array;
+ unsigned char* codeword_array = (unsigned char *) _alloca(codeword_array_len);
+#endif /* _MSC_VER */
+
+ if (symbol->eci > 811799) {
+ strcpy(symbol->errtxt, "525: Invalid ECI");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ data_length = dotcode_encode_message(symbol, source, length, codeword_array, &binary_finish);
+
+ ecc_length = 3 + (data_length / 2);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Codeword length = %d, ECC length = %d\n", data_length, ecc_length);
+ printf("Codewords: ");
+ for (i = 0; i < data_length; i++) {
+ printf("[%d] ",codeword_array[i]);
+ }
+ printf("\n");
+ }
+#ifdef ZINT_TEST
+ if (debug & ZINT_DEBUG_TEST) {
+ debug_test_codeword_dump(symbol, codeword_array, data_length);
+ }
+#endif
+
+ min_dots = 9 * (data_length + 3 + (data_length / 2)) + 2;
+ min_area = min_dots * 2;
+
+ if (symbol->option_2 == 0) {
+ /* Automatic sizing */
+ /* Following Rule 3 (Section 5.2.2) and applying a recommended width to height ratio 3:2 */
+ /* Eliminates under sized symbols */
+
+ float h = (float) (sqrt(min_area * 0.666));
+ float w = (float) (sqrt(min_area * 1.5));
+
+ height = (int) h;
+ width = (int) w;
+
+ if ((width + height) % 2 == 1) {
+ if ((width * height) < min_area) {
+ width++;
+ height++;
+ }
+ } else {
+ if ((h * width) < (w * height)) {
+ width++;
+ if ((width * height) < min_area) {
+ width--;
+ height++;
+ if ((width * height) < min_area) {
+ width += 2;
+ }
+ }
+ } else {
+ height++;
+ if ((width * height) < min_area) {
+ width++;
+ height--;
+ if ((width * height) < min_area) {
+ height += 2;
+ }
+ }
+ }
+ }
+
+ } else {
+ /* User defined width */
+ /* Eliminates under sized symbols */
+
+ width = symbol->option_2;
+ height = (min_area + (width - 1)) / width;
+
+ if (!((width + height) % 2)) {
+ height++;
+ }
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Width = %d, Height = %d\n", width, height);
+ }
+
+ if ((height > 200) || (width > 200)) {
+ strcpy(symbol->errtxt, "526: Specified symbol size is too large");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ if ((height < 5) || (width < 5)) {
+ strcpy(symbol->errtxt, "527: Specified symbol size has a dimension which is too small");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ n_dots = (height * width) / 2;
+
+#ifndef _MSC_VER
+ char dot_stream[height * width * 3];
+ char dot_array[width * height * sizeof (char) ];
+#else
+ dot_stream = (char *) _alloca(height * width * 3);
+ if (!dot_stream) return ZINT_ERROR_MEMORY;
+
+ dot_array = (char *) _alloca(width * height * sizeof (char));
+ if (!dot_array) return ZINT_ERROR_MEMORY;
+#endif
+
+ /* Add pad characters */
+ padding_dots = n_dots - min_dots; /* get the number of free dots available for padding */
+ is_first = 1; /* first padding character flag */
+
+ while (padding_dots >= 9) {
+ if (padding_dots < 18 && ((data_length % 2) == 0))
+ padding_dots -= 9;
+
+ else if (padding_dots >= 18) {
+ if ((data_length % 2) == 0)
+ padding_dots -= 9;
+ else
+ padding_dots -= 18;
+ } else
+ break; /* not enough padding dots left for padding */
+
+ if ((is_first == 1) && (binary_finish == 1))
+ codeword_array[data_length] = 109;
+ else
+ codeword_array[data_length] = 106;
+
+ data_length++;
+ is_first = 0;
+ }
+
+ ecc_length = 3 + (data_length / 2);
+
+
+#ifndef _MSC_VER
+ unsigned char masked_codeword_array[data_length + 1 + ecc_length];
+#else
+ masked_codeword_array = (unsigned char *) _alloca((data_length + 1 + ecc_length) * sizeof (unsigned char));
+#endif /* _MSC_VER */
+
+ /* Evaluate data mask options */
+ for (i = 0; i < 4; i++) {
+
+ apply_mask(i, data_length, masked_codeword_array, codeword_array, ecc_length);
+
+ dot_stream_length = make_dotstream(masked_codeword_array, (data_length + ecc_length + 1), dot_stream);
+
+ /* Add pad bits */
+ for (jc = dot_stream_length; jc < n_dots; jc++) {
+ strcat(dot_stream, "1");
+ }
+
+ fold_dotstream(dot_stream, width, height, dot_array);
+
+ mask_score[i] = score_array(dot_array, height, width);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Mask %d score is %d\n", i, mask_score[i]);
+ }
+ }
+
+ high_score = mask_score[0];
+ best_mask = 0;
+
+ for (i = 1; i < 4; i++) {
+ if (mask_score[i] >= high_score) {
+ high_score = mask_score[i];
+ best_mask = i;
+ }
+ }
+
+ /* Re-evaluate using forced corners if needed */
+ if (best_mask <= (height * width) / 2) {
+ for (i = 0; i < 4; i++) {
+
+ apply_mask(i, data_length, masked_codeword_array, codeword_array, ecc_length);
+
+ dot_stream_length = make_dotstream(masked_codeword_array, (data_length + ecc_length + 1), dot_stream);
+
+ /* Add pad bits */
+ for (jc = dot_stream_length; jc < n_dots; jc++) {
+ strcat(dot_stream, "1");
+ }
+
+ fold_dotstream(dot_stream, width, height, dot_array);
+
+ force_corners(width, height, dot_array);
+
+ mask_score[i + 4] = score_array(dot_array, height, width);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Mask %d score is %d\n", i + 4, mask_score[i + 4]);
+ }
+ }
+
+ for (i = 4; i < 8; i++) {
+ if (mask_score[i] >= high_score) {
+ high_score = mask_score[i];
+ best_mask = i;
+ }
+ }
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Applying mask %d, high_score %d\n", best_mask, high_score);
+ }
+
+ /* Apply best mask */
+ apply_mask(best_mask % 4, data_length, masked_codeword_array, codeword_array, ecc_length);
+
+ dot_stream_length = make_dotstream(masked_codeword_array, (data_length + ecc_length + 1), dot_stream);
+
+ /* Add pad bits */
+ for (jc = dot_stream_length; jc < n_dots; jc++) {
+ strcat(dot_stream, "1");
+ }
+
+ fold_dotstream(dot_stream, width, height, dot_array);
+
+ if (best_mask >= 4) {
+ force_corners(width, height, dot_array);
+ }
+
+ /* Copy values to symbol */
+ symbol->width = width;
+ symbol->rows = height;
+
+ for (k = 0; k < height; k++) {
+ for (j = 0; j < width; j++) {
+ if (dot_array[(k * width) + j] == '1') {
+ set_module(symbol, k, j);
+ }
+ }
+ symbol->row_height[k] = 1;
+ }
+
+ if (!(symbol->output_options & BARCODE_DOTTY_MODE)) {
+ symbol->output_options += BARCODE_DOTTY_MODE;
+ }
+
+ return 0;
+}
diff --git a/backend/eci.c b/backend/eci.c
new file mode 100644
index 0000000..4227790
--- /dev/null
+++ b/backend/eci.c
@@ -0,0 +1,273 @@
+/* eci.c - Extended Channel Interpretations
+
+ libzint - the open source barcode library
+ Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <string.h>
+#include <stdio.h>
+#include "eci.h"
+#include "common.h"
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+
+/* Convert Unicode to other character encodings */
+INTERNAL int utf_to_eci(const int eci, const unsigned char source[], unsigned char dest[], size_t *length) {
+ int in_posn;
+ int out_posn;
+ int ext;
+ int done;
+
+ if (eci == 26) {
+ /* Unicode mode, do not process - just copy data across */
+ memcpy(dest, source, *length);
+ dest[*length] = '\0';
+ return 0;
+ }
+
+ in_posn = 0;
+ out_posn = 0;
+ do {
+ /* Single byte (ASCII) character */
+ int bytelen = 1;
+ int glyph = (int) source[in_posn];
+
+ if ((source[in_posn] >= 0x80) && (source[in_posn] < 0xc0)) {
+ /* Something has gone wrong, abort */
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ if ((source[in_posn] >= 0xc0) && (source[in_posn] < 0xe0)) {
+ /* Two-byte character */
+ bytelen = 2;
+ glyph = (source[in_posn] & 0x1f) << 6;
+
+ if ((int) *length < (in_posn + 2)) {
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ if (source[in_posn + 1] > 0xc0) {
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ glyph += (source[in_posn + 1] & 0x3f);
+ }
+
+ if ((source[in_posn] >= 0xe0) && (source[in_posn] < 0xf0)) {
+ /* Three-byte character */
+ bytelen = 3;
+ glyph = (source[in_posn] & 0x0f) << 12;
+
+ if ((int) *length < (in_posn + 2)) {
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ if ((int) *length < (in_posn + 3)) {
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ if (source[in_posn + 1] > 0xc0) {
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ if (source[in_posn + 2] > 0xc0) {
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ glyph += (source[in_posn + 1] & 0x3f) << 6;
+ glyph += (source[in_posn + 2] & 0x3f);
+ }
+
+ if (source[in_posn] >= 0xf0 || glyph > 0x2122) {
+ /* Not in any ISO 8859 or Windows page */
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ if (glyph < 128) {
+ dest[out_posn] = glyph;
+ } else {
+ done = 0;
+ for (ext = 0; ext < 128; ext++) {
+ switch (eci) {
+ case 3: // Latin-1
+ if (glyph == iso_8859_1[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 4: // Latin-2
+ if (glyph == iso_8859_2[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 5: // Latin-3
+ if (glyph == iso_8859_3[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 6: // Latin-4
+ if (glyph == iso_8859_4[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 7: // Latin/Cyrillic
+ if (glyph == iso_8859_5[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 8: // Latin/Arabic
+ if (glyph == iso_8859_6[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 9: // Latin/Greek
+ if (glyph == iso_8859_7[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 10: // Latin/Hebrew
+ if (glyph == iso_8859_8[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 11: // Latin-5
+ if (glyph == iso_8859_9[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 12: // Latin-6
+ if (glyph == iso_8859_10[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 13: // Latin/Thai
+ if (glyph == iso_8859_11[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 15: // Latin-7
+ if (glyph == iso_8859_13[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 16: // Latin-8
+ if (glyph == iso_8859_14[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 17: // Latin-9
+ if (glyph == iso_8859_15[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 18: // Latin-10
+ if (glyph == iso_8859_16[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 21: // Windows-1250
+ if (glyph == windows_1250[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 22: // Windows-1251
+ if (glyph == windows_1251[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 23: // Windows-1252
+ if (glyph == windows_1252[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ case 24: // Windows-1256
+ if (glyph == windows_1256[ext]) {
+ dest[out_posn] = ext + 128;
+ done = 1;
+ }
+ break;
+ default:
+ break;
+ }
+ if (done) {
+ break;
+ }
+ }
+
+ if (!(done)) {
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ }
+
+ in_posn += bytelen;
+ out_posn++;
+ } while (in_posn < (int) *length);
+ dest[out_posn] = '\0';
+ *length = out_posn;
+
+ return 0;
+}
+
+/* Find the lowest ECI mode which will encode a given set of Unicode text */
+INTERNAL int get_best_eci(unsigned char source[], size_t length) {
+ int eci = 3;
+
+#ifndef _MSC_VER
+ unsigned char local_source[length + 1];
+#else
+ unsigned char *local_source = (unsigned char*) _alloca(length + 1);
+#endif
+
+ do {
+ if (utf_to_eci(eci, source, local_source, &length) == 0) {
+ return eci;
+ }
+ eci++;
+ } while (eci < 25);
+
+ return 26; // If all of these fail, use Unicode!
+}
diff --git a/backend/eci.h b/backend/eci.h
new file mode 100644
index 0000000..d4f2534
--- /dev/null
+++ b/backend/eci.h
@@ -0,0 +1,254 @@
+/* eci.c - Extended Channel Interpretations to Unicode tables
+
+ libzint - the open source barcode library
+ Copyright (C) 2009-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+
+#ifndef ECI_H
+#define ECI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static const unsigned short int iso_8859_1[] = {// Latin alphabet No. 1
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
+ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+ 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+ 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
+};
+
+static const unsigned short int iso_8859_2[] = {// Latin alphabet No. 2
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b,
+ 0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c,
+ 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
+ 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
+ 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
+ 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9
+};
+
+static const unsigned short int iso_8859_3[] = {// Latin alphabet No. 3
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00a0, 0x0126, 0x02d8, 0x00a3, 0x00a4, 0x0000, 0x0124, 0x00a7, 0x00a8, 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, 0x0000, 0x017b,
+ 0x00b0, 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7, 0x00b8, 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, 0x0000, 0x017c,
+ 0x00c0, 0x00c1, 0x00c2, 0x0000, 0x00c4, 0x010a, 0x0108, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+ 0x0000, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7, 0x011c, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df,
+ 0x00e0, 0x00e1, 0x00e2, 0x0000, 0x00e4, 0x010b, 0x0109, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x0000, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7, 0x011d, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9
+};
+
+static const unsigned short int iso_8859_4[] = {// Latin alphabet No. 4
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x012b, 0x013b, 0x00a7, 0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af,
+ 0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7, 0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b,
+ 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a,
+ 0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df,
+ 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b,
+ 0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9
+};
+
+static const unsigned short int iso_8859_5[] = {// Latin/Cyrillic alphabet
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f,
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f,
+ 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f
+};
+
+static const unsigned short int iso_8859_6[] = {// Latin/Arabic alphabet
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00a0, 0x0000, 0x0000, 0x0000, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x060c, 0x00ad, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f,
+ 0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f,
+ 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f,
+ 0x0650, 0x0651, 0x0652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short int iso_8859_7[] = {// Latin/Greek alphabet
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00a0, 0x2018, 0x2019, 0x00a3, 0x20ac, 0x20af, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x037a, 0x00ab, 0x00ac, 0x00ad, 0x0000, 0x2015,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x0385, 0x0386, 0x00b7, 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f,
+ 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
+ 0x03a0, 0x03a1, 0x0000, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af,
+ 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
+ 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0000
+};
+
+static const unsigned short int iso_8859_8[] = {// Latin/Hebrew alphabet
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00a0, 0x0000, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2017,
+ 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df,
+ 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x0000, 0x0000, 0x200e, 0x200f, 0x0000
+};
+
+static const unsigned short int iso_8859_9[] = {// Latin alphabet No. 5
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
+ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+ 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df,
+ 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff
+};
+
+static const unsigned short int iso_8859_10[] = {// Latin alphabet No. 6
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00a0, 0x0104, 0x0112, 0x0122, 0x012a, 0x012b, 0x0136, 0x00a7, 0x013b, 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a,
+ 0x00b0, 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7, 0x013c, 0x0111, 0x0161, 0x0167, 0x017e, 0x2015, 0x016b, 0x014b,
+ 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf,
+ 0x00d0, 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168, 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+ 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef,
+ 0x00f0, 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169, 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138
+};
+
+static const unsigned short int iso_8859_11[] = {// Latin/Thai alphabet
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f,
+ 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f,
+ 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f,
+ 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e36, 0x0e36, 0x0e37, 0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e3f,
+ 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f,
+ 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short int iso_8859_13[] = {// Latin alphabet No. 7
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00a0, 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x201e, 0x00a6, 0x00a7, 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, 0x00b5, 0x00b6, 0x00b7, 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6,
+ 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b,
+ 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df,
+ 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c,
+ 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x2019
+};
+
+static const unsigned short int iso_8859_14[] = {// Latin alphabet No. 8 (Celtic)
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00a0, 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7, 0x1e80, 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x0178,
+ 0x1e1e, 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56, 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61,
+ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+ 0x0174, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df,
+ 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x0175, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff
+};
+
+static const unsigned short int iso_8859_15[] = {// Latin alphabet No. 9
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7, 0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7, 0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf,
+ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+ 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+ 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
+};
+
+static const unsigned short int iso_8859_16[] = {// Latin alphabet No. 10
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00a0, 0x0104, 0x0105, 0x0141, 0x20ac, 0x201e, 0x0160, 0x00a7, 0x0161, 0x00a9, 0x0218, 0x00ab, 0x0179, 0x00ad, 0x017a, 0x017b,
+ 0x00b0, 0x00b1, 0x010c, 0x0142, 0x017d, 0x201d, 0x00b6, 0x00b7, 0x017e, 0x010d, 0x0219, 0x00bb, 0x0152, 0x0153, 0x0178, 0x017c,
+ 0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0106, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+ 0x0110, 0x0143, 0x00d2, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x015a, 0x0170, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0118, 0x021a, 0x00df,
+ 0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x0107, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x0111, 0x0144, 0x00f2, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x015b, 0x0171, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0119, 0x021b, 0x00ff
+};
+
+static const unsigned short int windows_1250[] = {
+ 0x20ac, 0x0000, 0x201a, 0x0000, 0x201e, 0x2026, 0x2020, 0x2021, 0x0000, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179,
+ 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a,
+ 0x00a0, 0x02c7, 0x02db, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b,
+ 0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c,
+ 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
+ 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
+ 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
+ 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9
+};
+
+static const unsigned short int windows_1251[] = {
+ 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f,
+ 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f,
+ 0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407,
+ 0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457,
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f
+};
+
+static const unsigned short int windows_1252[] = {
+ 0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017d, 0x0000,
+ 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178,
+ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
+ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
+ 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
+ 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
+ 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
+};
+
+static const unsigned short int windows_1256[] = {
+ 0x20ac, 0x067e, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
+ 0x06af, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x06a9, 0x2122, 0x0691, 0x203a, 0x0153, 0x200c, 0x200d, 0x06ba,
+ 0x00a0, 0x060c, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x06be, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
+ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x061b, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x061f,
+ 0x06c1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f,
+ 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00d7, 0x0637, 0x0638, 0x0639, 0x063a, 0x0640, 0x0641, 0x0642, 0x0643,
+ 0x00e0, 0x0644, 0x00e2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0649, 0x064a, 0x00ee, 0x00ef,
+ 0x064b, 0x064c, 0x064d, 0x064e, 0x00f4, 0x064f, 0x0650, 0x00f7, 0x0651, 0x00f9, 0x0652, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x06d2
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ECI_H */
+
+
diff --git a/backend/emf.c b/backend/emf.c
new file mode 100644
index 0000000..bd6f6a2
--- /dev/null
+++ b/backend/emf.c
@@ -0,0 +1,655 @@
+/* emf.c - Support for Microsoft Enhanced Metafile Format
+
+ libzint - the open source barcode library
+ Copyright (C) 2016 - 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/* Developed according to [MS-EMF] - v20160714, Released July 14, 2016
+ * and [MS-WMF] - v20160714, Released July 14, 2016 */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+#include "common.h"
+#include "emf.h"
+
+int colour_to_red(int colour) {
+ int return_val = 0;
+
+ switch(colour) {
+ case 0: // White
+ case 3: // Magenta
+ case 4: // Red
+ case 5: // Yellow
+ return_val = 255;
+ break;
+ }
+
+ return return_val;
+}
+
+int colour_to_green(int colour) {
+ int return_val = 0;
+
+ switch(colour) {
+ case 0: // White
+ case 1: // Cyan
+ case 5: // Yellow
+ case 6: // Green
+ return_val = 255;
+ break;
+ }
+
+ return return_val;
+}
+
+int colour_to_blue(int colour) {
+ int return_val = 0;
+
+ switch(colour) {
+ case 0: // White
+ case 1: // Cyan
+ case 2: // Blue
+ case 3: // Magenta
+ return_val = 255;
+ break;
+ }
+
+ return return_val;
+}
+
+static int count_rectangles(struct zint_symbol *symbol) {
+ int rectangles = 0;
+ struct zint_vector_rect *rect;
+
+ rect = symbol->vector->rectangles;
+ while (rect) {
+ rectangles++;
+ rect = rect->next;
+ }
+
+ return rectangles;
+}
+
+static int count_circles(struct zint_symbol *symbol) {
+ int circles = 0;
+ struct zint_vector_circle *circ;
+
+ circ = symbol->vector->circles;
+ while (circ) {
+ circles++;
+ circ = circ->next;
+ }
+
+ return circles;
+}
+
+static int count_hexagons(struct zint_symbol *symbol) {
+ int hexagons = 0;
+ struct zint_vector_hexagon *hex;
+
+ hex = symbol->vector->hexagons;
+ while (hex) {
+ hexagons++;
+ hex = hex->next;
+ }
+
+ return hexagons;
+}
+
+static int count_strings(struct zint_symbol *symbol) {
+ int strings = 0;
+ struct zint_vector_string *str;
+
+ str = symbol->vector->strings;
+ while (str) {
+ strings++;
+ str = str->next;
+ }
+
+ return strings;
+}
+
+static void utfle_copy(unsigned char *output, unsigned char *input, int length) {
+ int i;
+ int o;
+
+ /* Convert UTF-8 to UTF-16LE - only needs to handle characters <= U+00FF */
+ i = 0;
+ o = 0;
+ do {
+ if (input[i] <= 0x7f) {
+ /* 1 byte mode (7-bit ASCII) */
+ output[o] = input[i];
+ output[o + 1] = 0x00;
+ o += 2;
+ i++;
+ } else {
+ /* 2 byte mode */
+ output[o] = ((input[i] & 0x1f) << 6) + (input[i + 1] & 0x3f);
+ output[o + 1] = 0x00;
+ o += 2;
+ i += 2;
+ }
+ } while (i < length);
+}
+
+static int bump_up(int input) {
+ /* Strings length must be a multiple of 4 bytes */
+ if ((input % 2) == 1) {
+ input++;
+ }
+ return input;
+}
+
+INTERNAL int emf_plot(struct zint_symbol *symbol) {
+ int i,j;
+ FILE *emf_file;
+ int fgred, fggrn, fgblu, bgred, bggrn, bgblu;
+ int error_number = 0;
+ int rectangle_count, this_rectangle;
+ int circle_count, this_circle;
+ int hexagon_count, this_hexagon;
+ int string_count, this_text;
+ int bytecount, recordcount;
+ float radius;
+ int colours_used = 0;
+ int rectangle_count_bycolour[8];
+ unsigned char *this_string[6];
+ uint32_t spacing;
+
+ float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy;
+
+ struct zint_vector_rect *rect;
+ struct zint_vector_circle *circ;
+ struct zint_vector_hexagon *hex;
+ struct zint_vector_string *str;
+
+ emr_header_t emr_header;
+ emr_eof_t emr_eof;
+ emr_createbrushindirect_t emr_createbrushindirect_fg;
+ emr_createbrushindirect_t emr_createbrushindirect_bg;
+ emr_createbrushindirect_t emr_createbrushindirect_colour[8]; // Used for colour symbols only
+ emr_selectobject_t emr_selectobject_fgbrush;
+ emr_selectobject_t emr_selectobject_bgbrush;
+ emr_selectobject_t emr_selectobject_colour[8]; // Used for colour symbols only
+ emr_createpen_t emr_createpen;
+ emr_selectobject_t emr_selectobject_pen;
+ emr_rectangle_t background;
+ emr_extcreatefontindirectw_t emr_extcreatefontindirectw;
+ emr_selectobject_t emr_selectobject_font;
+ //emr_extcreatefontindirectw_t emr_extcreatefontindirectw_big;
+ //emr_selectobject_t emr_selectobject_font_big;
+
+#ifdef _MSC_VER
+ emr_rectangle_t *rectangle;
+ emr_ellipse_t *circle;
+ emr_polygon_t *hexagon;
+ emr_exttextoutw_t *text;
+#endif
+
+ 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]);
+
+ rectangle_count = count_rectangles(symbol);
+ circle_count = count_circles(symbol);
+ hexagon_count = count_hexagons(symbol);
+ string_count = count_strings(symbol);
+
+#ifndef _MSC_VER
+ emr_rectangle_t rectangle[rectangle_count ? rectangle_count : 1]; // Avoid sanitize runtime error by making always non-zero
+ emr_ellipse_t circle[circle_count ? circle_count : 1];
+ emr_polygon_t hexagon[hexagon_count ? hexagon_count : 1];
+ emr_exttextoutw_t text[string_count ? string_count: 1];
+#else
+ rectangle = (emr_rectangle_t*) _alloca(rectangle_count * sizeof (emr_rectangle_t));
+ circle = (emr_ellipse_t*) _alloca(circle_count * sizeof (emr_ellipse_t));
+ hexagon = (emr_polygon_t*) _alloca(hexagon_count * sizeof (emr_polygon_t));
+ text = (emr_exttextoutw_t*) _alloca(string_count * sizeof (emr_exttextoutw_t));
+#endif
+
+ //Calculate how many coloured rectangles
+ if (symbol->symbology == BARCODE_ULTRA) {
+ for (i = 0; i < 8; i++) {
+ rectangle_count_bycolour[i] = 0;
+ }
+
+ rect = symbol->vector->rectangles;
+ while (rect) {
+ if (rectangle_count_bycolour[rect->colour] == 0) {
+ colours_used++;
+ }
+ rectangle_count_bycolour[rect->colour]++;
+ rect = rect->next;
+ }
+ }
+
+ /* Header */
+ emr_header.type = 0x00000001; // EMR_HEADER
+ emr_header.size = 108; // Including extensions
+ emr_header.emf_header.bounds.left = 0;
+ emr_header.emf_header.bounds.right = ceil(symbol->vector->width);
+ emr_header.emf_header.bounds.bottom = ceil(symbol->vector->height);
+ emr_header.emf_header.bounds.top = 0;
+ emr_header.emf_header.frame.left = 0;
+ emr_header.emf_header.frame.right = emr_header.emf_header.bounds.right * 30;
+ emr_header.emf_header.frame.top = 0;
+ emr_header.emf_header.frame.bottom = emr_header.emf_header.bounds.bottom * 30;
+ emr_header.emf_header.record_signature = 0x464d4520; // ENHMETA_SIGNATURE
+ emr_header.emf_header.version = 0x00010000;
+ emr_header.emf_header.handles = 4; // Number of graphics objects
+ emr_header.emf_header.reserved = 0x0000;
+ emr_header.emf_header.n_description = 0;
+ emr_header.emf_header.off_description = 0;
+ emr_header.emf_header.n_pal_entries = 0;
+ emr_header.emf_header.device.cx = 1000;
+ emr_header.emf_header.device.cy = 1000;
+ emr_header.emf_header.millimeters.cx = 300;
+ emr_header.emf_header.millimeters.cy = 300;
+ /* HeaderExtension1 */
+ emr_header.emf_header.cb_pixel_format = 0x0000; // None set
+ emr_header.emf_header.off_pixel_format = 0x0000; // None set
+ emr_header.emf_header.b_open_gl = 0x0000; // OpenGL not present
+ /* HeaderExtension2 */
+ emr_header.emf_header.micrometers.cx = 0;
+ emr_header.emf_header.micrometers.cy = 0;
+ bytecount = 108;
+ recordcount = 1;
+
+ /* Create Brushes */
+ emr_createbrushindirect_bg.type = 0x00000027; // EMR_CREATEBRUSHINDIRECT
+ emr_createbrushindirect_bg.size = 24;
+ emr_createbrushindirect_bg.ih_brush = 1;
+ emr_createbrushindirect_bg.log_brush.brush_style = 0x0000; // BS_SOLID
+ emr_createbrushindirect_bg.log_brush.color.red = bgred;
+ emr_createbrushindirect_bg.log_brush.color.green = bggrn;
+ emr_createbrushindirect_bg.log_brush.color.blue = bgblu;
+ emr_createbrushindirect_bg.log_brush.color.reserved = 0;
+ emr_createbrushindirect_bg.log_brush.brush_hatch = 0x0006; // HS_SOLIDCLR
+ bytecount += 24;
+ recordcount++;
+
+ if (symbol->symbology == BARCODE_ULTRA) {
+ for (i = 0; i < 8; i++) {
+ emr_createbrushindirect_colour[i].type = 0x00000027; // EMR_CREATEBRUSHINDIRECT
+ emr_createbrushindirect_colour[i].size = 24;
+ emr_createbrushindirect_colour[i].ih_brush = 2 + i;
+ emr_createbrushindirect_colour[i].log_brush.brush_style = 0x0000; // BS_SOLID
+ emr_createbrushindirect_colour[i].log_brush.color.red = colour_to_red(i);
+ emr_createbrushindirect_colour[i].log_brush.color.green = colour_to_green(i);
+ emr_createbrushindirect_colour[i].log_brush.color.blue = colour_to_blue(i);
+ emr_createbrushindirect_colour[i].log_brush.color.reserved = 0;
+ emr_createbrushindirect_colour[i].log_brush.brush_hatch = 0x0006; // HS_SOLIDCLR
+ }
+ bytecount += colours_used * 24;
+ recordcount += colours_used;
+ } else {
+ emr_createbrushindirect_fg.type = 0x00000027; // EMR_CREATEBRUSHINDIRECT
+ emr_createbrushindirect_fg.size = 24;
+ emr_createbrushindirect_fg.ih_brush = 2;
+ emr_createbrushindirect_fg.log_brush.brush_style = 0x0000; // BS_SOLID
+ emr_createbrushindirect_fg.log_brush.color.red = fgred;
+ emr_createbrushindirect_fg.log_brush.color.green = fggrn;
+ emr_createbrushindirect_fg.log_brush.color.blue = fgblu;
+ emr_createbrushindirect_fg.log_brush.color.reserved = 0;
+ emr_createbrushindirect_fg.log_brush.brush_hatch = 0x0006; // HS_SOLIDCLR
+ bytecount += 24;
+ recordcount++;
+ }
+
+ emr_selectobject_bgbrush.type = 0x00000025; // EMR_SELECTOBJECT
+ emr_selectobject_bgbrush.size = 12;
+ emr_selectobject_bgbrush.ih_object = 1;
+ bytecount += 12;
+ recordcount++;
+
+ if (symbol->symbology == BARCODE_ULTRA) {
+ for (i = 0; i < 8; i++) {
+ emr_selectobject_colour[i].type = 0x00000025; // EMR_SELECTOBJECT
+ emr_selectobject_colour[i].size = 12;
+ emr_selectobject_colour[i].ih_object = 2 + i;
+ }
+ bytecount += colours_used * 12;
+ recordcount += colours_used;
+ } else {
+ emr_selectobject_fgbrush.type = 0x00000025; // EMR_SELECTOBJECT
+ emr_selectobject_fgbrush.size = 12;
+ emr_selectobject_fgbrush.ih_object = 2;
+ bytecount += 12;
+ recordcount++;
+ }
+
+ /* Create Pens */
+ emr_createpen.type = 0x00000026; // EMR_CREATEPEN
+ emr_createpen.size = 28;
+ emr_createpen.ih_pen = 10;
+ emr_createpen.log_pen.pen_style = 0x00000005; // PS_NULL
+ emr_createpen.log_pen.width.x = 1;
+ emr_createpen.log_pen.width.y = 0; // ignored
+ emr_createpen.log_pen.color_ref.red = 0;
+ emr_createpen.log_pen.color_ref.green = 0;
+ emr_createpen.log_pen.color_ref.blue = 0;
+ emr_createpen.log_pen.color_ref.reserved = 0;
+ bytecount += 28;
+ recordcount++;
+
+ emr_selectobject_pen.type = 0x00000025; // EMR_SELECTOBJECT
+ emr_selectobject_pen.size = 12;
+ emr_selectobject_pen.ih_object = 10;
+ bytecount += 12;
+ recordcount++;
+
+ /* Make background from a rectangle */
+ background.type = 0x0000002b; // EMR_RECTANGLE;
+ background.size = 24;
+ background.box.top = 0;
+ background.box.left = 0;
+ background.box.right = emr_header.emf_header.bounds.right;
+ background.box.bottom = emr_header.emf_header.bounds.bottom;
+ bytecount += 24;
+ recordcount++;
+
+ //Rectangles
+ rect = symbol->vector->rectangles;
+ this_rectangle = 0;
+ while (rect) {
+ rectangle[this_rectangle].type = 0x0000002b; // EMR_RECTANGLE;
+ rectangle[this_rectangle].size = 24;
+ rectangle[this_rectangle].box.top = rect->y;
+ rectangle[this_rectangle].box.bottom = rect->y + rect->height;
+ rectangle[this_rectangle].box.left = rect->x;
+ rectangle[this_rectangle].box.right = rect->x + rect->width;
+ this_rectangle++;
+ bytecount += 24;
+ recordcount++;
+ rect = rect->next;
+ }
+
+ //Circles
+ circ = symbol->vector->circles;
+ this_circle = 0;
+ while (circ) {
+ radius = circ->diameter / 2.0;
+ circle[this_circle].type = 0x0000002a; // EMR_ELLIPSE
+ circle[this_circle].size = 24;
+ circle[this_circle].box.top = circ->y - radius;
+ circle[this_circle].box.bottom = circ->y + radius;
+ circle[this_circle].box.left = circ->x - radius;
+ circle[this_circle].box.right = circ->x + radius;
+ this_circle++;
+ bytecount += 24;
+ recordcount++;
+ circ = circ->next;
+ }
+
+ //Hexagons
+ hex = symbol->vector->hexagons;
+ this_hexagon = 0;
+ while (hex) {
+ hexagon[this_hexagon].type = 0x00000003; // EMR_POLYGON
+ hexagon[this_hexagon].size = 76;
+ hexagon[this_hexagon].count = 6;
+
+ radius = hex->diameter / 2.0;
+ ay = hex->y + (1.0 * radius);
+ by = hex->y + (0.5 * radius);
+ cy = hex->y - (0.5 * radius);
+ dy = hex->y - (1.0 * radius);
+ ey = hex->y - (0.5 * radius);
+ fy = hex->y + (0.5 * radius);
+ ax = hex->x;
+ bx = hex->x + (0.86 * radius);
+ cx = hex->x + (0.86 * radius);
+ dx = hex->x;
+ ex = hex->x - (0.86 * radius);
+ fx = hex->x - (0.86 * radius);
+
+ hexagon[this_hexagon].a_points_a.x = ax;
+ hexagon[this_hexagon].a_points_a.y = ay;
+ hexagon[this_hexagon].a_points_b.x = bx;
+ hexagon[this_hexagon].a_points_b.y = by;
+ hexagon[this_hexagon].a_points_c.x = cx;
+ hexagon[this_hexagon].a_points_c.y = cy;
+ hexagon[this_hexagon].a_points_d.x = dx;
+ hexagon[this_hexagon].a_points_d.y = dy;
+ hexagon[this_hexagon].a_points_e.x = ex;
+ hexagon[this_hexagon].a_points_e.y = ey;
+ hexagon[this_hexagon].a_points_f.x = fx;
+ hexagon[this_hexagon].a_points_f.y = fy;
+
+ hexagon[this_hexagon].bounds.top = hexagon[this_hexagon].a_points_d.y;
+ hexagon[this_hexagon].bounds.bottom = hexagon[this_hexagon].a_points_a.y;
+ hexagon[this_hexagon].bounds.left = hexagon[this_hexagon].a_points_e.x;
+ hexagon[this_hexagon].bounds.right = hexagon[this_hexagon].a_points_c.x;
+ this_hexagon++;
+ bytecount += 76;
+ recordcount++;
+ hex = hex->next;
+ }
+
+ /* Create font records */
+ if (symbol->vector->strings) {
+ emr_extcreatefontindirectw.type = 0x00000052; // EMR_EXTCREATEFONTINDIRECTW
+ emr_extcreatefontindirectw.size = 104;
+ emr_extcreatefontindirectw.ih_fonts = 4;
+ emr_extcreatefontindirectw.elw.height = 16 * symbol->scale;
+ emr_extcreatefontindirectw.elw.width = 0; // automatic
+ emr_extcreatefontindirectw.elw.escapement = 0;
+ emr_extcreatefontindirectw.elw.orientation = 0;
+ emr_extcreatefontindirectw.elw.weight = 400;
+ emr_extcreatefontindirectw.elw.italic = 0x00;
+ emr_extcreatefontindirectw.elw.underline = 0x00;
+ emr_extcreatefontindirectw.elw.strike_out = 0x00;
+ emr_extcreatefontindirectw.elw.char_set = 0x01;
+ emr_extcreatefontindirectw.elw.out_precision = 0x00; // OUT_DEFAULT_PRECIS
+ emr_extcreatefontindirectw.elw.clip_precision = 0x00; // CLIP_DEFAULT_PRECIS
+ emr_extcreatefontindirectw.elw.quality = 0x00;
+ emr_extcreatefontindirectw.elw.pitch_and_family = 0x00;
+ for (i = 0; i < 64; i++) {
+ emr_extcreatefontindirectw.elw.facename[i] = '\0';
+ }
+ utfle_copy(emr_extcreatefontindirectw.elw.facename, (unsigned char*) "sans-serif", 10);
+ bytecount += 104;
+ recordcount++;
+
+ emr_selectobject_font.type = 0x00000025; // EMR_SELECTOBJECT
+ emr_selectobject_font.size = 12;
+ emr_selectobject_font.ih_object = 4;
+ bytecount += 12;
+ recordcount++;
+ }
+
+ //Text
+ str = symbol->vector->strings;
+ this_text = 0;
+ while (str) {
+ this_string[this_text] = (unsigned char *) malloc(bump_up(str->length + 1) * 2);
+ text[this_text].type = 0x00000054; // EMR_EXTTEXTOUTW
+ text[this_text].size = 76 + (6 * bump_up(str->length + 1));
+ text[this_text].bounds.top = 0; // ignored
+ text[this_text].bounds.left = 0; // ignored
+ text[this_text].bounds.right = 0xffffffff; // ignored
+ text[this_text].bounds.bottom = 0xffffffff; // ignored
+ text[this_text].i_graphics_mode = 0x00000001; // GM_COMPATIBLE
+ text[this_text].ex_scale = 1.0;
+ text[this_text].ey_scale = 1.0;
+ text[this_text].w_emr_text.reference.x = str->x - (4 * str->length * symbol->scale); // text left
+ text[this_text].w_emr_text.reference.y = str->y - (16 * symbol->scale); // text top
+ text[this_text].w_emr_text.chars = str->length;
+ text[this_text].w_emr_text.off_string = 76;
+ text[this_text].w_emr_text.options = 0;
+ text[this_text].w_emr_text.rectangle.top = 0;
+ text[this_text].w_emr_text.rectangle.left = 0;
+ text[this_text].w_emr_text.rectangle.right = 0xffffffff;
+ text[this_text].w_emr_text.rectangle.bottom = 0xffffffff;
+ text[this_text].w_emr_text.off_dx = 76 + (2 * bump_up(str->length + 1));
+ for (i = 0; i < bump_up(str->length + 1) * 2; i++) {
+ this_string[this_text][i] = '\0';
+ }
+ utfle_copy(this_string[this_text], str->text, str->length);
+ bytecount += 76 + (6 * bump_up(str->length + 1));
+ recordcount++;
+
+ this_text++;
+ str = str->next;
+ }
+
+ /* Create EOF record */
+ emr_eof.type = 0x0000000e; // EMR_EOF
+ emr_eof.size = 20; // Assuming no palette entries
+ emr_eof.n_pal_entries = 0;
+ emr_eof.off_pal_entries = 0;
+ emr_eof.size_last = emr_eof.size;
+ bytecount += 20;
+ recordcount++;
+
+ if (symbol->symbology == BARCODE_MAXICODE) {
+ bytecount += 5 * sizeof (emr_selectobject_t);
+ recordcount += 5;
+ }
+
+ /* Put final counts in header */
+ emr_header.emf_header.bytes = bytecount;
+ emr_header.emf_header.records = recordcount;
+
+ /* Send EMF data to file */
+ if (symbol->output_options & BARCODE_STDOUT) {
+ emf_file = stdout;
+ } else {
+ emf_file = fopen(symbol->outfile, "wb");
+ }
+ if (emf_file == NULL) {
+ strcpy(symbol->errtxt, "640: Could not open output file");
+ return ZINT_ERROR_FILE_ACCESS;
+ }
+
+ fwrite(&emr_header, sizeof (emr_header_t), 1, emf_file);
+
+ fwrite(&emr_createbrushindirect_bg, sizeof (emr_createbrushindirect_t), 1, emf_file);
+
+ if (symbol->symbology == BARCODE_ULTRA) {
+ for (i = 0; i < 8; i++) {
+ if (rectangle_count_bycolour[i]) {
+ fwrite(&emr_createbrushindirect_colour[i], sizeof (emr_createbrushindirect_t), 1, emf_file);
+ }
+ }
+ } else {
+ fwrite(&emr_createbrushindirect_fg, sizeof (emr_createbrushindirect_t), 1, emf_file);
+ }
+
+ fwrite(&emr_createpen, sizeof (emr_createpen_t), 1, emf_file);
+
+ if (symbol->vector->strings) {
+ fwrite(&emr_extcreatefontindirectw, sizeof (emr_extcreatefontindirectw_t), 1, emf_file);
+ }
+
+ fwrite(&emr_selectobject_bgbrush, sizeof (emr_selectobject_t), 1, emf_file);
+ fwrite(&emr_selectobject_pen, sizeof (emr_selectobject_t), 1, emf_file);
+ fwrite(&background, sizeof (emr_rectangle_t), 1, emf_file);
+
+ if (symbol->symbology == BARCODE_ULTRA) {
+ for(i = 0; i < 8; i++) {
+ if (rectangle_count_bycolour[i]) {
+ fwrite(&emr_selectobject_colour[i], sizeof (emr_selectobject_t), 1, emf_file);
+
+ rect = symbol->vector->rectangles;
+ this_rectangle = 0;
+ while (rect) {
+ if (rect->colour == i) {
+ fwrite(&rectangle[this_rectangle], sizeof (emr_rectangle_t), 1, emf_file);
+ }
+ this_rectangle++;
+ rect = rect->next;
+ }
+ }
+ }
+ } else {
+ fwrite(&emr_selectobject_fgbrush, sizeof (emr_selectobject_t), 1, emf_file);
+
+ // Rectangles
+ for (i = 0; i < rectangle_count; i++) {
+ fwrite(&rectangle[i], sizeof (emr_rectangle_t), 1, emf_file);
+ }
+ }
+
+ // Hexagons
+ for (i = 0; i < hexagon_count; i++) {
+ fwrite(&hexagon[i], sizeof (emr_polygon_t), 1, emf_file);
+ }
+
+ // Circles
+ if (symbol->symbology == BARCODE_MAXICODE) {
+ // Bullseye needed
+ for (i = 0; i < circle_count; i++) {
+ fwrite(&circle[i], sizeof (emr_ellipse_t), 1, emf_file);
+ if (i < circle_count - 1) {
+ if (i % 2) {
+ fwrite(&emr_selectobject_fgbrush, sizeof (emr_selectobject_t), 1, emf_file);
+ } else {
+ fwrite(&emr_selectobject_bgbrush, sizeof (emr_selectobject_t), 1, emf_file);
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < circle_count; i++) {
+ fwrite(&circle[i], sizeof (emr_ellipse_t), 1, emf_file);
+ }
+ }
+
+ // Text
+ if (string_count > 0) {
+ fwrite(&emr_selectobject_font, sizeof (emr_selectobject_t), 1, emf_file);
+ }
+
+ for (i = 0; i < string_count; i++) {
+ spacing = 8 * symbol->scale;
+ fwrite(&text[i], sizeof (emr_exttextoutw_t), 1, emf_file);
+ fwrite(this_string[i], bump_up(text[i].w_emr_text.chars + 1) * 2, 1, emf_file); // NOLINT text set 0..(string_count - 1)
+ free(this_string[i]);
+ for (j = 0; j < bump_up(text[i].w_emr_text.chars + 1); j++) {
+ fwrite(&spacing, 4, 1, emf_file);
+ }
+ }
+
+ fwrite(&emr_eof, sizeof (emr_eof_t), 1, emf_file);
+
+ if (symbol->output_options & BARCODE_STDOUT) {
+ fflush(emf_file);
+ } else {
+ fclose(emf_file);
+ }
+ return error_number;
+}
diff --git a/backend/emf.h b/backend/emf.h
new file mode 100644
index 0000000..5ecb23d
--- /dev/null
+++ b/backend/emf.h
@@ -0,0 +1,223 @@
+/* emf.h - header structure for Microsoft EMF
+
+ libzint - the open source barcode library
+ Copyright (C) 2016-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+
+#ifndef EMF_H
+#define EMF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _MSC_VER
+#include <windows.h>
+#include "stdint_msvc.h"
+#else
+#include <stdint.h>
+#endif
+
+#pragma pack(1)
+
+ typedef struct rect_l {
+ int32_t left;
+ int32_t top;
+ int32_t right;
+ int32_t bottom;
+ } rect_l_t;
+
+ typedef struct size_l {
+ uint32_t cx;
+ uint32_t cy;
+ } size_l_t;
+
+ typedef struct point_l {
+ int32_t x;
+ int32_t y;
+ } point_l_t;
+
+ typedef struct color_ref {
+ uint8_t red;
+ uint8_t green;
+ uint8_t blue;
+ uint8_t reserved;
+ } color_ref_t;
+
+ typedef struct log_brush_ex {
+ uint32_t brush_style;
+ color_ref_t color;
+ uint32_t brush_hatch;
+ } log_brush_ex_t;
+
+ typedef struct log_pen {
+ uint32_t pen_style;
+ point_l_t width;
+ color_ref_t color_ref;
+ } log_pen_t;
+
+ typedef struct log_font {
+ int32_t height;
+ int32_t width;
+ int32_t escapement;
+ int32_t orientation;
+ int32_t weight;
+ uint8_t italic;
+ uint8_t underline;
+ uint8_t strike_out;
+ uint8_t char_set;
+ uint8_t out_precision;
+ uint8_t clip_precision;
+ uint8_t quality;
+ uint8_t pitch_and_family;
+ unsigned char facename[64];
+ } log_font_t;
+
+ typedef struct emr_text {
+ point_l_t reference;
+ uint32_t chars;
+ uint32_t off_string;
+ uint32_t options;
+ rect_l_t rectangle;
+ uint32_t off_dx;
+ } emr_text_t;
+
+ typedef struct emf_header {
+ rect_l_t bounds;
+ rect_l_t frame;
+ uint32_t record_signature;
+ uint32_t version;
+ uint32_t bytes;
+ uint32_t records;
+ uint16_t handles;
+ uint16_t reserved;
+ uint32_t n_description;
+ uint32_t off_description;
+ uint32_t n_pal_entries;
+ size_l_t device;
+ size_l_t millimeters;
+ // HeaderExtension1 Object
+ uint32_t cb_pixel_format;
+ uint32_t off_pixel_format;
+ uint32_t b_open_gl;
+ // HeaderExtension2 Object
+ size_l_t micrometers;
+ } emf_header_t;
+
+ typedef struct emr_header {
+ uint32_t type;
+ uint32_t size;
+ emf_header_t emf_header;
+ } emr_header_t;
+
+ typedef struct emr_createbrushindirect {
+ uint32_t type;
+ uint32_t size;
+ uint32_t ih_brush;
+ log_brush_ex_t log_brush;
+ } emr_createbrushindirect_t;
+
+ typedef struct emr_createpen {
+ uint32_t type;
+ uint32_t size;
+ uint32_t ih_pen;
+ log_pen_t log_pen;
+ } emr_createpen_t;
+
+ typedef struct emr_selectobject {
+ uint32_t type;
+ uint32_t size;
+ uint32_t ih_object;
+ } emr_selectobject_t;
+
+ typedef struct emr_rectangle {
+ uint32_t type;
+ uint32_t size;
+ rect_l_t box;
+ } emr_rectangle_t;
+
+ typedef struct emr_ellipse {
+ uint32_t type;
+ uint32_t size;
+ rect_l_t box;
+ } emr_ellipse_t;
+
+ typedef struct emr_polygon {
+ uint32_t type;
+ uint32_t size;
+ rect_l_t bounds;
+ uint32_t count;
+ point_l_t a_points_a;
+ point_l_t a_points_b;
+ point_l_t a_points_c;
+ point_l_t a_points_d;
+ point_l_t a_points_e;
+ point_l_t a_points_f;
+ } emr_polygon_t;
+
+ typedef struct emr_extcreatefontindirectw {
+ uint32_t type;
+ uint32_t size;
+ uint32_t ih_fonts;
+ log_font_t elw;
+ } emr_extcreatefontindirectw_t;
+
+ typedef struct emr_exttextoutw {
+ uint32_t type;
+ uint32_t size;
+ rect_l_t bounds;
+ uint32_t i_graphics_mode;
+ float ex_scale;
+ float ey_scale;
+ emr_text_t w_emr_text;
+ } emr_exttextoutw_t;
+
+ typedef struct emr_eof {
+ uint32_t type;
+ uint32_t size;
+ uint32_t n_pal_entries;
+ uint32_t off_pal_entries;
+ uint32_t size_last;
+ } emr_eof_t;
+
+ typedef struct box {
+ emr_rectangle_t top;
+ emr_rectangle_t bottom;
+ emr_rectangle_t left;
+ emr_rectangle_t right;
+ } box_t;
+
+#pragma pack()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EMF_H */
+
+
diff --git a/backend/font.h b/backend/font.h
index 4ce6364..021efac 100644
--- a/backend/font.h
+++ b/backend/font.h
@@ -2,7 +2,7 @@
/*
libzint - the open source barcode library
- Copyright (C) 2008 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2008-2017 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -28,1675 +28,392 @@
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.
-*/
+ */
-/* This file contains the pixel-by-pixel representation of the "Misc Fixed" font
- at 10 point size processed by the Gimp */
-
-static const 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 const 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
-};
-
-static const int small_font[] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,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,1,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,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,0,0,
- 0,0,1,0,0,0,1,1,0,0,1,1,1,1,0,0,
- 0,1,0,0,1,1,1,1,0,0,1,1,0,0,1,1,
- 1,1,0,0,1,1,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,1,0,0,0,1,1,0,0,
- 0,1,1,0,0,1,1,1,0,0,0,1,1,0,0,1,
- 1,1,0,0,1,1,1,1,0,1,1,1,1,0,0,1,
- 1,0,0,1,0,0,1,0,0,1,1,1,0,0,0,0,
- 1,0,1,0,0,1,0,1,0,0,0,0,1,0,0,1,
- 0,1,0,0,1,0,0,1,1,0,0,1,1,1,0,0,
- 0,1,1,0,0,1,1,1,0,0,0,1,1,0,0,0,
- 1,1,1,0,1,0,0,1,0,1,0,0,1,0,1,0,
- 0,1,0,1,0,0,1,0,0,1,0,1,0,1,1,1,
- 1,0,0,1,1,1,0,0,0,0,0,0,0,1,1,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,0,0,0,0,
- 0,0,1,0,0,0,0,0,0,0,0,1,0,0,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,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,
- 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,1,0,0,0,1,0,0,
- 0,0,1,0,1,0,0,0,0,0,0,
- 0,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,
- 1,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,
- 1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,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,1,0,0,1,0,1,0,
- 0,1,1,0,0,1,0,0,1,0,0,0,0,1,0,0,
- 1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,
- 0,1,0,1,0,0,1,0,1,0,0,1,0,0,1,1,
- 0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,
- 0,0,1,0,0,0,0,1,0,1,0,1,0,0,1,0,
- 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,
- 0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,
- 0,1,0,1,0,0,1,0,0,0,1,0,0,0,0,0,
- 1,0,1,0,1,0,0,1,0,0,0,0,1,1,1,1,
- 0,1,1,0,1,0,1,0,0,1,0,1,0,0,1,0,
- 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,
- 0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0,
- 0,1,0,1,0,0,1,0,0,1,0,1,0,0,0,0,
- 1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,
- 0,0,1,0,1,0,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,1,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,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,
- 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,0,0,0,0,1,0,0,0,0,1,0,
- 0,1,0,1,0,0,0,0,0,0,0,
- 0,0,1,0,0,0,1,0,1,0,1,1,1,1,1,1,
- 0,1,0,0,0,0,1,0,0,1,0,1,0,0,0,0,
- 1,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,0,0,0,
- 0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,
- 0,0,1,0,0,0,0,0,1,0,0,1,1,0,0,1,
- 0,1,0,0,1,1,1,0,0,1,1,1,0,0,0,0,
- 1,0,0,0,1,1,0,0,1,0,0,1,0,0,1,1,
- 0,0,0,1,1,0,0,0,0,1,0,0,1,1,1,1,
- 0,0,0,1,0,0,0,0,0,1,0,1,0,1,1,0,
- 1,0,0,1,0,1,1,1,0,0,1,0,0,0,0,1,
- 0,0,1,0,1,1,1,0,0,1,1,1,0,0,1,0,
- 0,0,0,1,1,1,1,0,0,0,1,0,0,0,0,0,
- 1,0,1,1,0,0,0,1,0,0,0,0,1,1,1,1,
- 0,1,1,0,1,0,1,0,0,1,0,1,0,0,1,0,
- 1,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,
- 0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,0,
- 0,1,0,0,1,1,0,0,0,1,0,1,0,0,0,1,
- 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,1,1,0,1,1,1,0,0,0,1,1,0,0,0,
- 1,1,1,0,0,1,1,0,0,0,1,0,0,0,0,1,
- 1,1,0,1,1,1,0,0,0,1,1,0,0,0,0,0,
- 1,0,1,0,1,0,0,0,0,1,0,0,1,0,1,0,
- 0,1,1,1,0,0,0,1,1,0,0,1,1,1,0,0,
- 0,1,1,1,0,1,1,1,0,0,0,1,1,1,0,1,
- 1,1,0,0,1,0,0,1,0,0,1,0,1,0,1,0,
- 0,1,0,1,0,0,1,0,1,0,0,1,0,1,1,1,
- 1,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,1,0,0,0,0,0,0,0,0,1,0,1,0,0,
- 1,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,
- 0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1,
- 1,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,
- 0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,
- 0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,1,
- 1,1,1,0,0,0,0,1,0,1,0,0,1,0,0,0,
- 1,0,0,1,0,0,1,0,0,1,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,1,0,0,0,1,0,0,1,0,1,1,0,
- 1,1,1,1,0,1,0,0,1,0,1,0,0,0,0,1,
- 0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,
- 1,1,0,1,0,0,1,0,0,0,1,0,0,0,0,0,
- 1,0,1,1,0,0,0,1,0,0,0,0,1,0,0,1,
- 0,1,0,1,1,0,1,0,0,1,0,1,1,1,0,0,
- 1,0,0,1,0,1,1,1,0,0,0,0,1,0,0,0,
- 0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,1,
- 1,1,0,0,1,1,0,0,0,0,1,0,0,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,0,0,0,0,0,0,0,0,0,0,
- 1,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1,
- 0,0,1,0,1,0,1,1,0,1,1,1,0,0,1,0,
- 0,1,0,1,0,0,1,0,0,0,1,0,0,0,0,0,
- 1,0,1,1,0,0,0,0,0,1,0,0,1,1,1,1,
- 0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,
- 1,0,0,1,0,1,0,0,1,0,1,1,0,0,0,0,
- 1,0,0,0,1,0,0,1,0,0,1,0,1,0,1,0,
- 0,1,0,0,1,1,0,0,1,0,0,1,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,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,
- 0,1,0,1,1,0,0,1,0,1,0,1,0,0,0,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,1,1,0,0,0,0,0,
- 0,0,1,1,0,0,1,0,0,0,0,0,1,0,1,0,
- 0,0,1,0,0,0,1,0,0,0,1,0,0,1,0,0,
- 0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,
- 0,0,0,1,0,0,1,0,0,0,0,1,0,0,1,1,
- 0,0,0,1,1,0,0,0,0,1,0,0,1,1,1,1,
- 0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,
- 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,
- 0,0,1,0,1,0,0,0,0,1,0,0,0,0,1,0,
- 0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,
- 1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,1,
- 0,1,0,1,1,0,1,0,0,1,0,1,0,0,0,0,
- 1,1,0,1,0,1,0,1,0,0,1,0,0,1,0,0,
- 0,1,0,0,1,0,0,1,0,0,1,1,0,0,1,1,
- 1,1,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,0,1,1,0,1,0,0,1,0,1,0,0,0,0,1,
- 0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,1,
- 1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,
- 1,0,1,0,1,0,0,0,0,1,0,0,1,0,0,1,
- 0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,
- 1,0,0,1,0,1,0,0,0,0,0,0,1,1,0,0,
- 1,0,0,0,1,0,0,1,0,0,1,0,1,0,1,1,
- 1,1,0,0,1,1,0,0,0,1,0,1,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,0,0,0,0,
- 0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,
- 1,1,1,0,0,0,0,1,0,0,1,0,1,0,0,0,
- 0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,
- 1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,
- 0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,
- 0,1,1,1,0,1,1,1,1,0,0,1,1,0,0,0,
- 0,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1,
- 0,0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,
- 0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,
- 0,0,1,0,0,0,0,0,1,0,0,0,1,1,0,0,
- 1,0,0,1,0,1,1,1,0,0,0,1,1,0,0,1,
- 1,1,0,0,1,1,1,1,0,1,0,0,0,0,0,1,
- 1,1,0,1,0,0,1,0,0,1,1,1,0,0,1,1,
- 0,0,1,0,0,1,0,1,1,1,1,0,1,0,0,1,
- 0,1,0,0,1,0,0,1,1,0,0,1,0,0,0,0,
- 0,1,1,0,0,1,0,0,1,0,0,1,1,0,0,0,
- 0,1,0,0,0,1,1,0,0,0,1,1,0,0,1,0,
- 0,1,0,1,0,0,1,0,0,0,1,0,0,1,1,1,
- 1,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,
- 0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,
- 0,1,0,1,0,1,1,1,0,0,0,1,1,0,0,0,
- 1,1,1,0,0,1,1,0,0,0,1,0,0,0,1,0,
- 0,0,0,1,0,0,1,0,0,1,1,1,0,0,1,0,
- 1,0,1,0,0,1,0,0,1,1,1,0,1,0,0,1,
- 0,1,0,0,1,0,0,1,1,0,0,1,1,1,0,0,
- 0,1,1,1,0,1,0,0,0,0,1,1,1,0,0,0,
- 0,1,1,0,0,1,1,1,0,0,0,1,0,0,1,1,
- 1,1,0,1,0,0,1,0,0,0,1,0,0,1,1,1,
- 1,0,0,0,0,1,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,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,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,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,
- 1,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,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,0,0,0,0,0,0,0,
- 0,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
+static const char ascii_font[] = {
+ /* Each character is 7 x 14 pixels */
+ 0, 0, 8, 8, 8, 8, 8, 8, 8, 0, 8, 8, 0, 0, /* ! */
+ 0, 20, 20, 20, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* " */
+ 0, 0, 20, 20, 20, 62, 20, 20, 62, 20, 20, 20, 0, 0, /* # */
+ 0, 0, 8, 60, 74, 74, 40, 28, 10, 74, 74, 60, 8, 0, /* $ */
+ 0, 0, 50, 74, 76, 56, 8, 16, 28, 50, 82, 76, 0, 0, /* % */
+ 0, 0, 24, 36, 36, 36, 24, 50, 74, 68, 76, 50, 0, 0, /* & */
+ 0, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ' */
+ 0, 2, 4, 8, 8, 16, 16, 16, 16, 16, 8, 8, 4, 2, /* ( */
+ 0, 32, 16, 8, 8, 4, 4, 4, 4, 4, 8, 8, 16, 32, /* ) */
+ 0, 0, 0, 0, 8, 42, 28, 8, 28, 42, 8, 0, 0, 0, /* * */
+ 0, 0, 0, 0, 8, 8, 8, 62, 8, 8, 8, 0, 0, 0, /* + */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 8, 8, 16, /* , */
+ 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0, /* - */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 28, 8, 0, /* . */
+ 0, 2, 2, 4, 4, 8, 8, 8, 16, 16, 32, 32, 64, 64, /* / */
+ 0, 0, 24, 36, 66, 66, 66, 66, 66, 66, 36, 24, 0, 0, /* 0 */
+ 0, 0, 8, 24, 40, 8, 8, 8, 8, 8, 8, 62, 0, 0, /* 1 */
+ 0, 0, 60, 66, 66, 2, 4, 4, 8, 16, 32, 126, 0, 0, /* 2 */
+ 0, 0, 126, 2, 4, 8, 28, 2, 2, 66, 66, 60, 0, 0, /* 3 */
+ 0, 0, 4, 12, 20, 20, 36, 36, 68, 126, 4, 4, 0, 0, /* 4 */
+ 0, 0, 126, 64, 64, 124, 66, 2, 2, 66, 66, 60, 0, 0, /* 5 */
+ 0, 0, 28, 32, 64, 64, 92, 98, 66, 66, 66, 60, 0, 0, /* 6 */
+ 0, 0, 126, 2, 4, 4, 8, 8, 16, 16, 32, 32, 0, 0, /* 7 */
+ 0, 0, 60, 66, 66, 36, 24, 36, 66, 66, 66, 60, 0, 0, /* 8 */
+ 0, 0, 60, 66, 66, 66, 70, 58, 2, 66, 68, 56, 0, 0, /* 9 */
+ 0, 0, 0, 0, 8, 28, 8, 0, 0, 8, 28, 8, 0, 0, /* : */
+ 0, 0, 0, 0, 0, 24, 24, 0, 0, 24, 8, 8, 16, 0, /* ; */
+ 0, 0, 0, 2, 4, 8, 16, 32, 16, 8, 4, 2, 0, 0, /* < */
+ 0, 0, 0, 0, 0, 126, 0, 0, 126, 0, 0, 0, 0, 0, /* = */
+ 0, 0, 0, 32, 16, 8, 4, 2, 4, 8, 16, 32, 0, 0, /* > */
+ 0, 0, 60, 66, 66, 4, 8, 8, 8, 0, 8, 8, 0, 0, /* ? */
+ 0, 0, 28, 34, 78, 82, 82, 82, 82, 78, 32, 30, 0, 0, /* @ */
+ 0, 0, 24, 36, 66, 66, 66, 126, 66, 66, 66, 66, 0, 0, /* A */
+ 0, 0, 120, 68, 66, 68, 120, 68, 66, 66, 68, 120, 0, 0, /* B */
+ 0, 0, 60, 66, 66, 64, 64, 64, 64, 66, 66, 60, 0, 0, /* C */
+ 0, 0, 120, 68, 66, 66, 66, 66, 66, 66, 68, 120, 0, 0, /* D */
+ 0, 0, 126, 64, 64, 64, 120, 64, 64, 64, 64, 126, 0, 0, /* E */
+ 0, 0, 126, 64, 64, 64, 120, 64, 64, 64, 64, 64, 0, 0, /* F */
+ 0, 0, 60, 66, 66, 64, 64, 78, 66, 66, 70, 58, 0, 0, /* G */
+ 0, 0, 66, 66, 66, 66, 126, 66, 66, 66, 66, 66, 0, 0, /* H */
+ 0, 0, 62, 8, 8, 8, 8, 8, 8, 8, 8, 62, 0, 0, /* I */
+ 0, 0, 14, 4, 4, 4, 4, 4, 4, 68, 68, 56, 0, 0, /* J */
+ 0, 0, 66, 68, 72, 80, 96, 80, 72, 68, 66, 66, 0, 0, /* K */
+ 0, 0, 64, 64, 64, 64, 64, 64, 64, 64, 64, 126, 0, 0, /* L */
+ 0, 0, 66, 102, 102, 90, 90, 66, 66, 66, 66, 66, 0, 0, /* M */
+ 0, 0, 66, 66, 98, 98, 82, 74, 70, 70, 66, 66, 0, 0, /* N */
+ 0, 0, 60, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* O */
+ 0, 0, 124, 66, 66, 66, 66, 124, 64, 64, 64, 64, 0, 0, /* P */
+ 0, 0, 60, 66, 66, 66, 66, 66, 114, 74, 70, 60, 4, 2, /* Q */
+ 0, 0, 124, 66, 66, 66, 66, 124, 72, 68, 66, 66, 0, 0, /* R */
+ 0, 0, 60, 66, 66, 64, 48, 12, 2, 66, 66, 60, 0, 0, /* S */
+ 0, 0, 127, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, /* T */
+ 0, 0, 66, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* U */
+ 0, 0, 66, 66, 66, 66, 36, 36, 36, 24, 24, 24, 0, 0, /* V */
+ 0, 0, 34, 34, 34, 34, 34, 34, 42, 42, 42, 20, 0, 0, /* W */
+ 0, 0, 66, 66, 36, 36, 24, 24, 36, 36, 66, 66, 0, 0, /* X */
+ 0, 0, 34, 34, 34, 20, 20, 8, 8, 8, 8, 8, 0, 0, /* Y */
+ 0, 0, 126, 2, 4, 8, 8, 16, 32, 32, 64, 126, 0, 0, /* Z */
+ 0, 30, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 30, /* [ */
+ 0, 64, 64, 32, 32, 16, 16, 16, 8, 8, 4, 4, 2, 2, /* \ */
+ 0, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 60, /* ] */
+ 0, 24, 36, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ^ */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, /* _ */
+ 0, 16, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` */
+ 0, 0, 0, 0, 0, 60, 66, 2, 62, 66, 66, 62, 0, 0, /* a */
+ 0, 0, 64, 64, 64, 92, 98, 66, 66, 66, 98, 92, 0, 0, /* b */
+ 0, 0, 0, 0, 0, 60, 66, 64, 64, 64, 66, 60, 0, 0, /* c */
+ 0, 0, 2, 2, 2, 58, 70, 66, 66, 66, 70, 58, 0, 0, /* d */
+ 0, 0, 0, 0, 0, 60, 66, 66, 126, 64, 66, 60, 0, 0, /* e */
+ 0, 0, 12, 18, 16, 16, 124, 16, 16, 16, 16, 16, 0, 0, /* f */
+ 0, 0, 0, 0, 0, 58, 68, 68, 68, 56, 32, 92, 66, 60, /* g */
+ 0, 0, 64, 64, 64, 92, 98, 66, 66, 66, 66, 66, 0, 0, /* h */
+ 0, 0, 8, 8, 0, 24, 8, 8, 8, 8, 8, 62, 0, 0, /* i */
+ 0, 0, 2, 2, 0, 6, 2, 2, 2, 2, 2, 34, 34, 28, /* j */
+ 0, 0, 64, 64, 64, 68, 72, 80, 112, 72, 68, 66, 0, 0, /* k */
+ 0, 0, 24, 8, 8, 8, 8, 8, 8, 8, 8, 62, 0, 0, /* l */
+ 0, 0, 0, 0, 0, 52, 42, 42, 42, 42, 42, 34, 0, 0, /* m */
+ 0, 0, 0, 0, 0, 92, 98, 66, 66, 66, 66, 66, 0, 0, /* n */
+ 0, 0, 0, 0, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0, /* o */
+ 0, 0, 0, 0, 0, 92, 98, 66, 66, 66, 98, 92, 64, 64, /* p */
+ 0, 0, 0, 0, 0, 58, 70, 66, 66, 66, 70, 58, 2, 2, /* q */
+ 0, 0, 0, 0, 0, 92, 98, 66, 64, 64, 64, 64, 0, 0, /* r */
+ 0, 0, 0, 0, 0, 60, 66, 32, 24, 4, 66, 60, 0, 0, /* s */
+ 0, 0, 16, 16, 16, 124, 16, 16, 16, 16, 18, 12, 0, 0, /* t */
+ 0, 0, 0, 0, 0, 66, 66, 66, 66, 66, 70, 58, 0, 0, /* u */
+ 0, 0, 0, 0, 0, 34, 34, 34, 20, 20, 8, 8, 0, 0, /* v */
+ 0, 0, 0, 0, 0, 34, 34, 42, 42, 42, 42, 20, 0, 0, /* w */
+ 0, 0, 0, 0, 0, 66, 66, 36, 24, 36, 66, 66, 0, 0, /* x */
+ 0, 0, 0, 0, 0, 66, 66, 66, 66, 70, 58, 2, 66, 60, /* y */
+ 0, 0, 0, 0, 0, 126, 4, 8, 16, 16, 32, 126, 0, 0, /* z */
+ 0, 6, 8, 8, 8, 8, 8, 16, 8, 8, 8, 8, 8, 6, /* { */
+ 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* | */
+ 0, 48, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 8, 48, /* } */
+ 0, 32, 82, 74, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ~ */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*  */
+ 0, 0, 8, 8, 0, 8, 8, 8, 8, 8, 8, 8, 0, 0, /* ¡ */
+ 0, 0, 0, 0, 16, 60, 82, 80, 80, 80, 82, 60, 16, 0, /* ¢ */
+ 0, 0, 0, 12, 18, 16, 16, 60, 16, 16, 60, 18, 0, 0, /* £ */
+ 0, 0, 0, 0, 66, 60, 36, 36, 60, 66, 0, 0, 0, 0, /* ¤ */
+ 0, 0, 34, 20, 20, 8, 62, 8, 62, 8, 8, 8, 0, 0, /* ¥ */
+ 0, 0, 8, 8, 8, 8, 0, 0, 8, 8, 8, 8, 0, 0, /* ¦ */
+ 0, 60, 66, 32, 24, 36, 66, 36, 24, 4, 66, 60, 0, 0, /* § */
+ 0, 36, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ¨ */
+ 0, 60, 66, 90, 102, 98, 98, 98, 102, 90, 66, 60, 0, 0, /* © */
+ 0, 28, 34, 30, 34, 38, 26, 0, 62, 0, 0, 0, 0, 0, /* ª */
+ 0, 0, 0, 0, 0, 10, 20, 40, 80, 40, 20, 10, 0, 0, /* « */
+ 0, 0, 0, 0, 0, 0, 0, 0, 62, 2, 2, 2, 0, 0, /* ¬ */
+ 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, /* ­ */
+ 0, 60, 66, 122, 102, 102, 122, 102, 102, 102, 66, 60, 0, 0, /* ® */
+ 0, 0, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ¯ */
+ 0, 24, 36, 36, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ° */
+ 0, 0, 0, 0, 0, 0, 8, 8, 62, 8, 8, 62, 0, 0, /* ± */
+ 0, 24, 36, 4, 8, 16, 32, 60, 0, 0, 0, 0, 0, 0, /* ² */
+ 0, 24, 36, 4, 24, 4, 36, 24, 0, 0, 0, 0, 0, 0, /* ³ */
+ 0, 4, 8, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ´ */
+ 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 54, 42, 32, 32, /* µ */
+ 0, 0, 30, 42, 42, 42, 42, 26, 10, 10, 10, 10, 10, 14, /* ¶ */
+ 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, /* · */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 16, /* ¸ */
+ 0, 8, 24, 8, 8, 8, 8, 28, 0, 0, 0, 0, 0, 0, /* ¹ */
+ 0, 0, 24, 36, 36, 24, 0, 60, 0, 0, 0, 0, 0, 0, /* º */
+ 0, 0, 0, 0, 0, 80, 40, 20, 10, 20, 40, 80, 0, 0, /* » */
+ 0, 0, 32, 98, 36, 36, 40, 18, 22, 42, 78, 66, 0, 0, /* ¼ */
+ 0, 0, 32, 98, 36, 36, 40, 20, 26, 34, 68, 78, 0, 0, /* ½ */
+ 0, 0, 98, 18, 36, 24, 104, 18, 38, 42, 78, 2, 0, 0, /* ¾ */
+ 0, 0, 0, 16, 16, 0, 16, 16, 16, 16, 32, 66, 66, 60, /* ¿ */
+ 16, 8, 0, 24, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0, /* À */
+ 8, 16, 0, 24, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0, /* Ã */
+ 24, 36, 0, 24, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0, /* Â */
+ 50, 76, 0, 24, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0, /* Ã */
+ 0, 36, 0, 24, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0, /* Ä */
+ 0, 24, 36, 24, 36, 66, 66, 126, 66, 66, 66, 66, 0, 0, /* Ã… */
+ 0, 0, 30, 40, 72, 72, 126, 72, 72, 72, 72, 78, 0, 0, /* Æ */
+ 0, 0, 60, 66, 66, 64, 64, 64, 64, 66, 66, 60, 8, 16, /* Ç */
+ 16, 8, 0, 126, 64, 64, 64, 124, 64, 64, 64, 126, 0, 0, /* È */
+ 8, 16, 0, 126, 64, 64, 64, 124, 64, 64, 64, 126, 0, 0, /* É */
+ 24, 36, 0, 126, 64, 64, 64, 124, 64, 64, 64, 126, 0, 0, /* Ê */
+ 0, 36, 0, 126, 64, 64, 64, 124, 64, 64, 64, 126, 0, 0, /* Ë */
+ 16, 8, 0, 62, 8, 8, 8, 8, 8, 8, 8, 62, 0, 0, /* Ì */
+ 4, 8, 0, 62, 8, 8, 8, 8, 8, 8, 8, 62, 0, 0, /* Ã */
+ 8, 20, 0, 62, 8, 8, 8, 8, 8, 8, 8, 62, 0, 0, /* ÃŽ */
+ 0, 20, 0, 62, 8, 8, 8, 8, 8, 8, 8, 62, 0, 0, /* Ã */
+ 0, 0, 60, 34, 33, 33, 121, 33, 33, 33, 34, 60, 0, 0, /* Ã */
+ 50, 76, 0, 98, 98, 82, 82, 74, 74, 74, 70, 70, 0, 0, /* Ñ */
+ 16, 8, 0, 60, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Ã’ */
+ 8, 16, 0, 60, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Ó */
+ 24, 36, 0, 60, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Ô */
+ 50, 76, 0, 60, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Õ */
+ 0, 36, 0, 60, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Ö */
+ 0, 0, 0, 0, 0, 65, 34, 20, 8, 20, 34, 65, 0, 0, /* × */
+ 2, 2, 60, 70, 74, 74, 74, 82, 82, 82, 98, 60, 64, 64, /* Ø */
+ 16, 8, 0, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Ù */
+ 8, 16, 0, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Ú */
+ 24, 36, 0, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Û */
+ 0, 36, 0, 66, 66, 66, 66, 66, 66, 66, 66, 60, 0, 0, /* Ü */
+ 4, 8, 0, 34, 34, 20, 20, 8, 8, 8, 8, 8, 0, 0, /* Ã */
+ 0, 0, 64, 64, 124, 66, 66, 66, 66, 124, 64, 64, 0, 0, /* Þ */
+ 0, 0, 24, 36, 36, 36, 56, 36, 34, 34, 34, 124, 0, 0, /* ß */
+ 0, 0, 16, 8, 0, 60, 66, 14, 50, 66, 70, 58, 0, 0, /* à */
+ 0, 0, 4, 8, 0, 60, 66, 14, 50, 66, 70, 58, 0, 0, /* á */
+ 0, 0, 24, 36, 0, 60, 66, 14, 50, 66, 70, 58, 0, 0, /* â */
+ 0, 0, 50, 76, 0, 60, 66, 14, 50, 66, 70, 58, 0, 0, /* ã */
+ 0, 0, 0, 36, 0, 60, 66, 14, 50, 66, 70, 58, 0, 0, /* ä */
+ 0, 24, 36, 24, 0, 60, 66, 14, 50, 66, 70, 58, 0, 0, /* å */
+ 0, 0, 0, 0, 0, 62, 73, 25, 47, 72, 73, 62, 0, 0, /* æ */
+ 0, 0, 0, 0, 0, 60, 66, 64, 64, 64, 66, 60, 8, 16, /* ç */
+ 0, 0, 16, 8, 0, 60, 66, 66, 126, 64, 66, 60, 0, 0, /* è */
+ 0, 0, 8, 16, 0, 60, 66, 66, 126, 64, 66, 60, 0, 0, /* é */
+ 0, 0, 24, 36, 0, 60, 66, 66, 126, 64, 66, 60, 0, 0, /* ê */
+ 0, 0, 0, 36, 0, 60, 66, 66, 126, 64, 66, 60, 0, 0, /* ë */
+ 0, 0, 16, 8, 0, 24, 8, 8, 8, 8, 8, 62, 0, 0, /* ì */
+ 0, 0, 4, 8, 0, 24, 8, 8, 8, 8, 8, 62, 0, 0, /* í */
+ 0, 0, 24, 36, 0, 24, 8, 8, 8, 8, 8, 62, 0, 0, /* î */
+ 0, 0, 0, 20, 0, 24, 8, 8, 8, 8, 8, 62, 0, 0, /* ï */
+ 0, 20, 8, 20, 2, 30, 34, 34, 34, 34, 34, 28, 0, 0, /* ð */
+ 0, 0, 50, 76, 0, 92, 98, 66, 66, 66, 66, 66, 0, 0, /* ñ */
+ 0, 0, 16, 8, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0, /* ò */
+ 0, 0, 8, 16, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0, /* ó */
+ 0, 0, 24, 36, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0, /* ô */
+ 0, 0, 50, 76, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0, /* õ */
+ 0, 0, 0, 36, 0, 60, 66, 66, 66, 66, 66, 60, 0, 0, /* ö */
+ 0, 0, 0, 0, 0, 0, 0, 24, 0, 126, 0, 24, 0, 0, /* ÷ */
+ 0, 0, 0, 2, 4, 60, 74, 74, 82, 82, 98, 60, 64, 64, /* ø */
+ 0, 0, 16, 8, 0, 66, 66, 66, 66, 66, 70, 58, 0, 0, /* ù */
+ 0, 0, 8, 16, 0, 66, 66, 66, 66, 66, 70, 58, 0, 0, /* ú */
+ 0, 0, 24, 36, 0, 66, 66, 66, 66, 66, 70, 58, 0, 0, /* û */
+ 0, 0, 0, 36, 0, 66, 66, 66, 66, 66, 70, 58, 0, 0, /* ü */
+ 0, 0, 8, 16, 0, 66, 66, 34, 36, 20, 28, 8, 72, 48, /* ý */
+ 0, 0, 64, 64, 64, 92, 98, 66, 66, 66, 98, 92, 64, 64, /* þ */
+ 0, 0, 0, 36, 0, 66, 66, 34, 36, 20, 28, 8, 72, 48, /* ÿ */
};
-static const int small_font_extended[] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,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,1,0,0,0,0,0,0,0,0,
- 1,1,0,0,1,0,1,0,0,1,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,1,1,0,1,1,1,1,0,0,0,1,0,0,
- 0,0,1,0,0,0,1,1,0,0,0,1,1,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,0,0,0,1,0,0,0,1,0,
- 0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,
- 0,1,1,0,0,0,0,0,1,0,0,0,1,1,0,0,
- 0,1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,
- 0,0,1,0,0,1,1,0,0,0,1,1,1,0,0,1,
- 1,0,0,1,1,1,1,0,1,1,1,1,0,1,1,1,
- 1,0,1,1,1,1,0,0,1,1,1,0,0,1,1,1,
- 0,0,1,1,1,0,0,1,1,1,0,1,1,1,0,0,
- 1,0,1,1,0,0,1,1,0,0,0,1,1,0,0,0,
- 1,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,
- 0,0,0,0,1,1,1,0,1,0,0,1,0,1,0,0,
- 1,0,1,0,0,1,0,1,0,0,1,0,0,1,0,1,
- 0,1,0,0,0,0,0,1,1,0,0,0,1,0,0,0,
- 0,0,1,0,0,0,0,1,0,0,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,0,1,0,0,0,0,0,1,0,0,0,1,0,
- 0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,
- 0,0,0,1,0,0,0,1,0,1,0,0,1,0,0,0,
- 0,1,0,1,0,0,1,0,0,0,0,0,1,0,0,0,
- 1,1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,
- 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,
- 0,0,0,1,1,0,0,0,1,0,1,0,0,0,1,0,
- 0,0,0,0,0,0,0,1,0,1,0,
- 0,0,0,0,0,0,0,1,0,0,0,0,1,1,0,1,
- 0,0,0,1,0,1,0,1,0,0,0,1,0,0,0,1,
- 0,0,0,0,0,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,0,0,0,1,0,0,0,0,0,0,1,0,1,0,
- 0,0,1,0,0,0,0,1,0,0,0,1,1,0,0,0,
- 1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,
- 0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,1,
- 0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,
- 0,1,1,0,0,0,0,0,0,0,0,1,0,0,1,0,
- 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,
- 1,1,0,0,0,1,1,0,0,1,0,1,0,0,1,0,
- 0,1,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,1,0,
- 0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,
- 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,
- 0,0,1,0,1,0,0,1,0,0,1,1,0,0,0,0,
- 0,0,0,1,0,1,1,0,1,0,0,1,0,1,0,0,
- 1,0,1,0,0,1,0,0,0,0,0,0,0,1,0,1,
- 0,1,1,1,0,0,1,0,0,1,0,0,0,1,0,0,
- 0,1,0,0,0,0,1,0,1,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,1,0,0,0,1,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,0,0,0,0,1,1,0,
- 1,0,1,0,0,0,0,1,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,1,0,0,0,1,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,1,0,0,0,1,1,1,0,0,1,0,0,0,0,
- 1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,
- 1,0,0,0,0,0,0,0,1,0,1,0,1,0,1,1,
- 0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,
- 0,1,1,1,0,1,0,0,0,0,0,0,0,1,0,0,
- 1,1,1,1,1,0,1,0,0,0,0,0,1,0,0,0,
- 0,0,0,0,1,0,0,1,0,1,1,0,1,0,0,1,
- 1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,
- 0,0,1,0,0,1,0,1,0,0,0,0,1,0,0,0,
- 0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,
- 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,
- 0,0,1,0,1,0,0,1,0,1,0,1,1,0,1,0,
- 0,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1,
- 0,0,1,1,1,0,0,0,0,1,0,0,0,0,1,0,
- 0,0,0,1,0,0,0,0,1,0,0,1,1,0,1,0,
- 1,1,0,1,0,1,0,0,1,0,1,0,0,1,0,1,
- 0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,
- 0,1,0,1,0,1,1,0,1,0,0,1,0,1,0,0,
- 1,0,1,0,0,1,0,1,0,0,1,0,0,1,0,1,
- 0,1,0,0,1,0,1,0,1,0,0,0,1,1,1,0,
- 0,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,
- 1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,0,
- 1,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,
- 0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,
- 0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,0,
- 1,1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,
- 1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,0,
- 0,0,0,0,1,1,1,0,1,0,0,1,0,1,0,0,
- 1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,
- 0,1,1,1,0,0,1,0,0,1,0,
- 0,0,1,0,0,1,0,1,0,0,1,1,1,0,0,0,
- 1,0,1,0,0,1,1,1,0,0,0,0,0,0,0,1,
- 0,1,0,0,0,0,0,0,1,1,0,0,1,0,0,0,
- 0,0,1,0,0,1,0,1,1,1,1,0,0,0,0,0,
- 0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,
- 0,0,1,0,0,0,1,1,0,0,0,1,1,0,0,0,
- 0,0,0,0,1,0,0,1,0,0,1,0,1,0,0,1,
- 1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,
- 0,0,0,1,0,0,1,1,0,0,1,0,1,0,1,1,
- 0,1,1,0,1,0,0,1,0,0,0,1,1,1,1,0,
- 1,1,1,1,0,1,1,1,1,0,1,1,1,1,0,1,
- 1,1,1,0,1,1,1,1,0,1,1,1,0,0,1,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,1,0,
- 0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,
- 1,0,1,1,0,1,0,0,1,0,1,0,0,1,0,1,
- 0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,1,
- 1,0,0,1,1,0,1,0,1,0,0,1,0,1,0,0,
- 1,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,
- 0,1,1,1,0,0,1,0,0,1,0,1,0,0,1,0,
- 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,
- 0,0,1,0,1,0,0,1,0,1,0,1,1,0,0,1,
- 0,0,0,1,0,1,1,0,1,0,1,1,0,1,0,1,
- 1,0,1,0,1,1,0,0,0,1,0,0,0,0,1,0,
- 0,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0,
- 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,
- 0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,1,
- 1,1,0,1,0,1,1,0,1,0,0,1,0,1,0,0,
- 1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,1,
- 0,1,0,0,1,0,1,0,0,1,0,
- 0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,
- 1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,0,
- 1,1,0,0,0,0,0,0,1,0,1,0,1,0,0,0,
- 0,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,
- 0,1,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,0,0,0,
- 0,0,0,0,1,0,0,1,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,1,0,0,1,0,0,0,1,1,0,0,0,0,1,
- 0,0,0,1,1,0,0,1,0,1,0,1,0,0,1,0,
- 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,
- 0,0,1,0,1,0,0,1,0,1,0,1,0,0,1,0,
- 0,1,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,1,0,
- 0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,
- 1,0,1,1,0,1,0,0,1,0,1,0,0,1,0,1,
- 0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,1,
- 1,0,0,1,1,0,1,0,1,0,0,1,0,1,0,0,
- 1,0,1,0,0,1,0,1,0,0,1,0,0,0,1,0,
- 0,1,0,0,0,0,1,0,0,1,0,1,0,1,1,0,
- 1,0,1,1,0,1,0,1,1,0,1,0,1,1,0,1,
- 0,1,1,0,1,0,1,1,0,1,0,1,0,0,0,1,
- 0,0,0,1,1,0,0,0,1,1,0,0,0,1,1,0,
- 0,0,1,1,0,0,0,0,0,1,0,0,0,0,1,0,
- 0,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0,
- 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,
- 0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,
- 0,0,0,1,1,0,1,0,1,0,0,1,0,1,0,0,
- 1,0,1,0,0,1,0,1,0,0,1,0,0,1,0,1,
- 0,1,0,0,1,0,0,1,0,1,0,
- 0,0,1,0,0,0,1,1,1,0,1,0,1,1,0,1,
- 0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,
- 0,1,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,1,0,0,0,1,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,1,1,1,0,0,0,1,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,1,1,1,0,0,0,1,0,
- 0,0,1,1,1,0,0,0,1,0,0,1,0,0,1,0,
- 1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,
- 0,0,1,0,1,0,0,1,0,1,0,1,1,0,0,1,
- 1,0,0,1,1,1,1,0,1,1,1,1,0,1,1,1,
- 1,0,1,1,1,1,0,0,1,1,1,0,0,1,1,1,
- 0,0,1,1,1,0,0,1,1,1,0,1,1,1,0,0,
- 1,0,0,1,0,0,1,1,0,0,0,1,1,0,0,0,
- 1,1,0,0,0,1,1,0,0,0,1,1,0,0,1,0,
- 0,1,0,1,1,1,0,0,0,1,1,0,0,0,1,1,
- 0,0,0,1,1,0,0,0,1,1,0,0,0,0,1,0,
- 0,1,0,0,0,0,1,0,1,0,0,0,1,0,1,0,
- 0,1,0,1,0,0,1,0,1,0,0,1,0,1,0,0,
- 1,0,1,0,0,1,0,1,0,0,1,1,1,0,0,0,
- 1,1,0,0,1,1,0,0,0,1,1,0,0,0,1,1,
- 0,0,0,1,1,0,0,0,1,1,1,0,0,1,1,1,
- 0,0,1,1,1,0,0,1,1,1,0,0,1,1,0,0,
- 1,0,0,1,0,0,1,1,0,0,0,1,1,0,0,0,
- 1,1,0,0,0,1,1,0,0,0,1,1,0,0,0,1,
- 1,0,0,1,1,1,0,0,0,1,1,1,0,0,1,1,
- 1,0,0,1,1,1,0,0,1,1,1,0,0,0,1,0,
- 0,1,1,1,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,1,
- 1,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,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,1,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,1,0,0,0,1,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,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,
- 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,1,0,0,
- 0,1,0,0,0,0,0,1,0,0,0
+static const char small_font[] = {
+ /* Each character is 5 x 9 pixels */
+ 0, 2, 2, 2, 2, 0, 2, 0, 0, /* ! */
+ 0, 5, 5, 5, 0, 0, 0, 0, 0, /* " */
+ 0, 0, 5, 15, 5, 15, 5, 0, 0, /* # */
+ 0, 0, 7, 26, 7, 18, 7, 0, 0, /* $ */
+ 0, 8, 9, 2, 4, 25, 1, 0, 0, /* % */
+ 0, 0, 4, 10, 4, 10, 5, 0, 0, /* & */
+ 0, 2, 2, 2, 0, 0, 0, 0, 0, /* ' */
+ 0, 2, 4, 4, 4, 4, 2, 0, 0, /* ( */
+ 0, 4, 2, 2, 2, 2, 4, 0, 0, /* ) */
+ 0, 0, 5, 2, 7, 2, 5, 0, 0, /* * */
+ 0, 0, 2, 2, 15, 2, 2, 0, 0, /* + */
+ 0, 0, 0, 0, 16, 3, 2, 4, 0, /* , */
+ 0, 0, 0, 0, 15, 0, 0, 0, 0, /* - */
+ 0, 0, 0, 0, 0, 6, 6, 0, 0, /* . */
+ 0, 0, 1, 2, 4, 8, 0, 0, 0, /* / */
+ 0, 2, 5, 5, 5, 5, 2, 0, 0, /* 0 */
+ 0, 2, 6, 2, 2, 2, 7, 0, 0, /* 1 */
+ 0, 6, 9, 1, 2, 4, 15, 0, 0, /* 2 */
+ 0, 15, 1, 6, 1, 9, 6, 0, 0, /* 3 */
+ 0, 2, 6, 10, 15, 2, 2, 0, 0, /* 4 */
+ 0, 15, 8, 14, 1, 9, 6, 0, 0, /* 5 */
+ 0, 6, 8, 14, 9, 9, 6, 0, 0, /* 6 */
+ 0, 15, 1, 2, 2, 4, 4, 0, 0, /* 7 */
+ 0, 6, 9, 6, 9, 9, 6, 0, 0, /* 8 */
+ 0, 6, 9, 9, 7, 1, 6, 0, 0, /* 9 */
+ 0, 0, 6, 6, 0, 6, 6, 0, 0, /* : */
+ 0, 0, 6, 6, 0, 6, 4, 8, 0, /* ; */
+ 0, 0, 1, 2, 4, 2, 1, 0, 0, /* < */
+ 0, 0, 0, 15, 0, 15, 0, 0, 0, /* = */
+ 0, 0, 4, 2, 1, 2, 4, 0, 0, /* > */
+ 0, 2, 5, 1, 2, 0, 2, 0, 0, /* ? */
+ 0, 6, 9, 11, 11, 8, 6, 0, 0, /* @ */
+ 0, 6, 9, 9, 15, 9, 9, 0, 0, /* A */
+ 0, 14, 9, 14, 9, 9, 14, 0, 0, /* B */
+ 0, 6, 9, 8, 8, 9, 6, 0, 0, /* C */
+ 0, 14, 9, 9, 9, 9, 14, 0, 0, /* D */
+ 0, 15, 8, 14, 8, 8, 15, 0, 0, /* E */
+ 0, 15, 8, 14, 8, 8, 8, 0, 0, /* F */
+ 0, 6, 9, 8, 11, 9, 7, 0, 0, /* G */
+ 0, 9, 9, 15, 9, 9, 9, 0, 0, /* H */
+ 0, 7, 2, 2, 2, 2, 7, 0, 0, /* I */
+ 0, 1, 1, 1, 1, 9, 6, 0, 0, /* J */
+ 0, 9, 10, 12, 12, 10, 9, 0, 0, /* K */
+ 0, 8, 8, 8, 8, 8, 15, 0, 0, /* L */
+ 0, 9, 15, 15, 9, 9, 9, 0, 0, /* M */
+ 0, 9, 13, 13, 11, 11, 9, 0, 0, /* N */
+ 0, 6, 9, 9, 9, 9, 6, 0, 0, /* O */
+ 0, 14, 9, 9, 14, 8, 8, 0, 0, /* P */
+ 0, 6, 9, 9, 9, 13, 6, 1, 0, /* Q */
+ 0, 14, 9, 9, 14, 10, 9, 0, 0, /* R */
+ 0, 6, 9, 4, 2, 9, 6, 0, 0, /* S */
+ 0, 7, 2, 2, 2, 2, 2, 0, 0, /* T */
+ 0, 9, 9, 9, 9, 9, 6, 0, 0, /* U */
+ 0, 9, 9, 9, 9, 6, 6, 0, 0, /* V */
+ 0, 9, 9, 9, 15, 15, 9, 0, 0, /* W */
+ 0, 9, 9, 6, 6, 9, 9, 0, 0, /* X */
+ 0, 5, 5, 5, 2, 2, 2, 0, 0, /* Y */
+ 0, 15, 1, 2, 4, 8, 15, 0, 0, /* Z */
+ 0, 7, 4, 4, 4, 4, 7, 0, 0, /* [ */
+ 0, 0, 8, 4, 2, 1, 0, 0, 0, /* \ */
+ 0, 7, 1, 1, 1, 1, 7, 0, 0, /* ] */
+ 0, 2, 5, 0, 0, 0, 0, 0, 0, /* ^ */
+ 0, 0, 0, 0, 0, 0, 15, 0, 0, /* _ */
+ 0, 4, 2, 0, 0, 0, 0, 0, 0, /* ` */
+ 0, 0, 0, 7, 9, 11, 5, 0, 0, /* a */
+ 0, 8, 8, 14, 9, 9, 14, 0, 0, /* b */
+ 0, 0, 0, 6, 8, 8, 6, 0, 0, /* c */
+ 0, 1, 1, 7, 9, 9, 7, 0, 0, /* d */
+ 0, 0, 0, 6, 11, 12, 6, 0, 0, /* e */
+ 0, 2, 5, 4, 14, 4, 4, 0, 0, /* f */
+ 0, 0, 0, 7, 9, 6, 8, 7, 0, /* g */
+ 0, 8, 8, 14, 9, 9, 9, 0, 0, /* h */
+ 0, 2, 0, 6, 2, 2, 7, 0, 0, /* i */
+ 0, 1, 0, 1, 1, 1, 5, 2, 0, /* j */
+ 0, 8, 8, 10, 12, 10, 9, 0, 0, /* k */
+ 0, 6, 2, 2, 2, 2, 7, 0, 0, /* l */
+ 0, 0, 0, 10, 15, 9, 9, 0, 0, /* m */
+ 0, 0, 0, 14, 9, 9, 9, 0, 0, /* n */
+ 0, 0, 0, 6, 9, 9, 6, 0, 0, /* o */
+ 0, 0, 0, 14, 9, 9, 14, 8, 0, /* p */
+ 0, 0, 0, 7, 9, 9, 7, 1, 0, /* q */
+ 0, 0, 0, 14, 9, 8, 8, 0, 0, /* r */
+ 0, 0, 0, 7, 12, 3, 14, 0, 0, /* s */
+ 0, 4, 4, 14, 4, 4, 3, 0, 0, /* t */
+ 0, 0, 0, 9, 9, 9, 7, 0, 0, /* u */
+ 0, 0, 0, 5, 5, 5, 2, 0, 0, /* v */
+ 0, 0, 0, 9, 9, 15, 15, 0, 0, /* w */
+ 0, 0, 0, 9, 6, 6, 9, 0, 0, /* x */
+ 0, 0, 0, 9, 9, 5, 2, 4, 0, /* y */
+ 0, 0, 0, 15, 2, 4, 15, 0, 0, /* z */
+ 0, 1, 2, 6, 2, 2, 1, 0, 0, /* { */
+ 0, 2, 2, 2, 2, 2, 2, 0, 0, /* | */
+ 0, 4, 2, 3, 2, 2, 4, 0, 0, /* } */
+ 0, 5, 10, 0, 0, 0, 0, 0, 0, /* ~ */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, /*  */
+ 0, 2, 0, 2, 2, 2, 2, 0, 0, /* ¡ */
+ 0, 0, 2, 7, 10, 10, 7, 2, 0, /* ¢ */
+ 0, 0, 3, 4, 14, 4, 11, 0, 0, /* £ */
+ 0, 0, 8, 7, 5, 7, 8, 0, 0, /* ¤ */
+ 0, 5, 21, 2, 7, 2, 18, 0, 0, /* ¥ */
+ 0, 0, 2, 2, 0, 2, 2, 0, 0, /* ¦ */
+ 0, 3, 4, 6, 5, 3, 1, 6, 0, /* § */
+ 0, 5, 0, 0, 0, 0, 0, 0, 0, /* ¨ */
+ 0, 7, 8, 10, 12, 10, 8, 7, 0, /* © */
+ 0, 6, 26, 22, 16, 16, 16, 0, 0, /* ª */
+ 0, 0, 0, 4, 9, 4, 0, 0, 0, /* « */
+ 0, 0, 0, 16, 15, 17, 0, 0, 0, /* ¬ */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ­ */
+ 0, 7, 8, 14, 12, 12, 8, 7, 0, /* ® */
+ 0, 15, 16, 16, 16, 16, 16, 0, 0, /* ¯ */
+ 0, 2, 5, 2, 0, 0, 0, 0, 0, /* ° */
+ 0, 2, 2, 15, 2, 2, 15, 0, 0, /* ± */
+ 0, 6, 2, 20, 6, 0, 16, 0, 0, /* ² */
+ 0, 6, 6, 2, 6, 0, 0, 0, 0, /* ³ */
+ 0, 2, 4, 0, 0, 0, 0, 0, 0, /* ´ */
+ 0, 0, 0, 9, 9, 9, 14, 8, 0, /* µ */
+ 0, 7, 13, 13, 5, 5, 5, 0, 0, /* ¶ */
+ 0, 0, 0, 6, 6, 0, 0, 0, 0, /* · */
+ 0, 0, 0, 0, 0, 0, 2, 4, 0, /* ¸ */
+ 0, 2, 6, 2, 7, 0, 0, 0, 0, /* ¹ */
+ 0, 4, 10, 4, 0, 0, 0, 0, 0, /* º */
+ 0, 0, 0, 9, 4, 9, 0, 0, 0, /* » */
+ 0, 8, 8, 8, 25, 3, 7, 1, 0, /* ¼ */
+ 0, 8, 8, 8, 11, 1, 2, 3, 0, /* ½ */
+ 0, 12, 12, 4, 13, 3, 7, 1, 0, /* ¾ */
+ 0, 2, 0, 2, 4, 5, 2, 0, 0, /* ¿ */
+ 0, 6, 9, 9, 15, 9, 9, 0, 0, /* À */
+ 0, 6, 9, 9, 15, 9, 9, 0, 0, /* Ã */
+ 0, 6, 9, 9, 15, 9, 9, 0, 0, /* Â */
+ 0, 6, 9, 9, 15, 9, 9, 0, 0, /* Ã */
+ 0, 9, 6, 9, 15, 9, 9, 0, 0, /* Ä */
+ 0, 6, 6, 9, 15, 9, 9, 0, 0, /* Ã… */
+ 0, 7, 10, 11, 14, 10, 11, 0, 0, /* Æ */
+ 0, 6, 9, 8, 8, 9, 6, 4, 0, /* Ç */
+ 0, 15, 8, 14, 8, 8, 15, 0, 0, /* È */
+ 0, 15, 8, 14, 8, 8, 15, 0, 0, /* É */
+ 0, 15, 8, 14, 8, 8, 15, 0, 0, /* Ê */
+ 0, 15, 8, 14, 8, 8, 15, 0, 0, /* Ë */
+ 0, 7, 2, 2, 2, 2, 7, 0, 0, /* Ì */
+ 0, 7, 2, 2, 2, 2, 7, 0, 0, /* Ã */
+ 0, 7, 2, 2, 2, 2, 7, 0, 0, /* ÃŽ */
+ 0, 7, 2, 2, 2, 2, 7, 0, 0, /* Ã */
+ 0, 14, 5, 13, 5, 5, 14, 0, 0, /* Ã */
+ 0, 11, 9, 13, 11, 11, 9, 0, 0, /* Ñ */
+ 0, 6, 9, 9, 9, 9, 6, 0, 0, /* Ã’ */
+ 0, 6, 9, 9, 9, 9, 6, 0, 0, /* Ó */
+ 0, 6, 9, 9, 9, 9, 6, 0, 0, /* Ô */
+ 0, 6, 9, 9, 9, 9, 6, 0, 0, /* Õ */
+ 0, 9, 6, 9, 9, 9, 6, 0, 0, /* Ö */
+ 0, 0, 0, 9, 6, 6, 9, 0, 0, /* × */
+ 0, 7, 11, 11, 13, 13, 14, 0, 0, /* Ø */
+ 0, 9, 9, 9, 9, 9, 6, 0, 0, /* Ù */
+ 0, 9, 9, 9, 9, 9, 6, 0, 0, /* Ú */
+ 0, 9, 9, 9, 9, 9, 6, 0, 0, /* Û */
+ 0, 9, 0, 9, 9, 9, 6, 0, 0, /* Ü */
+ 0, 5, 5, 5, 2, 2, 2, 0, 0, /* Ã */
+ 0, 8, 14, 9, 14, 8, 8, 0, 0, /* Þ */
+ 0, 6, 9, 10, 9, 9, 10, 0, 0, /* ß */
+ 0, 4, 2, 7, 9, 11, 5, 0, 0, /* à */
+ 0, 2, 4, 7, 9, 11, 5, 0, 0, /* á */
+ 0, 2, 5, 7, 9, 11, 5, 0, 0, /* â */
+ 0, 5, 10, 7, 9, 11, 5, 0, 0, /* ã */
+ 0, 5, 0, 7, 9, 11, 5, 0, 0, /* ä */
+ 0, 6, 6, 7, 9, 11, 5, 0, 0, /* å */
+ 0, 0, 0, 7, 11, 10, 7, 0, 0, /* æ */
+ 0, 0, 0, 3, 4, 4, 3, 2, 0, /* ç */
+ 0, 4, 2, 6, 11, 12, 6, 0, 0, /* è */
+ 0, 2, 4, 6, 11, 12, 6, 0, 0, /* é */
+ 0, 4, 10, 6, 11, 12, 6, 0, 0, /* ê */
+ 0, 10, 0, 6, 11, 12, 6, 0, 0, /* ë */
+ 0, 4, 2, 6, 2, 2, 7, 0, 0, /* ì */
+ 0, 2, 4, 6, 2, 2, 7, 0, 0, /* í */
+ 0, 2, 5, 6, 2, 2, 7, 0, 0, /* î */
+ 0, 5, 0, 6, 2, 2, 7, 0, 0, /* ï */
+ 0, 4, 3, 6, 9, 9, 6, 0, 0, /* ð */
+ 0, 5, 10, 14, 9, 9, 9, 0, 0, /* ñ */
+ 0, 4, 2, 6, 9, 9, 6, 0, 0, /* ò */
+ 0, 2, 4, 6, 9, 9, 6, 0, 0, /* ó */
+ 0, 6, 0, 6, 9, 9, 6, 0, 0, /* ô */
+ 0, 5, 10, 6, 9, 9, 6, 0, 0, /* õ */
+ 0, 5, 0, 6, 9, 9, 6, 0, 0, /* ö */
+ 0, 0, 6, 0, 15, 0, 6, 0, 0, /* ÷ */
+ 0, 0, 0, 7, 11, 13, 14, 0, 0, /* ø */
+ 0, 4, 2, 9, 9, 9, 7, 0, 0, /* ù */
+ 0, 2, 4, 9, 9, 9, 7, 0, 0, /* ú */
+ 0, 6, 0, 9, 9, 9, 7, 0, 0, /* û */
+ 0, 5, 0, 9, 9, 9, 7, 0, 0, /* ü */
+ 0, 2, 4, 9, 9, 5, 2, 4, 0, /* ý */
+ 0, 0, 8, 14, 9, 9, 14, 8, 0, /* þ */
+ 0, 5, 0, 9, 9, 5, 2, 4, 0, /* ÿ */
};
diff --git a/backend/gb18030.c b/backend/gb18030.c
new file mode 100644
index 0000000..ae67fd7
--- /dev/null
+++ b/backend/gb18030.c
@@ -0,0 +1,2968 @@
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008-2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+/*
+ * Adapted from GNU LIBICONV library and patched to allow 2 duplicate mappings
+ * for compatibility with GB 2312 (GB2312.TXT):
+ * 1) U+30FB to 0xA1A4 (duplicate of U+00B7)
+ * 2) U+2015 to 0xA1AA (duplicate of U+2014)
+ */
+/*
+ * Copyright (C) 1999-2001, 2005, 2012, 2016 Free Software Foundation, Inc.
+ * This file is part of the GNU LIBICONV Library.
+ *
+ * The GNU LIBICONV Library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * The GNU LIBICONV Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the GNU LIBICONV Library; see the file COPYING.LIB.
+ * If not, see <https://www.gnu.org/licenses/>.
+ */
+#include <string.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+#include "common.h"
+#include "gb2312.h"
+#include "gb18030.h"
+
+INTERNAL int utf_to_eci(const int eci, const unsigned char source[], unsigned char dest[], size_t *length); /* Convert Unicode to other encodings */
+
+/*
+ * CP936 extensions (libiconv-1.16/lib/cp936ext.h)
+ */
+
+static const unsigned short cp936ext_page01[16] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xa8bd, 0x0000, 0x0000, 0x0000, /*0x40-0x47*/
+ 0xa8be, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x48-0x4f*/
+};
+static const unsigned short cp936ext_page02[24] = {
+ 0x0000, 0xa8bb, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x50-0x57*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x58-0x5f*/
+ 0x0000, 0xa8c0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x60-0x67*/
+};
+static const unsigned short cp936ext_pagefe[24] = {
+ 0x0000, 0xa6f2, 0x0000, 0xa6f4, 0xa6f5, 0xa6e0, 0xa6e1, 0xa6f0, /*0x30-0x37*/
+ 0xa6f1, 0xa6e2, 0xa6e3, 0xa6ee, 0xa6ef, 0xa6e6, 0xa6e7, 0xa6e4, /*0x38-0x3f*/
+ 0xa6e5, 0xa6e8, 0xa6e9, 0xa6ea, 0xa6eb, 0x0000, 0x0000, 0x0000, /*0x40-0x47*/
+};
+
+static int cp936ext_wctomb(unsigned int* r, unsigned int wc) {
+ unsigned short c = 0;
+ if (wc >= 0x0140 && wc < 0x0150) {
+ c = cp936ext_page01[wc-0x0140];
+ } else if (wc >= 0x0250 && wc < 0x0268) {
+ c = cp936ext_page02[wc-0x0250];
+ } else if (wc >= 0xfe30 && wc < 0xfe48) {
+ c = cp936ext_pagefe[wc-0xfe30];
+ }
+ if (c != 0) {
+ *r = c;
+ return 2;
+ }
+ return 0;
+}
+
+/*
+ * GBK extensions (libiconv-1.16/lib/gbkext_inv.h)
+ */
+
+static const unsigned short gbkext_inv_2charset[14313] = {
+ 0xa840, 0xa841, 0xa842, 0xa95c, 0xa843, 0xa844, 0xa845, 0xa846,
+ 0xa847, 0xa848, 0xa959, 0xa849, 0xa84a, 0xa84b, 0xa84c, 0xa84d,
+ 0xa84e, 0xa84f, 0xa850, 0xa851, 0xa852, 0xa892, 0xa853, 0xa854,
+ 0xa855, 0xa856, 0xa857, 0xa858, 0xa859, 0xa85a, 0xa85b, 0xa85c,
+ 0xa85d, 0xa85e, 0xa85f, 0xa860, 0xa861, 0xa862, 0xa863, 0xa864,
+ 0xa865, 0xa866, 0xa867, 0xa868, 0xa869, 0xa86a, 0xa86b, 0xa86c,
+ 0xa86d, 0xa86e, 0xa86f, 0xa870, 0xa871, 0xa872, 0xa873, 0xa874,
+ 0xa875, 0xa876, 0xa877, 0xa878, 0xa879, 0xa87a, 0xa87b, 0xa87c,
+ 0xa87d, 0xa87e, 0xa880, 0xa881, 0xa882, 0xa883, 0xa884, 0xa885,
+ 0xa886, 0xa887, 0xa888, 0xa889, 0xa88a, 0xa88b, 0xa88c, 0xa88d,
+ 0xa88e, 0xa88f, 0xa890, 0xa891, 0xa965, 0xa996, 0xa893, 0xa894,
+ 0xa895, 0xa940, 0xa941, 0xa942, 0xa943, 0xa944, 0xa945, 0xa946,
+ 0xa947, 0xa948, 0xa961, 0xa962, 0xa966, 0xa967, 0xa960, 0xa963,
+ 0xa964, 0xa95a, 0xa949, 0xa94a, 0xa94b, 0xa94c, 0xa94d, 0xa94e,
+ 0xa94f, 0xa950, 0xa951, 0xa952, 0xa953, 0xa954, 0x8140, 0x8141,
+ 0x8142, 0x8143, 0x8144, 0x8145, 0x8146, 0x8147, 0x8148, 0x8149,
+ 0x814a, 0x814b, 0x814c, 0x814d, 0x814e, 0x814f, 0x8150, 0x8151,
+ 0x8152, 0x8153, 0x8154, 0x8155, 0x8156, 0x8157, 0x8158, 0x8159,
+ 0x815a, 0x815b, 0x815c, 0x815d, 0x815e, 0x815f, 0x8160, 0x8161,
+ 0x8162, 0x8163, 0x8164, 0x8165, 0x8166, 0x8167, 0x8168, 0x8169,
+ 0x816a, 0x816b, 0x816c, 0x816d, 0x816e, 0x816f, 0x8170, 0x8171,
+ 0x8172, 0x8173, 0x8174, 0x8175, 0x8176, 0x8177, 0x8178, 0x8179,
+ 0x817a, 0x817b, 0x817c, 0x817d, 0x817e, 0x8180, 0x8181, 0x8182,
+ 0x8183, 0x8184, 0x8185, 0x8186, 0x8187, 0x8188, 0x8189, 0x818a,
+ 0x818b, 0x818c, 0x818d, 0x818e, 0x818f, 0x8190, 0x8191, 0x8192,
+ 0x8193, 0x8194, 0x8195, 0x8196, 0x8197, 0x8198, 0x8199, 0x819a,
+ 0x819b, 0x819c, 0x819d, 0x819e, 0x819f, 0x81a0, 0x81a1, 0x81a2,
+ 0x81a3, 0x81a4, 0x81a5, 0x81a6, 0x81a7, 0x81a8, 0x81a9, 0x81aa,
+ 0x81ab, 0x81ac, 0x81ad, 0x81ae, 0x81af, 0x81b0, 0x81b1, 0x81b2,
+ 0x81b3, 0x81b4, 0x81b5, 0x81b6, 0x81b7, 0x81b8, 0x81b9, 0x81ba,
+ 0x81bb, 0x81bc, 0x81bd, 0x81be, 0x81bf, 0x81c0, 0x81c1, 0x81c2,
+ 0x81c3, 0x81c4, 0x81c5, 0x81c6, 0x81c7, 0x81c8, 0x81c9, 0x81ca,
+ 0x81cb, 0x81cc, 0x81cd, 0x81ce, 0x81cf, 0x81d0, 0x81d1, 0x81d2,
+ 0x81d3, 0x81d4, 0x81d5, 0x81d6, 0x81d7, 0x81d8, 0x81d9, 0x81da,
+ 0x81db, 0x81dc, 0x81dd, 0x81de, 0x81df, 0x81e0, 0x81e1, 0x81e2,
+ 0x81e3, 0x81e4, 0x81e5, 0x81e6, 0x81e7, 0x81e8, 0x81e9, 0x81ea,
+ 0x81eb, 0x81ec, 0x81ed, 0x81ee, 0x81ef, 0x81f0, 0x81f1, 0x81f2,
+ 0x81f3, 0x81f4, 0x81f5, 0x81f6, 0x81f7, 0x81f8, 0x81f9, 0x81fa,
+ 0x81fb, 0x81fc, 0x81fd, 0x81fe, 0x8240, 0x8241, 0x8242, 0x8243,
+ 0x8244, 0x8245, 0x8246, 0x8247, 0x8248, 0x8249, 0x824a, 0x824b,
+ 0x824c, 0x824d, 0x824e, 0x824f, 0x8250, 0x8251, 0x8252, 0x8253,
+ 0x8254, 0x8255, 0x8256, 0x8257, 0x8258, 0x8259, 0x825a, 0x825b,
+ 0x825c, 0x825d, 0x825e, 0x825f, 0x8260, 0x8261, 0x8262, 0x8263,
+ 0x8264, 0x8265, 0x8266, 0x8267, 0x8268, 0x8269, 0x826a, 0x826b,
+ 0x826c, 0x826d, 0x826e, 0x826f, 0x8270, 0x8271, 0x8272, 0x8273,
+ 0x8274, 0x8275, 0x8276, 0x8277, 0x8278, 0x8279, 0x827a, 0x827b,
+ 0x827c, 0x827d, 0x827e, 0x8280, 0x8281, 0x8282, 0x8283, 0x8284,
+ 0x8285, 0x8286, 0x8287, 0x8288, 0x8289, 0x828a, 0x828b, 0x828c,
+ 0x828d, 0x828e, 0x828f, 0x8290, 0x8291, 0x8292, 0x8293, 0x8294,
+ 0x8295, 0x8296, 0x8297, 0x8298, 0x8299, 0x829a, 0x829b, 0x829c,
+ 0x829d, 0x829e, 0x829f, 0x82a0, 0x82a1, 0x82a2, 0x82a3, 0x82a4,
+ 0x82a5, 0x82a6, 0x82a7, 0x82a8, 0x82a9, 0x82aa, 0x82ab, 0x82ac,
+ 0x82ad, 0x82ae, 0x82af, 0x82b0, 0x82b1, 0x82b2, 0x82b3, 0x82b4,
+ 0x82b5, 0x82b6, 0x82b7, 0x82b8, 0x82b9, 0x82ba, 0x82bb, 0x82bc,
+ 0x82bd, 0x82be, 0x82bf, 0x82c0, 0x82c1, 0x82c2, 0x82c3, 0x82c4,
+ 0x82c5, 0x82c6, 0x82c7, 0x82c8, 0x82c9, 0x82ca, 0x82cb, 0x82cc,
+ 0x82cd, 0x82ce, 0x82cf, 0x82d0, 0x82d1, 0x82d2, 0x82d3, 0x82d4,
+ 0x82d5, 0x82d6, 0x82d7, 0x82d8, 0x82d9, 0x82da, 0x82db, 0x82dc,
+ 0x82dd, 0x82de, 0x82df, 0x82e0, 0x82e1, 0x82e2, 0x82e3, 0x82e4,
+ 0x82e5, 0x82e6, 0x82e7, 0x82e8, 0x82e9, 0x82ea, 0x82eb, 0x82ec,
+ 0x82ed, 0x82ee, 0x82ef, 0x82f0, 0x82f1, 0x82f2, 0x82f3, 0x82f4,
+ 0x82f5, 0x82f6, 0x82f7, 0x82f8, 0x82f9, 0x82fa, 0x82fb, 0x82fc,
+ 0x82fd, 0x82fe, 0x8340, 0x8341, 0x8342, 0x8343, 0x8344, 0x8345,
+ 0x8346, 0x8347, 0x8348, 0x8349, 0x834a, 0x834b, 0x834c, 0x834d,
+ 0x834e, 0x834f, 0x8350, 0x8351, 0x8352, 0x8353, 0x8354, 0x8355,
+ 0x8356, 0x8357, 0x8358, 0x8359, 0x835a, 0x835b, 0x835c, 0x835d,
+ 0x835e, 0x835f, 0x8360, 0x8361, 0x8362, 0x8363, 0x8364, 0x8365,
+ 0x8366, 0x8367, 0x8368, 0x8369, 0x836a, 0x836b, 0x836c, 0x836d,
+ 0x836e, 0x836f, 0x8370, 0x8371, 0x8372, 0x8373, 0x8374, 0x8375,
+ 0x8376, 0x8377, 0x8378, 0x8379, 0x837a, 0x837b, 0x837c, 0x837d,
+ 0x837e, 0x8380, 0x8381, 0x8382, 0x8383, 0x8384, 0x8385, 0x8386,
+ 0x8387, 0x8388, 0x8389, 0x838a, 0x838b, 0x838c, 0x838d, 0x838e,
+ 0x838f, 0x8390, 0x8391, 0x8392, 0x8393, 0x8394, 0x8395, 0x8396,
+ 0x8397, 0x8398, 0x8399, 0x839a, 0x839b, 0x839c, 0x839d, 0x839e,
+ 0x839f, 0x83a0, 0x83a1, 0x83a2, 0x83a3, 0x83a4, 0x83a5, 0x83a6,
+ 0x83a7, 0x83a8, 0x83a9, 0x83aa, 0x83ab, 0x83ac, 0x83ad, 0x83ae,
+ 0x83af, 0x83b0, 0x83b1, 0x83b2, 0x83b3, 0x83b4, 0x83b5, 0x83b6,
+ 0x83b7, 0x83b8, 0x83b9, 0x83ba, 0x83bb, 0x83bc, 0x83bd, 0x83be,
+ 0x83bf, 0x83c0, 0x83c1, 0x83c2, 0x83c3, 0x83c4, 0x83c5, 0x83c6,
+ 0x83c7, 0x83c8, 0x83c9, 0x83ca, 0x83cb, 0x83cc, 0x83cd, 0x83ce,
+ 0x83cf, 0x83d0, 0x83d1, 0x83d2, 0x83d3, 0x83d4, 0x83d5, 0x83d6,
+ 0x83d7, 0x83d8, 0x83d9, 0x83da, 0x83db, 0x83dc, 0x83dd, 0x83de,
+ 0x83df, 0x83e0, 0x83e1, 0x83e2, 0x83e3, 0x83e4, 0x83e5, 0x83e6,
+ 0x83e7, 0x83e8, 0x83e9, 0x83ea, 0x83eb, 0x83ec, 0x83ed, 0x83ee,
+ 0x83ef, 0x83f0, 0x83f1, 0x83f2, 0x83f3, 0x83f4, 0x83f5, 0x83f6,
+ 0x83f7, 0x83f8, 0x83f9, 0x83fa, 0x83fb, 0x83fc, 0x83fd, 0x83fe,
+ 0x8440, 0x8441, 0x8442, 0x8443, 0x8444, 0x8445, 0x8446, 0x8447,
+ 0x8448, 0x8449, 0x844a, 0x844b, 0x844c, 0x844d, 0x844e, 0x844f,
+ 0x8450, 0x8451, 0x8452, 0x8453, 0x8454, 0x8455, 0x8456, 0x8457,
+ 0x8458, 0x8459, 0x845a, 0x845b, 0x845c, 0x845d, 0x845e, 0x845f,
+ 0x8460, 0x8461, 0x8462, 0x8463, 0x8464, 0x8465, 0x8466, 0x8467,
+ 0x8468, 0x8469, 0x846a, 0x846b, 0x846c, 0x846d, 0x846e, 0x846f,
+ 0x8470, 0x8471, 0x8472, 0x8473, 0x8474, 0x8475, 0x8476, 0x8477,
+ 0x8478, 0x8479, 0x847a, 0x847b, 0x847c, 0x847d, 0x847e, 0x8480,
+ 0x8481, 0x8482, 0x8483, 0x8484, 0x8485, 0x8486, 0x8487, 0x8488,
+ 0x8489, 0x848a, 0x848b, 0x848c, 0x848d, 0x848e, 0x848f, 0x8490,
+ 0x8491, 0x8492, 0x8493, 0x8494, 0x8495, 0x8496, 0x8497, 0x8498,
+ 0x8499, 0x849a, 0x849b, 0x849c, 0x849d, 0x849e, 0x849f, 0x84a0,
+ 0x84a1, 0x84a2, 0x84a3, 0x84a4, 0x84a5, 0x84a6, 0x84a7, 0x84a8,
+ 0x84a9, 0x84aa, 0x84ab, 0x84ac, 0x84ad, 0x84ae, 0x84af, 0x84b0,
+ 0x84b1, 0x84b2, 0x84b3, 0x84b4, 0x84b5, 0x84b6, 0x84b7, 0x84b8,
+ 0x84b9, 0x84ba, 0x84bb, 0x84bc, 0x84bd, 0x84be, 0x84bf, 0x84c0,
+ 0x84c1, 0x84c2, 0x84c3, 0x84c4, 0x84c5, 0x84c6, 0x84c7, 0x84c8,
+ 0x84c9, 0x84ca, 0x84cb, 0x84cc, 0x84cd, 0x84ce, 0x84cf, 0x84d0,
+ 0x84d1, 0x84d2, 0x84d3, 0x84d4, 0x84d5, 0x84d6, 0x84d7, 0x84d8,
+ 0x84d9, 0x84da, 0x84db, 0x84dc, 0x84dd, 0x84de, 0x84df, 0x84e0,
+ 0x84e1, 0x84e2, 0x84e3, 0x84e4, 0x84e5, 0x84e6, 0x84e7, 0x84e8,
+ 0x84e9, 0x84ea, 0x84eb, 0x84ec, 0x84ed, 0x84ee, 0x84ef, 0x84f0,
+ 0x84f1, 0x84f2, 0x84f3, 0x84f4, 0x84f5, 0x84f6, 0x84f7, 0x84f8,
+ 0x84f9, 0x84fa, 0x84fb, 0x84fc, 0x84fd, 0x84fe, 0x8540, 0x8541,
+ 0x8542, 0x8543, 0x8544, 0x8545, 0x8546, 0x8547, 0x8548, 0x8549,
+ 0x854a, 0x854b, 0x854c, 0x854d, 0x854e, 0x854f, 0x8550, 0x8551,
+ 0x8552, 0x8553, 0x8554, 0x8555, 0x8556, 0x8557, 0x8558, 0x8559,
+ 0x855a, 0x855b, 0x855c, 0x855d, 0x855e, 0x855f, 0x8560, 0x8561,
+ 0x8562, 0x8563, 0x8564, 0x8565, 0x8566, 0x8567, 0x8568, 0x8569,
+ 0x856a, 0x856b, 0x856c, 0x856d, 0x856e, 0x856f, 0x8570, 0x8571,
+ 0x8572, 0x8573, 0x8574, 0x8575, 0x8576, 0x8577, 0x8578, 0x8579,
+ 0x857a, 0x857b, 0x857c, 0x857d, 0x857e, 0x8580, 0x8581, 0x8582,
+ 0x8583, 0x8584, 0x8585, 0x8586, 0x8587, 0x8588, 0x8589, 0x858a,
+ 0x858b, 0x858c, 0x858d, 0x858e, 0x858f, 0x8590, 0x8591, 0x8592,
+ 0x8593, 0x8594, 0x8595, 0x8596, 0x8597, 0x8598, 0x8599, 0x859a,
+ 0x859b, 0x859c, 0x859d, 0x859e, 0x859f, 0x85a0, 0x85a1, 0x85a2,
+ 0x85a3, 0x85a4, 0x85a5, 0x85a6, 0x85a7, 0x85a8, 0x85a9, 0x85aa,
+ 0x85ab, 0x85ac, 0x85ad, 0x85ae, 0x85af, 0x85b0, 0x85b1, 0x85b2,
+ 0x85b3, 0x85b4, 0x85b5, 0x85b6, 0x85b7, 0x85b8, 0x85b9, 0x85ba,
+ 0x85bb, 0x85bc, 0x85bd, 0x85be, 0x85bf, 0x85c0, 0x85c1, 0x85c2,
+ 0x85c3, 0x85c4, 0x85c5, 0x85c6, 0x85c7, 0x85c8, 0x85c9, 0x85ca,
+ 0x85cb, 0x85cc, 0x85cd, 0x85ce, 0x85cf, 0x85d0, 0x85d1, 0x85d2,
+ 0x85d3, 0x85d4, 0x85d5, 0x85d6, 0x85d7, 0x85d8, 0x85d9, 0x85da,
+ 0x85db, 0x85dc, 0x85dd, 0x85de, 0x85df, 0x85e0, 0x85e1, 0x85e2,
+ 0x85e3, 0x85e4, 0x85e5, 0x85e6, 0x85e7, 0x85e8, 0x85e9, 0x85ea,
+ 0x85eb, 0x85ec, 0x85ed, 0x85ee, 0x85ef, 0x85f0, 0x85f1, 0x85f2,
+ 0x85f3, 0x85f4, 0x85f5, 0x85f6, 0x85f7, 0x85f8, 0x85f9, 0x85fa,
+ 0x85fb, 0x85fc, 0x85fd, 0x85fe, 0x8640, 0x8641, 0x8642, 0x8643,
+ 0x8644, 0x8645, 0x8646, 0x8647, 0x8648, 0x8649, 0x864a, 0x864b,
+ 0x864c, 0x864d, 0x864e, 0x864f, 0x8650, 0x8651, 0x8652, 0x8653,
+ 0x8654, 0x8655, 0x8656, 0x8657, 0x8658, 0x8659, 0x865a, 0x865b,
+ 0x865c, 0x865d, 0x865e, 0x865f, 0x8660, 0x8661, 0x8662, 0x8663,
+ 0x8664, 0x8665, 0x8666, 0x8667, 0x8668, 0x8669, 0x866a, 0x866b,
+ 0x866c, 0x866d, 0x866e, 0x866f, 0x8670, 0x8671, 0x8672, 0x8673,
+ 0x8674, 0x8675, 0x8676, 0x8677, 0x8678, 0x8679, 0x867a, 0x867b,
+ 0x867c, 0x867d, 0x867e, 0x8680, 0x8681, 0x8682, 0x8683, 0x8684,
+ 0x8685, 0x8686, 0x8687, 0x8688, 0x8689, 0x868a, 0x868b, 0x868c,
+ 0x868d, 0x868e, 0x868f, 0x8690, 0x8691, 0x8692, 0x8693, 0x8694,
+ 0x8695, 0x8696, 0x8697, 0x8698, 0x8699, 0x869a, 0x869b, 0x869c,
+ 0x869d, 0x869e, 0x869f, 0x86a0, 0x86a1, 0x86a2, 0x86a3, 0x86a4,
+ 0x86a5, 0x86a6, 0x86a7, 0x86a8, 0x86a9, 0x86aa, 0x86ab, 0x86ac,
+ 0x86ad, 0x86ae, 0x86af, 0x86b0, 0x86b1, 0x86b2, 0x86b3, 0x86b4,
+ 0x86b5, 0x86b6, 0x86b7, 0x86b8, 0x86b9, 0x86ba, 0x86bb, 0x86bc,
+ 0x86bd, 0x86be, 0x86bf, 0x86c0, 0x86c1, 0x86c2, 0x86c3, 0x86c4,
+ 0x86c5, 0x86c6, 0x86c7, 0x86c8, 0x86c9, 0x86ca, 0x86cb, 0x86cc,
+ 0x86cd, 0x86ce, 0x86cf, 0x86d0, 0x86d1, 0x86d2, 0x86d3, 0x86d4,
+ 0x86d5, 0x86d6, 0x86d7, 0x86d8, 0x86d9, 0x86da, 0x86db, 0x86dc,
+ 0x86dd, 0x86de, 0x86df, 0x86e0, 0x86e1, 0x86e2, 0x86e3, 0x86e4,
+ 0x86e5, 0x86e6, 0x86e7, 0x86e8, 0x86e9, 0x86ea, 0x86eb, 0x86ec,
+ 0x86ed, 0x86ee, 0x86ef, 0x86f0, 0x86f1, 0x86f2, 0x86f3, 0x86f4,
+ 0x86f5, 0x86f6, 0x86f7, 0x86f8, 0x86f9, 0x86fa, 0x86fb, 0x86fc,
+ 0x86fd, 0x86fe, 0x8740, 0x8741, 0x8742, 0x8743, 0x8744, 0x8745,
+ 0x8746, 0x8747, 0x8748, 0x8749, 0x874a, 0x874b, 0x874c, 0x874d,
+ 0x874e, 0x874f, 0x8750, 0x8751, 0x8752, 0x8753, 0x8754, 0x8755,
+ 0x8756, 0x8757, 0x8758, 0x8759, 0x875a, 0x875b, 0x875c, 0x875d,
+ 0x875e, 0x875f, 0x8760, 0x8761, 0x8762, 0x8763, 0x8764, 0x8765,
+ 0x8766, 0x8767, 0x8768, 0x8769, 0x876a, 0x876b, 0x876c, 0x876d,
+ 0x876e, 0x876f, 0x8770, 0x8771, 0x8772, 0x8773, 0x8774, 0x8775,
+ 0x8776, 0x8777, 0x8778, 0x8779, 0x877a, 0x877b, 0x877c, 0x877d,
+ 0x877e, 0x8780, 0x8781, 0x8782, 0x8783, 0x8784, 0x8785, 0x8786,
+ 0x8787, 0x8788, 0x8789, 0x878a, 0x878b, 0x878c, 0x878d, 0x878e,
+ 0x878f, 0x8790, 0x8791, 0x8792, 0x8793, 0x8794, 0x8795, 0x8796,
+ 0x8797, 0x8798, 0x8799, 0x879a, 0x879b, 0x879c, 0x879d, 0x879e,
+ 0x879f, 0x87a0, 0x87a1, 0x87a2, 0x87a3, 0x87a4, 0x87a5, 0x87a6,
+ 0x87a7, 0x87a8, 0x87a9, 0x87aa, 0x87ab, 0x87ac, 0x87ad, 0x87ae,
+ 0x87af, 0x87b0, 0x87b1, 0x87b2, 0x87b3, 0x87b4, 0x87b5, 0x87b6,
+ 0x87b7, 0x87b8, 0x87b9, 0x87ba, 0x87bb, 0x87bc, 0x87bd, 0x87be,
+ 0x87bf, 0x87c0, 0x87c1, 0x87c2, 0x87c3, 0x87c4, 0x87c5, 0x87c6,
+ 0x87c7, 0x87c8, 0x87c9, 0x87ca, 0x87cb, 0x87cc, 0x87cd, 0x87ce,
+ 0x87cf, 0x87d0, 0x87d1, 0x87d2, 0x87d3, 0x87d4, 0x87d5, 0x87d6,
+ 0x87d7, 0x87d8, 0x87d9, 0x87da, 0x87db, 0x87dc, 0x87dd, 0x87de,
+ 0x87df, 0x87e0, 0x87e1, 0x87e2, 0x87e3, 0x87e4, 0x87e5, 0x87e6,
+ 0x87e7, 0x87e8, 0x87e9, 0x87ea, 0x87eb, 0x87ec, 0x87ed, 0x87ee,
+ 0x87ef, 0x87f0, 0x87f1, 0x87f2, 0x87f3, 0x87f4, 0x87f5, 0x87f6,
+ 0x87f7, 0x87f8, 0x87f9, 0x87fa, 0x87fb, 0x87fc, 0x87fd, 0x87fe,
+ 0x8840, 0x8841, 0x8842, 0x8843, 0x8844, 0x8845, 0x8846, 0x8847,
+ 0x8848, 0x8849, 0x884a, 0x884b, 0x884c, 0x884d, 0x884e, 0x884f,
+ 0x8850, 0x8851, 0x8852, 0x8853, 0x8854, 0x8855, 0x8856, 0x8857,
+ 0x8858, 0x8859, 0x885a, 0x885b, 0x885c, 0x885d, 0x885e, 0x885f,
+ 0x8860, 0x8861, 0x8862, 0x8863, 0x8864, 0x8865, 0x8866, 0x8867,
+ 0x8868, 0x8869, 0x886a, 0x886b, 0x886c, 0x886d, 0x886e, 0x886f,
+ 0x8870, 0x8871, 0x8872, 0x8873, 0x8874, 0x8875, 0x8876, 0x8877,
+ 0x8878, 0x8879, 0x887a, 0x887b, 0x887c, 0x887d, 0x887e, 0x8880,
+ 0x8881, 0x8882, 0x8883, 0x8884, 0x8885, 0x8886, 0x8887, 0x8888,
+ 0x8889, 0x888a, 0x888b, 0x888c, 0x888d, 0x888e, 0x888f, 0x8890,
+ 0x8891, 0x8892, 0x8893, 0x8894, 0x8895, 0x8896, 0x8897, 0x8898,
+ 0x8899, 0x889a, 0x889b, 0x889c, 0x889d, 0x889e, 0x889f, 0x88a0,
+ 0x88a1, 0x88a2, 0x88a3, 0x88a4, 0x88a5, 0x88a6, 0x88a7, 0x88a8,
+ 0x88a9, 0x88aa, 0x88ab, 0x88ac, 0x88ad, 0x88ae, 0x88af, 0x88b0,
+ 0x88b1, 0x88b2, 0x88b3, 0x88b4, 0x88b5, 0x88b6, 0x88b7, 0x88b8,
+ 0x88b9, 0x88ba, 0x88bb, 0x88bc, 0x88bd, 0x88be, 0x88bf, 0x88c0,
+ 0x88c1, 0x88c2, 0x88c3, 0x88c4, 0x88c5, 0x88c6, 0x88c7, 0x88c8,
+ 0x88c9, 0x88ca, 0x88cb, 0x88cc, 0x88cd, 0x88ce, 0x88cf, 0x88d0,
+ 0x88d1, 0x88d2, 0x88d3, 0x88d4, 0x88d5, 0x88d6, 0x88d7, 0x88d8,
+ 0x88d9, 0x88da, 0x88db, 0x88dc, 0x88dd, 0x88de, 0x88df, 0x88e0,
+ 0x88e1, 0x88e2, 0x88e3, 0x88e4, 0x88e5, 0x88e6, 0x88e7, 0x88e8,
+ 0x88e9, 0x88ea, 0x88eb, 0x88ec, 0x88ed, 0x88ee, 0x88ef, 0x88f0,
+ 0x88f1, 0x88f2, 0x88f3, 0x88f4, 0x88f5, 0x88f6, 0x88f7, 0x88f8,
+ 0x88f9, 0x88fa, 0x88fb, 0x88fc, 0x88fd, 0x88fe, 0x8940, 0x8941,
+ 0x8942, 0x8943, 0x8944, 0x8945, 0x8946, 0x8947, 0x8948, 0x8949,
+ 0x894a, 0x894b, 0x894c, 0x894d, 0x894e, 0x894f, 0x8950, 0x8951,
+ 0x8952, 0x8953, 0x8954, 0x8955, 0x8956, 0x8957, 0x8958, 0x8959,
+ 0x895a, 0x895b, 0x895c, 0x895d, 0x895e, 0x895f, 0x8960, 0x8961,
+ 0x8962, 0x8963, 0x8964, 0x8965, 0x8966, 0x8967, 0x8968, 0x8969,
+ 0x896a, 0x896b, 0x896c, 0x896d, 0x896e, 0x896f, 0x8970, 0x8971,
+ 0x8972, 0x8973, 0x8974, 0x8975, 0x8976, 0x8977, 0x8978, 0x8979,
+ 0x897a, 0x897b, 0x897c, 0x897d, 0x897e, 0x8980, 0x8981, 0x8982,
+ 0x8983, 0x8984, 0x8985, 0x8986, 0x8987, 0x8988, 0x8989, 0x898a,
+ 0x898b, 0x898c, 0x898d, 0x898e, 0x898f, 0x8990, 0x8991, 0x8992,
+ 0x8993, 0x8994, 0x8995, 0x8996, 0x8997, 0x8998, 0x8999, 0x899a,
+ 0x899b, 0x899c, 0x899d, 0x899e, 0x899f, 0x89a0, 0x89a1, 0x89a2,
+ 0x89a3, 0x89a4, 0x89a5, 0x89a6, 0x89a7, 0x89a8, 0x89a9, 0x89aa,
+ 0x89ab, 0x89ac, 0x89ad, 0x89ae, 0x89af, 0x89b0, 0x89b1, 0x89b2,
+ 0x89b3, 0x89b4, 0x89b5, 0x89b6, 0x89b7, 0x89b8, 0x89b9, 0x89ba,
+ 0x89bb, 0x89bc, 0x89bd, 0x89be, 0x89bf, 0x89c0, 0x89c1, 0x89c2,
+ 0x89c3, 0x89c4, 0x89c5, 0x89c6, 0x89c7, 0x89c8, 0x89c9, 0x89ca,
+ 0x89cb, 0x89cc, 0x89cd, 0x89ce, 0x89cf, 0x89d0, 0x89d1, 0x89d2,
+ 0x89d3, 0x89d4, 0x89d5, 0x89d6, 0x89d7, 0x89d8, 0x89d9, 0x89da,
+ 0x89db, 0x89dc, 0x89dd, 0x89de, 0x89df, 0x89e0, 0x89e1, 0x89e2,
+ 0x89e3, 0x89e4, 0x89e5, 0x89e6, 0x89e7, 0x89e8, 0x89e9, 0x89ea,
+ 0x89eb, 0x89ec, 0x89ed, 0x89ee, 0x89ef, 0x89f0, 0x89f1, 0x89f2,
+ 0x89f3, 0x89f4, 0x89f5, 0x89f6, 0x89f7, 0x89f8, 0x89f9, 0x89fa,
+ 0x89fb, 0x89fc, 0x89fd, 0x89fe, 0x8a40, 0x8a41, 0x8a42, 0x8a43,
+ 0x8a44, 0x8a45, 0x8a46, 0x8a47, 0x8a48, 0x8a49, 0x8a4a, 0x8a4b,
+ 0x8a4c, 0x8a4d, 0x8a4e, 0x8a4f, 0x8a50, 0x8a51, 0x8a52, 0x8a53,
+ 0x8a54, 0x8a55, 0x8a56, 0x8a57, 0x8a58, 0x8a59, 0x8a5a, 0x8a5b,
+ 0x8a5c, 0x8a5d, 0x8a5e, 0x8a5f, 0x8a60, 0x8a61, 0x8a62, 0x8a63,
+ 0x8a64, 0x8a65, 0x8a66, 0x8a67, 0x8a68, 0x8a69, 0x8a6a, 0x8a6b,
+ 0x8a6c, 0x8a6d, 0x8a6e, 0x8a6f, 0x8a70, 0x8a71, 0x8a72, 0x8a73,
+ 0x8a74, 0x8a75, 0x8a76, 0x8a77, 0x8a78, 0x8a79, 0x8a7a, 0x8a7b,
+ 0x8a7c, 0x8a7d, 0x8a7e, 0x8a80, 0x8a81, 0x8a82, 0x8a83, 0x8a84,
+ 0x8a85, 0x8a86, 0x8a87, 0x8a88, 0x8a89, 0x8a8a, 0x8a8b, 0x8a8c,
+ 0x8a8d, 0x8a8e, 0x8a8f, 0x8a90, 0x8a91, 0x8a92, 0x8a93, 0x8a94,
+ 0x8a95, 0x8a96, 0x8a97, 0x8a98, 0x8a99, 0x8a9a, 0x8a9b, 0x8a9c,
+ 0x8a9d, 0x8a9e, 0x8a9f, 0x8aa0, 0x8aa1, 0x8aa2, 0x8aa3, 0x8aa4,
+ 0x8aa5, 0x8aa6, 0x8aa7, 0x8aa8, 0x8aa9, 0x8aaa, 0x8aab, 0x8aac,
+ 0x8aad, 0x8aae, 0x8aaf, 0x8ab0, 0x8ab1, 0x8ab2, 0x8ab3, 0x8ab4,
+ 0x8ab5, 0x8ab6, 0x8ab7, 0x8ab8, 0x8ab9, 0x8aba, 0x8abb, 0x8abc,
+ 0x8abd, 0x8abe, 0x8abf, 0x8ac0, 0x8ac1, 0x8ac2, 0x8ac3, 0x8ac4,
+ 0x8ac5, 0x8ac6, 0x8ac7, 0x8ac8, 0x8ac9, 0x8aca, 0x8acb, 0x8acc,
+ 0x8acd, 0x8ace, 0x8acf, 0x8ad0, 0x8ad1, 0x8ad2, 0x8ad3, 0x8ad4,
+ 0x8ad5, 0x8ad6, 0x8ad7, 0x8ad8, 0x8ad9, 0x8ada, 0x8adb, 0x8adc,
+ 0x8add, 0x8ade, 0x8adf, 0x8ae0, 0x8ae1, 0x8ae2, 0x8ae3, 0x8ae4,
+ 0x8ae5, 0x8ae6, 0x8ae7, 0x8ae8, 0x8ae9, 0x8aea, 0x8aeb, 0x8aec,
+ 0x8aed, 0x8aee, 0x8aef, 0x8af0, 0x8af1, 0x8af2, 0x8af3, 0x8af4,
+ 0x8af5, 0x8af6, 0x8af7, 0x8af8, 0x8af9, 0x8afa, 0x8afb, 0x8afc,
+ 0x8afd, 0x8afe, 0x8b40, 0x8b41, 0x8b42, 0x8b43, 0x8b44, 0x8b45,
+ 0x8b46, 0x8b47, 0x8b48, 0x8b49, 0x8b4a, 0x8b4b, 0x8b4c, 0x8b4d,
+ 0x8b4e, 0x8b4f, 0x8b50, 0x8b51, 0x8b52, 0x8b53, 0x8b54, 0x8b55,
+ 0x8b56, 0x8b57, 0x8b58, 0x8b59, 0x8b5a, 0x8b5b, 0x8b5c, 0x8b5d,
+ 0x8b5e, 0x8b5f, 0x8b60, 0x8b61, 0x8b62, 0x8b63, 0x8b64, 0x8b65,
+ 0x8b66, 0x8b67, 0x8b68, 0x8b69, 0x8b6a, 0x8b6b, 0x8b6c, 0x8b6d,
+ 0x8b6e, 0x8b6f, 0x8b70, 0x8b71, 0x8b72, 0x8b73, 0x8b74, 0x8b75,
+ 0x8b76, 0x8b77, 0x8b78, 0x8b79, 0x8b7a, 0x8b7b, 0x8b7c, 0x8b7d,
+ 0x8b7e, 0x8b80, 0x8b81, 0x8b82, 0x8b83, 0x8b84, 0x8b85, 0x8b86,
+ 0x8b87, 0x8b88, 0x8b89, 0x8b8a, 0x8b8b, 0x8b8c, 0x8b8d, 0x8b8e,
+ 0x8b8f, 0x8b90, 0x8b91, 0x8b92, 0x8b93, 0x8b94, 0x8b95, 0x8b96,
+ 0x8b97, 0x8b98, 0x8b99, 0x8b9a, 0x8b9b, 0x8b9c, 0x8b9d, 0x8b9e,
+ 0x8b9f, 0x8ba0, 0x8ba1, 0x8ba2, 0x8ba3, 0x8ba4, 0x8ba5, 0x8ba6,
+ 0x8ba7, 0x8ba8, 0x8ba9, 0x8baa, 0x8bab, 0x8bac, 0x8bad, 0x8bae,
+ 0x8baf, 0x8bb0, 0x8bb1, 0x8bb2, 0x8bb3, 0x8bb4, 0x8bb5, 0x8bb6,
+ 0x8bb7, 0x8bb8, 0x8bb9, 0x8bba, 0x8bbb, 0x8bbc, 0x8bbd, 0x8bbe,
+ 0x8bbf, 0x8bc0, 0x8bc1, 0x8bc2, 0x8bc3, 0x8bc4, 0x8bc5, 0x8bc6,
+ 0x8bc7, 0x8bc8, 0x8bc9, 0x8bca, 0x8bcb, 0x8bcc, 0x8bcd, 0x8bce,
+ 0x8bcf, 0x8bd0, 0x8bd1, 0x8bd2, 0x8bd3, 0x8bd4, 0x8bd5, 0x8bd6,
+ 0x8bd7, 0x8bd8, 0x8bd9, 0x8bda, 0x8bdb, 0x8bdc, 0x8bdd, 0x8bde,
+ 0x8bdf, 0x8be0, 0x8be1, 0x8be2, 0x8be3, 0x8be4, 0x8be5, 0x8be6,
+ 0x8be7, 0x8be8, 0x8be9, 0x8bea, 0x8beb, 0x8bec, 0x8bed, 0x8bee,
+ 0x8bef, 0x8bf0, 0x8bf1, 0x8bf2, 0x8bf3, 0x8bf4, 0x8bf5, 0x8bf6,
+ 0x8bf7, 0x8bf8, 0x8bf9, 0x8bfa, 0x8bfb, 0x8bfc, 0x8bfd, 0x8bfe,
+ 0x8c40, 0x8c41, 0x8c42, 0x8c43, 0x8c44, 0x8c45, 0x8c46, 0x8c47,
+ 0x8c48, 0x8c49, 0x8c4a, 0x8c4b, 0x8c4c, 0x8c4d, 0x8c4e, 0x8c4f,
+ 0x8c50, 0x8c51, 0x8c52, 0x8c53, 0x8c54, 0x8c55, 0x8c56, 0x8c57,
+ 0x8c58, 0x8c59, 0x8c5a, 0x8c5b, 0x8c5c, 0x8c5d, 0x8c5e, 0x8c5f,
+ 0x8c60, 0x8c61, 0x8c62, 0x8c63, 0x8c64, 0x8c65, 0x8c66, 0x8c67,
+ 0x8c68, 0x8c69, 0x8c6a, 0x8c6b, 0x8c6c, 0x8c6d, 0x8c6e, 0x8c6f,
+ 0x8c70, 0x8c71, 0x8c72, 0x8c73, 0x8c74, 0x8c75, 0x8c76, 0x8c77,
+ 0x8c78, 0x8c79, 0x8c7a, 0x8c7b, 0x8c7c, 0x8c7d, 0x8c7e, 0x8c80,
+ 0x8c81, 0x8c82, 0x8c83, 0x8c84, 0x8c85, 0x8c86, 0x8c87, 0x8c88,
+ 0x8c89, 0x8c8a, 0x8c8b, 0x8c8c, 0x8c8d, 0x8c8e, 0x8c8f, 0x8c90,
+ 0x8c91, 0x8c92, 0x8c93, 0x8c94, 0x8c95, 0x8c96, 0x8c97, 0x8c98,
+ 0x8c99, 0x8c9a, 0x8c9b, 0x8c9c, 0x8c9d, 0x8c9e, 0x8c9f, 0x8ca0,
+ 0x8ca1, 0x8ca2, 0x8ca3, 0x8ca4, 0x8ca5, 0x8ca6, 0x8ca7, 0x8ca8,
+ 0x8ca9, 0x8caa, 0x8cab, 0x8cac, 0x8cad, 0x8cae, 0x8caf, 0x8cb0,
+ 0x8cb1, 0x8cb2, 0x8cb3, 0x8cb4, 0x8cb5, 0x8cb6, 0x8cb7, 0x8cb8,
+ 0x8cb9, 0x8cba, 0x8cbb, 0x8cbc, 0x8cbd, 0x8cbe, 0x8cbf, 0x8cc0,
+ 0x8cc1, 0x8cc2, 0x8cc3, 0x8cc4, 0x8cc5, 0x8cc6, 0x8cc7, 0x8cc8,
+ 0x8cc9, 0x8cca, 0x8ccb, 0x8ccc, 0x8ccd, 0x8cce, 0x8ccf, 0x8cd0,
+ 0x8cd1, 0x8cd2, 0x8cd3, 0x8cd4, 0x8cd5, 0x8cd6, 0x8cd7, 0x8cd8,
+ 0x8cd9, 0x8cda, 0x8cdb, 0x8cdc, 0x8cdd, 0x8cde, 0x8cdf, 0x8ce0,
+ 0x8ce1, 0x8ce2, 0x8ce3, 0x8ce4, 0x8ce5, 0x8ce6, 0x8ce7, 0x8ce8,
+ 0x8ce9, 0x8cea, 0x8ceb, 0x8cec, 0x8ced, 0x8cee, 0x8cef, 0x8cf0,
+ 0x8cf1, 0x8cf2, 0x8cf3, 0x8cf4, 0x8cf5, 0x8cf6, 0x8cf7, 0x8cf8,
+ 0x8cf9, 0x8cfa, 0x8cfb, 0x8cfc, 0x8cfd, 0x8cfe, 0x8d40, 0x8d41,
+ 0x8d42, 0x8d43, 0x8d44, 0x8d45, 0x8d46, 0x8d47, 0x8d48, 0x8d49,
+ 0x8d4a, 0x8d4b, 0x8d4c, 0x8d4d, 0x8d4e, 0x8d4f, 0x8d50, 0x8d51,
+ 0x8d52, 0x8d53, 0x8d54, 0x8d55, 0x8d56, 0x8d57, 0x8d58, 0x8d59,
+ 0x8d5a, 0x8d5b, 0x8d5c, 0x8d5d, 0x8d5e, 0x8d5f, 0x8d60, 0x8d61,
+ 0x8d62, 0x8d63, 0x8d64, 0x8d65, 0x8d66, 0x8d67, 0x8d68, 0x8d69,
+ 0x8d6a, 0x8d6b, 0x8d6c, 0x8d6d, 0x8d6e, 0x8d6f, 0x8d70, 0x8d71,
+ 0x8d72, 0x8d73, 0x8d74, 0x8d75, 0x8d76, 0x8d77, 0x8d78, 0x8d79,
+ 0x8d7a, 0x8d7b, 0x8d7c, 0x8d7d, 0x8d7e, 0x8d80, 0x8d81, 0x8d82,
+ 0x8d83, 0x8d84, 0x8d85, 0x8d86, 0x8d87, 0x8d88, 0x8d89, 0x8d8a,
+ 0x8d8b, 0x8d8c, 0x8d8d, 0x8d8e, 0x8d8f, 0x8d90, 0x8d91, 0x8d92,
+ 0x8d93, 0x8d94, 0x8d95, 0x8d96, 0x8d97, 0x8d98, 0x8d99, 0x8d9a,
+ 0x8d9b, 0x8d9c, 0x8d9d, 0x8d9e, 0x8d9f, 0x8da0, 0x8da1, 0x8da2,
+ 0x8da3, 0x8da4, 0x8da5, 0x8da6, 0x8da7, 0x8da8, 0x8da9, 0x8daa,
+ 0x8dab, 0x8dac, 0x8dad, 0x8dae, 0x8daf, 0x8db0, 0x8db1, 0x8db2,
+ 0x8db3, 0x8db4, 0x8db5, 0x8db6, 0x8db7, 0x8db8, 0x8db9, 0x8dba,
+ 0x8dbb, 0x8dbc, 0x8dbd, 0x8dbe, 0x8dbf, 0x8dc0, 0x8dc1, 0x8dc2,
+ 0x8dc3, 0x8dc4, 0x8dc5, 0x8dc6, 0x8dc7, 0x8dc8, 0x8dc9, 0x8dca,
+ 0x8dcb, 0x8dcc, 0x8dcd, 0x8dce, 0x8dcf, 0x8dd0, 0x8dd1, 0x8dd2,
+ 0x8dd3, 0x8dd4, 0x8dd5, 0x8dd6, 0x8dd7, 0x8dd8, 0x8dd9, 0x8dda,
+ 0x8ddb, 0x8ddc, 0x8ddd, 0x8dde, 0x8ddf, 0x8de0, 0x8de1, 0x8de2,
+ 0x8de3, 0x8de4, 0x8de5, 0x8de6, 0x8de7, 0x8de8, 0x8de9, 0x8dea,
+ 0x8deb, 0x8dec, 0x8ded, 0x8dee, 0x8def, 0x8df0, 0x8df1, 0x8df2,
+ 0x8df3, 0x8df4, 0x8df5, 0x8df6, 0x8df7, 0x8df8, 0x8df9, 0x8dfa,
+ 0x8dfb, 0x8dfc, 0x8dfd, 0x8dfe, 0x8e40, 0x8e41, 0x8e42, 0x8e43,
+ 0x8e44, 0x8e45, 0x8e46, 0x8e47, 0x8e48, 0x8e49, 0x8e4a, 0x8e4b,
+ 0x8e4c, 0x8e4d, 0x8e4e, 0x8e4f, 0x8e50, 0x8e51, 0x8e52, 0x8e53,
+ 0x8e54, 0x8e55, 0x8e56, 0x8e57, 0x8e58, 0x8e59, 0x8e5a, 0x8e5b,
+ 0x8e5c, 0x8e5d, 0x8e5e, 0x8e5f, 0x8e60, 0x8e61, 0x8e62, 0x8e63,
+ 0x8e64, 0x8e65, 0x8e66, 0x8e67, 0x8e68, 0x8e69, 0x8e6a, 0x8e6b,
+ 0x8e6c, 0x8e6d, 0x8e6e, 0x8e6f, 0x8e70, 0x8e71, 0x8e72, 0x8e73,
+ 0x8e74, 0x8e75, 0x8e76, 0x8e77, 0x8e78, 0x8e79, 0x8e7a, 0x8e7b,
+ 0x8e7c, 0x8e7d, 0x8e7e, 0x8e80, 0x8e81, 0x8e82, 0x8e83, 0x8e84,
+ 0x8e85, 0x8e86, 0x8e87, 0x8e88, 0x8e89, 0x8e8a, 0x8e8b, 0x8e8c,
+ 0x8e8d, 0x8e8e, 0x8e8f, 0x8e90, 0x8e91, 0x8e92, 0x8e93, 0x8e94,
+ 0x8e95, 0x8e96, 0x8e97, 0x8e98, 0x8e99, 0x8e9a, 0x8e9b, 0x8e9c,
+ 0x8e9d, 0x8e9e, 0x8e9f, 0x8ea0, 0x8ea1, 0x8ea2, 0x8ea3, 0x8ea4,
+ 0x8ea5, 0x8ea6, 0x8ea7, 0x8ea8, 0x8ea9, 0x8eaa, 0x8eab, 0x8eac,
+ 0x8ead, 0x8eae, 0x8eaf, 0x8eb0, 0x8eb1, 0x8eb2, 0x8eb3, 0x8eb4,
+ 0x8eb5, 0x8eb6, 0x8eb7, 0x8eb8, 0x8eb9, 0x8eba, 0x8ebb, 0x8ebc,
+ 0x8ebd, 0x8ebe, 0x8ebf, 0x8ec0, 0x8ec1, 0x8ec2, 0x8ec3, 0x8ec4,
+ 0x8ec5, 0x8ec6, 0x8ec7, 0x8ec8, 0x8ec9, 0x8eca, 0x8ecb, 0x8ecc,
+ 0x8ecd, 0x8ece, 0x8ecf, 0x8ed0, 0x8ed1, 0x8ed2, 0x8ed3, 0x8ed4,
+ 0x8ed5, 0x8ed6, 0x8ed7, 0x8ed8, 0x8ed9, 0x8eda, 0x8edb, 0x8edc,
+ 0x8edd, 0x8ede, 0x8edf, 0x8ee0, 0x8ee1, 0x8ee2, 0x8ee3, 0x8ee4,
+ 0x8ee5, 0x8ee6, 0x8ee7, 0x8ee8, 0x8ee9, 0x8eea, 0x8eeb, 0x8eec,
+ 0x8eed, 0x8eee, 0x8eef, 0x8ef0, 0x8ef1, 0x8ef2, 0x8ef3, 0x8ef4,
+ 0x8ef5, 0x8ef6, 0x8ef7, 0x8ef8, 0x8ef9, 0x8efa, 0x8efb, 0x8efc,
+ 0x8efd, 0x8efe, 0x8f40, 0x8f41, 0x8f42, 0x8f43, 0x8f44, 0x8f45,
+ 0x8f46, 0x8f47, 0x8f48, 0x8f49, 0x8f4a, 0x8f4b, 0x8f4c, 0x8f4d,
+ 0x8f4e, 0x8f4f, 0x8f50, 0x8f51, 0x8f52, 0x8f53, 0x8f54, 0x8f55,
+ 0x8f56, 0x8f57, 0x8f58, 0x8f59, 0x8f5a, 0x8f5b, 0x8f5c, 0x8f5d,
+ 0x8f5e, 0x8f5f, 0x8f60, 0x8f61, 0x8f62, 0x8f63, 0x8f64, 0x8f65,
+ 0x8f66, 0x8f67, 0x8f68, 0x8f69, 0x8f6a, 0x8f6b, 0x8f6c, 0x8f6d,
+ 0x8f6e, 0x8f6f, 0x8f70, 0x8f71, 0x8f72, 0x8f73, 0x8f74, 0x8f75,
+ 0x8f76, 0x8f77, 0x8f78, 0x8f79, 0x8f7a, 0x8f7b, 0x8f7c, 0x8f7d,
+ 0x8f7e, 0x8f80, 0x8f81, 0x8f82, 0x8f83, 0x8f84, 0x8f85, 0x8f86,
+ 0x8f87, 0x8f88, 0x8f89, 0x8f8a, 0x8f8b, 0x8f8c, 0x8f8d, 0x8f8e,
+ 0x8f8f, 0x8f90, 0x8f91, 0x8f92, 0x8f93, 0x8f94, 0x8f95, 0x8f96,
+ 0x8f97, 0x8f98, 0x8f99, 0x8f9a, 0x8f9b, 0x8f9c, 0x8f9d, 0x8f9e,
+ 0x8f9f, 0x8fa0, 0x8fa1, 0x8fa2, 0x8fa3, 0x8fa4, 0x8fa5, 0x8fa6,
+ 0x8fa7, 0x8fa8, 0x8fa9, 0x8faa, 0x8fab, 0x8fac, 0x8fad, 0x8fae,
+ 0x8faf, 0x8fb0, 0x8fb1, 0x8fb2, 0x8fb3, 0x8fb4, 0x8fb5, 0x8fb6,
+ 0x8fb7, 0x8fb8, 0x8fb9, 0x8fba, 0x8fbb, 0x8fbc, 0x8fbd, 0x8fbe,
+ 0x8fbf, 0x8fc0, 0x8fc1, 0x8fc2, 0x8fc3, 0x8fc4, 0x8fc5, 0x8fc6,
+ 0x8fc7, 0x8fc8, 0x8fc9, 0x8fca, 0x8fcb, 0x8fcc, 0x8fcd, 0x8fce,
+ 0x8fcf, 0x8fd0, 0x8fd1, 0x8fd2, 0x8fd3, 0x8fd4, 0x8fd5, 0x8fd6,
+ 0x8fd7, 0x8fd8, 0x8fd9, 0x8fda, 0x8fdb, 0x8fdc, 0x8fdd, 0x8fde,
+ 0x8fdf, 0x8fe0, 0x8fe1, 0x8fe2, 0x8fe3, 0x8fe4, 0x8fe5, 0x8fe6,
+ 0x8fe7, 0x8fe8, 0x8fe9, 0x8fea, 0x8feb, 0x8fec, 0x8fed, 0x8fee,
+ 0x8fef, 0x8ff0, 0x8ff1, 0x8ff2, 0x8ff3, 0x8ff4, 0x8ff5, 0x8ff6,
+ 0x8ff7, 0x8ff8, 0x8ff9, 0x8ffa, 0x8ffb, 0x8ffc, 0x8ffd, 0x8ffe,
+ 0x9040, 0x9041, 0x9042, 0x9043, 0x9044, 0x9045, 0x9046, 0x9047,
+ 0x9048, 0x9049, 0x904a, 0x904b, 0x904c, 0x904d, 0x904e, 0x904f,
+ 0x9050, 0x9051, 0x9052, 0x9053, 0x9054, 0x9055, 0x9056, 0x9057,
+ 0x9058, 0x9059, 0x905a, 0x905b, 0x905c, 0x905d, 0x905e, 0x905f,
+ 0x9060, 0x9061, 0x9062, 0x9063, 0x9064, 0x9065, 0x9066, 0x9067,
+ 0x9068, 0x9069, 0x906a, 0x906b, 0x906c, 0x906d, 0x906e, 0x906f,
+ 0x9070, 0x9071, 0x9072, 0x9073, 0x9074, 0x9075, 0x9076, 0x9077,
+ 0x9078, 0x9079, 0x907a, 0x907b, 0x907c, 0x907d, 0x907e, 0x9080,
+ 0x9081, 0x9082, 0x9083, 0x9084, 0x9085, 0x9086, 0x9087, 0x9088,
+ 0x9089, 0x908a, 0x908b, 0x908c, 0x908d, 0x908e, 0x908f, 0x9090,
+ 0x9091, 0x9092, 0x9093, 0x9094, 0x9095, 0x9096, 0x9097, 0x9098,
+ 0x9099, 0x909a, 0x909b, 0x909c, 0x909d, 0x909e, 0x909f, 0x90a0,
+ 0x90a1, 0x90a2, 0x90a3, 0x90a4, 0x90a5, 0x90a6, 0x90a7, 0x90a8,
+ 0x90a9, 0x90aa, 0x90ab, 0x90ac, 0x90ad, 0x90ae, 0x90af, 0x90b0,
+ 0x90b1, 0x90b2, 0x90b3, 0x90b4, 0x90b5, 0x90b6, 0x90b7, 0x90b8,
+ 0x90b9, 0x90ba, 0x90bb, 0x90bc, 0x90bd, 0x90be, 0x90bf, 0x90c0,
+ 0x90c1, 0x90c2, 0x90c3, 0x90c4, 0x90c5, 0x90c6, 0x90c7, 0x90c8,
+ 0x90c9, 0x90ca, 0x90cb, 0x90cc, 0x90cd, 0x90ce, 0x90cf, 0x90d0,
+ 0x90d1, 0x90d2, 0x90d3, 0x90d4, 0x90d5, 0x90d6, 0x90d7, 0x90d8,
+ 0x90d9, 0x90da, 0x90db, 0x90dc, 0x90dd, 0x90de, 0x90df, 0x90e0,
+ 0x90e1, 0x90e2, 0x90e3, 0x90e4, 0x90e5, 0x90e6, 0x90e7, 0x90e8,
+ 0x90e9, 0x90ea, 0x90eb, 0x90ec, 0x90ed, 0x90ee, 0x90ef, 0x90f0,
+ 0x90f1, 0x90f2, 0x90f3, 0x90f4, 0x90f5, 0x90f6, 0x90f7, 0x90f8,
+ 0x90f9, 0x90fa, 0x90fb, 0x90fc, 0x90fd, 0x90fe, 0x9140, 0x9141,
+ 0x9142, 0x9143, 0x9144, 0x9145, 0x9146, 0x9147, 0x9148, 0x9149,
+ 0x914a, 0x914b, 0x914c, 0x914d, 0x914e, 0x914f, 0x9150, 0x9151,
+ 0x9152, 0x9153, 0x9154, 0x9155, 0x9156, 0x9157, 0x9158, 0x9159,
+ 0x915a, 0x915b, 0x915c, 0x915d, 0x915e, 0x915f, 0x9160, 0x9161,
+ 0x9162, 0x9163, 0x9164, 0x9165, 0x9166, 0x9167, 0x9168, 0x9169,
+ 0x916a, 0x916b, 0x916c, 0x916d, 0x916e, 0x916f, 0x9170, 0x9171,
+ 0x9172, 0x9173, 0x9174, 0x9175, 0x9176, 0x9177, 0x9178, 0x9179,
+ 0x917a, 0x917b, 0x917c, 0x917d, 0x917e, 0x9180, 0x9181, 0x9182,
+ 0x9183, 0x9184, 0x9185, 0x9186, 0x9187, 0x9188, 0x9189, 0x918a,
+ 0x918b, 0x918c, 0x918d, 0x918e, 0x918f, 0x9190, 0x9191, 0x9192,
+ 0x9193, 0x9194, 0x9195, 0x9196, 0x9197, 0x9198, 0x9199, 0x919a,
+ 0x919b, 0x919c, 0x919d, 0x919e, 0x919f, 0x91a0, 0x91a1, 0x91a2,
+ 0x91a3, 0x91a4, 0x91a5, 0x91a6, 0x91a7, 0x91a8, 0x91a9, 0x91aa,
+ 0x91ab, 0x91ac, 0x91ad, 0x91ae, 0x91af, 0x91b0, 0x91b1, 0x91b2,
+ 0x91b3, 0x91b4, 0x91b5, 0x91b6, 0x91b7, 0x91b8, 0x91b9, 0x91ba,
+ 0x91bb, 0x91bc, 0x91bd, 0x91be, 0x91bf, 0x91c0, 0x91c1, 0x91c2,
+ 0x91c3, 0x91c4, 0x91c5, 0x91c6, 0x91c7, 0x91c8, 0x91c9, 0x91ca,
+ 0x91cb, 0x91cc, 0x91cd, 0x91ce, 0x91cf, 0x91d0, 0x91d1, 0x91d2,
+ 0x91d3, 0x91d4, 0x91d5, 0x91d6, 0x91d7, 0x91d8, 0x91d9, 0x91da,
+ 0x91db, 0x91dc, 0x91dd, 0x91de, 0x91df, 0x91e0, 0x91e1, 0x91e2,
+ 0x91e3, 0x91e4, 0x91e5, 0x91e6, 0x91e7, 0x91e8, 0x91e9, 0x91ea,
+ 0x91eb, 0x91ec, 0x91ed, 0x91ee, 0x91ef, 0x91f0, 0x91f1, 0x91f2,
+ 0x91f3, 0x91f4, 0x91f5, 0x91f6, 0x91f7, 0x91f8, 0x91f9, 0x91fa,
+ 0x91fb, 0x91fc, 0x91fd, 0x91fe, 0x9240, 0x9241, 0x9242, 0x9243,
+ 0x9244, 0x9245, 0x9246, 0x9247, 0x9248, 0x9249, 0x924a, 0x924b,
+ 0x924c, 0x924d, 0x924e, 0x924f, 0x9250, 0x9251, 0x9252, 0x9253,
+ 0x9254, 0x9255, 0x9256, 0x9257, 0x9258, 0x9259, 0x925a, 0x925b,
+ 0x925c, 0x925d, 0x925e, 0x925f, 0x9260, 0x9261, 0x9262, 0x9263,
+ 0x9264, 0x9265, 0x9266, 0x9267, 0x9268, 0x9269, 0x926a, 0x926b,
+ 0x926c, 0x926d, 0x926e, 0x926f, 0x9270, 0x9271, 0x9272, 0x9273,
+ 0x9274, 0x9275, 0x9276, 0x9277, 0x9278, 0x9279, 0x927a, 0x927b,
+ 0x927c, 0x927d, 0x927e, 0x9280, 0x9281, 0x9282, 0x9283, 0x9284,
+ 0x9285, 0x9286, 0x9287, 0x9288, 0x9289, 0x928a, 0x928b, 0x928c,
+ 0x928d, 0x928e, 0x928f, 0x9290, 0x9291, 0x9292, 0x9293, 0x9294,
+ 0x9295, 0x9296, 0x9297, 0x9298, 0x9299, 0x929a, 0x929b, 0x929c,
+ 0x929d, 0x929e, 0x929f, 0x92a0, 0x92a1, 0x92a2, 0x92a3, 0x92a4,
+ 0x92a5, 0x92a6, 0x92a7, 0x92a8, 0x92a9, 0x92aa, 0x92ab, 0x92ac,
+ 0x92ad, 0x92ae, 0x92af, 0x92b0, 0x92b1, 0x92b2, 0x92b3, 0x92b4,
+ 0x92b5, 0x92b6, 0x92b7, 0x92b8, 0x92b9, 0x92ba, 0x92bb, 0x92bc,
+ 0x92bd, 0x92be, 0x92bf, 0x92c0, 0x92c1, 0x92c2, 0x92c3, 0x92c4,
+ 0x92c5, 0x92c6, 0x92c7, 0x92c8, 0x92c9, 0x92ca, 0x92cb, 0x92cc,
+ 0x92cd, 0x92ce, 0x92cf, 0x92d0, 0x92d1, 0x92d2, 0x92d3, 0x92d4,
+ 0x92d5, 0x92d6, 0x92d7, 0x92d8, 0x92d9, 0x92da, 0x92db, 0x92dc,
+ 0x92dd, 0x92de, 0x92df, 0x92e0, 0x92e1, 0x92e2, 0x92e3, 0x92e4,
+ 0x92e5, 0x92e6, 0x92e7, 0x92e8, 0x92e9, 0x92ea, 0x92eb, 0x92ec,
+ 0x92ed, 0x92ee, 0x92ef, 0x92f0, 0x92f1, 0x92f2, 0x92f3, 0x92f4,
+ 0x92f5, 0x92f6, 0x92f7, 0x92f8, 0x92f9, 0x92fa, 0x92fb, 0x92fc,
+ 0x92fd, 0x92fe, 0x9340, 0x9341, 0x9342, 0x9343, 0x9344, 0x9345,
+ 0x9346, 0x9347, 0x9348, 0x9349, 0x934a, 0x934b, 0x934c, 0x934d,
+ 0x934e, 0x934f, 0x9350, 0x9351, 0x9352, 0x9353, 0x9354, 0x9355,
+ 0x9356, 0x9357, 0x9358, 0x9359, 0x935a, 0x935b, 0x935c, 0x935d,
+ 0x935e, 0x935f, 0x9360, 0x9361, 0x9362, 0x9363, 0x9364, 0x9365,
+ 0x9366, 0x9367, 0x9368, 0x9369, 0x936a, 0x936b, 0x936c, 0x936d,
+ 0x936e, 0x936f, 0x9370, 0x9371, 0x9372, 0x9373, 0x9374, 0x9375,
+ 0x9376, 0x9377, 0x9378, 0x9379, 0x937a, 0x937b, 0x937c, 0x937d,
+ 0x937e, 0x9380, 0x9381, 0x9382, 0x9383, 0x9384, 0x9385, 0x9386,
+ 0x9387, 0x9388, 0x9389, 0x938a, 0x938b, 0x938c, 0x938d, 0x938e,
+ 0x938f, 0x9390, 0x9391, 0x9392, 0x9393, 0x9394, 0x9395, 0x9396,
+ 0x9397, 0x9398, 0x9399, 0x939a, 0x939b, 0x939c, 0x939d, 0x939e,
+ 0x939f, 0x93a0, 0x93a1, 0x93a2, 0x93a3, 0x93a4, 0x93a5, 0x93a6,
+ 0x93a7, 0x93a8, 0x93a9, 0x93aa, 0x93ab, 0x93ac, 0x93ad, 0x93ae,
+ 0x93af, 0x93b0, 0x93b1, 0x93b2, 0x93b3, 0x93b4, 0x93b5, 0x93b6,
+ 0x93b7, 0x93b8, 0x93b9, 0x93ba, 0x93bb, 0x93bc, 0x93bd, 0x93be,
+ 0x93bf, 0x93c0, 0x93c1, 0x93c2, 0x93c3, 0x93c4, 0x93c5, 0x93c6,
+ 0x93c7, 0x93c8, 0x93c9, 0x93ca, 0x93cb, 0x93cc, 0x93cd, 0x93ce,
+ 0x93cf, 0x93d0, 0x93d1, 0x93d2, 0x93d3, 0x93d4, 0x93d5, 0x93d6,
+ 0x93d7, 0x93d8, 0x93d9, 0x93da, 0x93db, 0x93dc, 0x93dd, 0x93de,
+ 0x93df, 0x93e0, 0x93e1, 0x93e2, 0x93e3, 0x93e4, 0x93e5, 0x93e6,
+ 0x93e7, 0x93e8, 0x93e9, 0x93ea, 0x93eb, 0x93ec, 0x93ed, 0x93ee,
+ 0x93ef, 0x93f0, 0x93f1, 0x93f2, 0x93f3, 0x93f4, 0x93f5, 0x93f6,
+ 0x93f7, 0x93f8, 0x93f9, 0x93fa, 0x93fb, 0x93fc, 0x93fd, 0x93fe,
+ 0x9440, 0x9441, 0x9442, 0x9443, 0x9444, 0x9445, 0x9446, 0x9447,
+ 0x9448, 0x9449, 0x944a, 0x944b, 0x944c, 0x944d, 0x944e, 0x944f,
+ 0x9450, 0x9451, 0x9452, 0x9453, 0x9454, 0x9455, 0x9456, 0x9457,
+ 0x9458, 0x9459, 0x945a, 0x945b, 0x945c, 0x945d, 0x945e, 0x945f,
+ 0x9460, 0x9461, 0x9462, 0x9463, 0x9464, 0x9465, 0x9466, 0x9467,
+ 0x9468, 0x9469, 0x946a, 0x946b, 0x946c, 0x946d, 0x946e, 0x946f,
+ 0x9470, 0x9471, 0x9472, 0x9473, 0x9474, 0x9475, 0x9476, 0x9477,
+ 0x9478, 0x9479, 0x947a, 0x947b, 0x947c, 0x947d, 0x947e, 0x9480,
+ 0x9481, 0x9482, 0x9483, 0x9484, 0x9485, 0x9486, 0x9487, 0x9488,
+ 0x9489, 0x948a, 0x948b, 0x948c, 0x948d, 0x948e, 0x948f, 0x9490,
+ 0x9491, 0x9492, 0x9493, 0x9494, 0x9495, 0x9496, 0x9497, 0x9498,
+ 0x9499, 0x949a, 0x949b, 0x949c, 0x949d, 0x949e, 0x949f, 0x94a0,
+ 0x94a1, 0x94a2, 0x94a3, 0x94a4, 0x94a5, 0x94a6, 0x94a7, 0x94a8,
+ 0x94a9, 0x94aa, 0x94ab, 0x94ac, 0x94ad, 0x94ae, 0x94af, 0x94b0,
+ 0x94b1, 0x94b2, 0x94b3, 0x94b4, 0x94b5, 0x94b6, 0x94b7, 0x94b8,
+ 0x94b9, 0x94ba, 0x94bb, 0x94bc, 0x94bd, 0x94be, 0x94bf, 0x94c0,
+ 0x94c1, 0x94c2, 0x94c3, 0x94c4, 0x94c5, 0x94c6, 0x94c7, 0x94c8,
+ 0x94c9, 0x94ca, 0x94cb, 0x94cc, 0x94cd, 0x94ce, 0x94cf, 0x94d0,
+ 0x94d1, 0x94d2, 0x94d3, 0x94d4, 0x94d5, 0x94d6, 0x94d7, 0x94d8,
+ 0x94d9, 0x94da, 0x94db, 0x94dc, 0x94dd, 0x94de, 0x94df, 0x94e0,
+ 0x94e1, 0x94e2, 0x94e3, 0x94e4, 0x94e5, 0x94e6, 0x94e7, 0x94e8,
+ 0x94e9, 0x94ea, 0x94eb, 0x94ec, 0x94ed, 0x94ee, 0x94ef, 0x94f0,
+ 0x94f1, 0x94f2, 0x94f3, 0x94f4, 0x94f5, 0x94f6, 0x94f7, 0x94f8,
+ 0x94f9, 0x94fa, 0x94fb, 0x94fc, 0x94fd, 0x94fe, 0x9540, 0x9541,
+ 0x9542, 0x9543, 0x9544, 0x9545, 0x9546, 0x9547, 0x9548, 0x9549,
+ 0x954a, 0x954b, 0x954c, 0x954d, 0x954e, 0x954f, 0x9550, 0x9551,
+ 0x9552, 0x9553, 0x9554, 0x9555, 0x9556, 0x9557, 0x9558, 0x9559,
+ 0x955a, 0x955b, 0x955c, 0x955d, 0x955e, 0x955f, 0x9560, 0x9561,
+ 0x9562, 0x9563, 0x9564, 0x9565, 0x9566, 0x9567, 0x9568, 0x9569,
+ 0x956a, 0x956b, 0x956c, 0x956d, 0x956e, 0x956f, 0x9570, 0x9571,
+ 0x9572, 0x9573, 0x9574, 0x9575, 0x9576, 0x9577, 0x9578, 0x9579,
+ 0x957a, 0x957b, 0x957c, 0x957d, 0x957e, 0x9580, 0x9581, 0x9582,
+ 0x9583, 0x9584, 0x9585, 0x9586, 0x9587, 0x9588, 0x9589, 0x958a,
+ 0x958b, 0x958c, 0x958d, 0x958e, 0x958f, 0x9590, 0x9591, 0x9592,
+ 0x9593, 0x9594, 0x9595, 0x9596, 0x9597, 0x9598, 0x9599, 0x959a,
+ 0x959b, 0x959c, 0x959d, 0x959e, 0x959f, 0x95a0, 0x95a1, 0x95a2,
+ 0x95a3, 0x95a4, 0x95a5, 0x95a6, 0x95a7, 0x95a8, 0x95a9, 0x95aa,
+ 0x95ab, 0x95ac, 0x95ad, 0x95ae, 0x95af, 0x95b0, 0x95b1, 0x95b2,
+ 0x95b3, 0x95b4, 0x95b5, 0x95b6, 0x95b7, 0x95b8, 0x95b9, 0x95ba,
+ 0x95bb, 0x95bc, 0x95bd, 0x95be, 0x95bf, 0x95c0, 0x95c1, 0x95c2,
+ 0x95c3, 0x95c4, 0x95c5, 0x95c6, 0x95c7, 0x95c8, 0x95c9, 0x95ca,
+ 0x95cb, 0x95cc, 0x95cd, 0x95ce, 0x95cf, 0x95d0, 0x95d1, 0x95d2,
+ 0x95d3, 0x95d4, 0x95d5, 0x95d6, 0x95d7, 0x95d8, 0x95d9, 0x95da,
+ 0x95db, 0x95dc, 0x95dd, 0x95de, 0x95df, 0x95e0, 0x95e1, 0x95e2,
+ 0x95e3, 0x95e4, 0x95e5, 0x95e6, 0x95e7, 0x95e8, 0x95e9, 0x95ea,
+ 0x95eb, 0x95ec, 0x95ed, 0x95ee, 0x95ef, 0x95f0, 0x95f1, 0x95f2,
+ 0x95f3, 0x95f4, 0x95f5, 0x95f6, 0x95f7, 0x95f8, 0x95f9, 0x95fa,
+ 0x95fb, 0x95fc, 0x95fd, 0x95fe, 0x9640, 0x9641, 0x9642, 0x9643,
+ 0x9644, 0x9645, 0x9646, 0x9647, 0x9648, 0x9649, 0x964a, 0x964b,
+ 0x964c, 0x964d, 0x964e, 0x964f, 0x9650, 0x9651, 0x9652, 0x9653,
+ 0x9654, 0x9655, 0x9656, 0x9657, 0x9658, 0x9659, 0x965a, 0x965b,
+ 0x965c, 0x965d, 0x965e, 0x965f, 0x9660, 0x9661, 0x9662, 0x9663,
+ 0x9664, 0x9665, 0x9666, 0x9667, 0x9668, 0x9669, 0x966a, 0x966b,
+ 0x966c, 0x966d, 0x966e, 0x966f, 0x9670, 0x9671, 0x9672, 0x9673,
+ 0x9674, 0x9675, 0x9676, 0x9677, 0x9678, 0x9679, 0x967a, 0x967b,
+ 0x967c, 0x967d, 0x967e, 0x9680, 0x9681, 0x9682, 0x9683, 0x9684,
+ 0x9685, 0x9686, 0x9687, 0x9688, 0x9689, 0x968a, 0x968b, 0x968c,
+ 0x968d, 0x968e, 0x968f, 0x9690, 0x9691, 0x9692, 0x9693, 0x9694,
+ 0x9695, 0x9696, 0x9697, 0x9698, 0x9699, 0x969a, 0x969b, 0x969c,
+ 0x969d, 0x969e, 0x969f, 0x96a0, 0x96a1, 0x96a2, 0x96a3, 0x96a4,
+ 0x96a5, 0x96a6, 0x96a7, 0x96a8, 0x96a9, 0x96aa, 0x96ab, 0x96ac,
+ 0x96ad, 0x96ae, 0x96af, 0x96b0, 0x96b1, 0x96b2, 0x96b3, 0x96b4,
+ 0x96b5, 0x96b6, 0x96b7, 0x96b8, 0x96b9, 0x96ba, 0x96bb, 0x96bc,
+ 0x96bd, 0x96be, 0x96bf, 0x96c0, 0x96c1, 0x96c2, 0x96c3, 0x96c4,
+ 0x96c5, 0x96c6, 0x96c7, 0x96c8, 0x96c9, 0x96ca, 0x96cb, 0x96cc,
+ 0x96cd, 0x96ce, 0x96cf, 0x96d0, 0x96d1, 0x96d2, 0x96d3, 0x96d4,
+ 0x96d5, 0x96d6, 0x96d7, 0x96d8, 0x96d9, 0x96da, 0x96db, 0x96dc,
+ 0x96dd, 0x96de, 0x96df, 0x96e0, 0x96e1, 0x96e2, 0x96e3, 0x96e4,
+ 0x96e5, 0x96e6, 0x96e7, 0x96e8, 0x96e9, 0x96ea, 0x96eb, 0x96ec,
+ 0x96ed, 0x96ee, 0x96ef, 0x96f0, 0x96f1, 0x96f2, 0x96f3, 0x96f4,
+ 0x96f5, 0x96f6, 0x96f7, 0x96f8, 0x96f9, 0x96fa, 0x96fb, 0x96fc,
+ 0x96fd, 0x96fe, 0x9740, 0x9741, 0x9742, 0x9743, 0x9744, 0x9745,
+ 0x9746, 0x9747, 0x9748, 0x9749, 0x974a, 0x974b, 0x974c, 0x974d,
+ 0x974e, 0x974f, 0x9750, 0x9751, 0x9752, 0x9753, 0x9754, 0x9755,
+ 0x9756, 0x9757, 0x9758, 0x9759, 0x975a, 0x975b, 0x975c, 0x975d,
+ 0x975e, 0x975f, 0x9760, 0x9761, 0x9762, 0x9763, 0x9764, 0x9765,
+ 0x9766, 0x9767, 0x9768, 0x9769, 0x976a, 0x976b, 0x976c, 0x976d,
+ 0x976e, 0x976f, 0x9770, 0x9771, 0x9772, 0x9773, 0x9774, 0x9775,
+ 0x9776, 0x9777, 0x9778, 0x9779, 0x977a, 0x977b, 0x977c, 0x977d,
+ 0x977e, 0x9780, 0x9781, 0x9782, 0x9783, 0x9784, 0x9785, 0x9786,
+ 0x9787, 0x9788, 0x9789, 0x978a, 0x978b, 0x978c, 0x978d, 0x978e,
+ 0x978f, 0x9790, 0x9791, 0x9792, 0x9793, 0x9794, 0x9795, 0x9796,
+ 0x9797, 0x9798, 0x9799, 0x979a, 0x979b, 0x979c, 0x979d, 0x979e,
+ 0x979f, 0x97a0, 0x97a1, 0x97a2, 0x97a3, 0x97a4, 0x97a5, 0x97a6,
+ 0x97a7, 0x97a8, 0x97a9, 0x97aa, 0x97ab, 0x97ac, 0x97ad, 0x97ae,
+ 0x97af, 0x97b0, 0x97b1, 0x97b2, 0x97b3, 0x97b4, 0x97b5, 0x97b6,
+ 0x97b7, 0x97b8, 0x97b9, 0x97ba, 0x97bb, 0x97bc, 0x97bd, 0x97be,
+ 0x97bf, 0x97c0, 0x97c1, 0x97c2, 0x97c3, 0x97c4, 0x97c5, 0x97c6,
+ 0x97c7, 0x97c8, 0x97c9, 0x97ca, 0x97cb, 0x97cc, 0x97cd, 0x97ce,
+ 0x97cf, 0x97d0, 0x97d1, 0x97d2, 0x97d3, 0x97d4, 0x97d5, 0x97d6,
+ 0x97d7, 0x97d8, 0x97d9, 0x97da, 0x97db, 0x97dc, 0x97dd, 0x97de,
+ 0x97df, 0x97e0, 0x97e1, 0x97e2, 0x97e3, 0x97e4, 0x97e5, 0x97e6,
+ 0x97e7, 0x97e8, 0x97e9, 0x97ea, 0x97eb, 0x97ec, 0x97ed, 0x97ee,
+ 0x97ef, 0x97f0, 0x97f1, 0x97f2, 0x97f3, 0x97f4, 0x97f5, 0x97f6,
+ 0x97f7, 0x97f8, 0x97f9, 0x97fa, 0x97fb, 0x97fc, 0x97fd, 0x97fe,
+ 0x9840, 0x9841, 0x9842, 0x9843, 0x9844, 0x9845, 0x9846, 0x9847,
+ 0x9848, 0x9849, 0x984a, 0x984b, 0x984c, 0x984d, 0x984e, 0x984f,
+ 0x9850, 0x9851, 0x9852, 0x9853, 0x9854, 0x9855, 0x9856, 0x9857,
+ 0x9858, 0x9859, 0x985a, 0x985b, 0x985c, 0x985d, 0x985e, 0x985f,
+ 0x9860, 0x9861, 0x9862, 0x9863, 0x9864, 0x9865, 0x9866, 0x9867,
+ 0x9868, 0x9869, 0x986a, 0x986b, 0x986c, 0x986d, 0x986e, 0x986f,
+ 0x9870, 0x9871, 0x9872, 0x9873, 0x9874, 0x9875, 0x9876, 0x9877,
+ 0x9878, 0x9879, 0x987a, 0x987b, 0x987c, 0x987d, 0x987e, 0x9880,
+ 0x9881, 0x9882, 0x9883, 0x9884, 0x9885, 0x9886, 0x9887, 0x9888,
+ 0x9889, 0x988a, 0x988b, 0x988c, 0x988d, 0x988e, 0x988f, 0x9890,
+ 0x9891, 0x9892, 0x9893, 0x9894, 0x9895, 0x9896, 0x9897, 0x9898,
+ 0x9899, 0x989a, 0x989b, 0x989c, 0x989d, 0x989e, 0x989f, 0x98a0,
+ 0x98a1, 0x98a2, 0x98a3, 0x98a4, 0x98a5, 0x98a6, 0x98a7, 0x98a8,
+ 0x98a9, 0x98aa, 0x98ab, 0x98ac, 0x98ad, 0x98ae, 0x98af, 0x98b0,
+ 0x98b1, 0x98b2, 0x98b3, 0x98b4, 0x98b5, 0x98b6, 0x98b7, 0x98b8,
+ 0x98b9, 0x98ba, 0x98bb, 0x98bc, 0x98bd, 0x98be, 0x98bf, 0x98c0,
+ 0x98c1, 0x98c2, 0x98c3, 0x98c4, 0x98c5, 0x98c6, 0x98c7, 0x98c8,
+ 0x98c9, 0x98ca, 0x98cb, 0x98cc, 0x98cd, 0x98ce, 0x98cf, 0x98d0,
+ 0x98d1, 0x98d2, 0x98d3, 0x98d4, 0x98d5, 0x98d6, 0x98d7, 0x98d8,
+ 0x98d9, 0x98da, 0x98db, 0x98dc, 0x98dd, 0x98de, 0x98df, 0x98e0,
+ 0x98e1, 0x98e2, 0x98e3, 0x98e4, 0x98e5, 0x98e6, 0x98e7, 0x98e8,
+ 0x98e9, 0x98ea, 0x98eb, 0x98ec, 0x98ed, 0x98ee, 0x98ef, 0x98f0,
+ 0x98f1, 0x98f2, 0x98f3, 0x98f4, 0x98f5, 0x98f6, 0x98f7, 0x98f8,
+ 0x98f9, 0x98fa, 0x98fb, 0x98fc, 0x98fd, 0x98fe, 0x9940, 0x9941,
+ 0x9942, 0x9943, 0x9944, 0x9945, 0x9946, 0x9947, 0x9948, 0x9949,
+ 0x994a, 0x994b, 0x994c, 0x994d, 0x994e, 0x994f, 0x9950, 0x9951,
+ 0x9952, 0x9953, 0x9954, 0x9955, 0x9956, 0x9957, 0x9958, 0x9959,
+ 0x995a, 0x995b, 0x995c, 0x995d, 0x995e, 0x995f, 0x9960, 0x9961,
+ 0x9962, 0x9963, 0x9964, 0x9965, 0x9966, 0x9967, 0x9968, 0x9969,
+ 0x996a, 0x996b, 0x996c, 0x996d, 0x996e, 0x996f, 0x9970, 0x9971,
+ 0x9972, 0x9973, 0x9974, 0x9975, 0x9976, 0x9977, 0x9978, 0x9979,
+ 0x997a, 0x997b, 0x997c, 0x997d, 0x997e, 0x9980, 0x9981, 0x9982,
+ 0x9983, 0x9984, 0x9985, 0x9986, 0x9987, 0x9988, 0x9989, 0x998a,
+ 0x998b, 0x998c, 0x998d, 0x998e, 0x998f, 0x9990, 0x9991, 0x9992,
+ 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998, 0x9999, 0x999a,
+ 0x999b, 0x999c, 0x999d, 0x999e, 0x999f, 0x99a0, 0x99a1, 0x99a2,
+ 0x99a3, 0x99a4, 0x99a5, 0x99a6, 0x99a7, 0x99a8, 0x99a9, 0x99aa,
+ 0x99ab, 0x99ac, 0x99ad, 0x99ae, 0x99af, 0x99b0, 0x99b1, 0x99b2,
+ 0x99b3, 0x99b4, 0x99b5, 0x99b6, 0x99b7, 0x99b8, 0x99b9, 0x99ba,
+ 0x99bb, 0x99bc, 0x99bd, 0x99be, 0x99bf, 0x99c0, 0x99c1, 0x99c2,
+ 0x99c3, 0x99c4, 0x99c5, 0x99c6, 0x99c7, 0x99c8, 0x99c9, 0x99ca,
+ 0x99cb, 0x99cc, 0x99cd, 0x99ce, 0x99cf, 0x99d0, 0x99d1, 0x99d2,
+ 0x99d3, 0x99d4, 0x99d5, 0x99d6, 0x99d7, 0x99d8, 0x99d9, 0x99da,
+ 0x99db, 0x99dc, 0x99dd, 0x99de, 0x99df, 0x99e0, 0x99e1, 0x99e2,
+ 0x99e3, 0x99e4, 0x99e5, 0x99e6, 0x99e7, 0x99e8, 0x99e9, 0x99ea,
+ 0x99eb, 0x99ec, 0x99ed, 0x99ee, 0x99ef, 0x99f0, 0x99f1, 0x99f2,
+ 0x99f3, 0x99f4, 0x99f5, 0x99f6, 0x99f7, 0x99f8, 0x99f9, 0x99fa,
+ 0x99fb, 0x99fc, 0x99fd, 0x99fe, 0x9a40, 0x9a41, 0x9a42, 0x9a43,
+ 0x9a44, 0x9a45, 0x9a46, 0x9a47, 0x9a48, 0x9a49, 0x9a4a, 0x9a4b,
+ 0x9a4c, 0x9a4d, 0x9a4e, 0x9a4f, 0x9a50, 0x9a51, 0x9a52, 0x9a53,
+ 0x9a54, 0x9a55, 0x9a56, 0x9a57, 0x9a58, 0x9a59, 0x9a5a, 0x9a5b,
+ 0x9a5c, 0x9a5d, 0x9a5e, 0x9a5f, 0x9a60, 0x9a61, 0x9a62, 0x9a63,
+ 0x9a64, 0x9a65, 0x9a66, 0x9a67, 0x9a68, 0x9a69, 0x9a6a, 0x9a6b,
+ 0x9a6c, 0x9a6d, 0x9a6e, 0x9a6f, 0x9a70, 0x9a71, 0x9a72, 0x9a73,
+ 0x9a74, 0x9a75, 0x9a76, 0x9a77, 0x9a78, 0x9a79, 0x9a7a, 0x9a7b,
+ 0x9a7c, 0x9a7d, 0x9a7e, 0x9a80, 0x9a81, 0x9a82, 0x9a83, 0x9a84,
+ 0x9a85, 0x9a86, 0x9a87, 0x9a88, 0x9a89, 0x9a8a, 0x9a8b, 0x9a8c,
+ 0x9a8d, 0x9a8e, 0x9a8f, 0x9a90, 0x9a91, 0x9a92, 0x9a93, 0x9a94,
+ 0x9a95, 0x9a96, 0x9a97, 0x9a98, 0x9a99, 0x9a9a, 0x9a9b, 0x9a9c,
+ 0x9a9d, 0x9a9e, 0x9a9f, 0x9aa0, 0x9aa1, 0x9aa2, 0x9aa3, 0x9aa4,
+ 0x9aa5, 0x9aa6, 0x9aa7, 0x9aa8, 0x9aa9, 0x9aaa, 0x9aab, 0x9aac,
+ 0x9aad, 0x9aae, 0x9aaf, 0x9ab0, 0x9ab1, 0x9ab2, 0x9ab3, 0x9ab4,
+ 0x9ab5, 0x9ab6, 0x9ab7, 0x9ab8, 0x9ab9, 0x9aba, 0x9abb, 0x9abc,
+ 0x9abd, 0x9abe, 0x9abf, 0x9ac0, 0x9ac1, 0x9ac2, 0x9ac3, 0x9ac4,
+ 0x9ac5, 0x9ac6, 0x9ac7, 0x9ac8, 0x9ac9, 0x9aca, 0x9acb, 0x9acc,
+ 0x9acd, 0x9ace, 0x9acf, 0x9ad0, 0x9ad1, 0x9ad2, 0x9ad3, 0x9ad4,
+ 0x9ad5, 0x9ad6, 0x9ad7, 0x9ad8, 0x9ad9, 0x9ada, 0x9adb, 0x9adc,
+ 0x9add, 0x9ade, 0x9adf, 0x9ae0, 0x9ae1, 0x9ae2, 0x9ae3, 0x9ae4,
+ 0x9ae5, 0x9ae6, 0x9ae7, 0x9ae8, 0x9ae9, 0x9aea, 0x9aeb, 0x9aec,
+ 0x9aed, 0x9aee, 0x9aef, 0x9af0, 0x9af1, 0x9af2, 0x9af3, 0x9af4,
+ 0x9af5, 0x9af6, 0x9af7, 0x9af8, 0x9af9, 0x9afa, 0x9afb, 0x9afc,
+ 0x9afd, 0x9afe, 0x9b40, 0x9b41, 0x9b42, 0x9b43, 0x9b44, 0x9b45,
+ 0x9b46, 0x9b47, 0x9b48, 0x9b49, 0x9b4a, 0x9b4b, 0x9b4c, 0x9b4d,
+ 0x9b4e, 0x9b4f, 0x9b50, 0x9b51, 0x9b52, 0x9b53, 0x9b54, 0x9b55,
+ 0x9b56, 0x9b57, 0x9b58, 0x9b59, 0x9b5a, 0x9b5b, 0x9b5c, 0x9b5d,
+ 0x9b5e, 0x9b5f, 0x9b60, 0x9b61, 0x9b62, 0x9b63, 0x9b64, 0x9b65,
+ 0x9b66, 0x9b67, 0x9b68, 0x9b69, 0x9b6a, 0x9b6b, 0x9b6c, 0x9b6d,
+ 0x9b6e, 0x9b6f, 0x9b70, 0x9b71, 0x9b72, 0x9b73, 0x9b74, 0x9b75,
+ 0x9b76, 0x9b77, 0x9b78, 0x9b79, 0x9b7a, 0x9b7b, 0x9b7c, 0x9b7d,
+ 0x9b7e, 0x9b80, 0x9b81, 0x9b82, 0x9b83, 0x9b84, 0x9b85, 0x9b86,
+ 0x9b87, 0x9b88, 0x9b89, 0x9b8a, 0x9b8b, 0x9b8c, 0x9b8d, 0x9b8e,
+ 0x9b8f, 0x9b90, 0x9b91, 0x9b92, 0x9b93, 0x9b94, 0x9b95, 0x9b96,
+ 0x9b97, 0x9b98, 0x9b99, 0x9b9a, 0x9b9b, 0x9b9c, 0x9b9d, 0x9b9e,
+ 0x9b9f, 0x9ba0, 0x9ba1, 0x9ba2, 0x9ba3, 0x9ba4, 0x9ba5, 0x9ba6,
+ 0x9ba7, 0x9ba8, 0x9ba9, 0x9baa, 0x9bab, 0x9bac, 0x9bad, 0x9bae,
+ 0x9baf, 0x9bb0, 0x9bb1, 0x9bb2, 0x9bb3, 0x9bb4, 0x9bb5, 0x9bb6,
+ 0x9bb7, 0x9bb8, 0x9bb9, 0x9bba, 0x9bbb, 0x9bbc, 0x9bbd, 0x9bbe,
+ 0x9bbf, 0x9bc0, 0x9bc1, 0x9bc2, 0x9bc3, 0x9bc4, 0x9bc5, 0x9bc6,
+ 0x9bc7, 0x9bc8, 0x9bc9, 0x9bca, 0x9bcb, 0x9bcc, 0x9bcd, 0x9bce,
+ 0x9bcf, 0x9bd0, 0x9bd1, 0x9bd2, 0x9bd3, 0x9bd4, 0x9bd5, 0x9bd6,
+ 0x9bd7, 0x9bd8, 0x9bd9, 0x9bda, 0x9bdb, 0x9bdc, 0x9bdd, 0x9bde,
+ 0x9bdf, 0x9be0, 0x9be1, 0x9be2, 0x9be3, 0x9be4, 0x9be5, 0x9be6,
+ 0x9be7, 0x9be8, 0x9be9, 0x9bea, 0x9beb, 0x9bec, 0x9bed, 0x9bee,
+ 0x9bef, 0x9bf0, 0x9bf1, 0x9bf2, 0x9bf3, 0x9bf4, 0x9bf5, 0x9bf6,
+ 0x9bf7, 0x9bf8, 0x9bf9, 0x9bfa, 0x9bfb, 0x9bfc, 0x9bfd, 0x9bfe,
+ 0x9c40, 0x9c41, 0x9c42, 0x9c43, 0x9c44, 0x9c45, 0x9c46, 0x9c47,
+ 0x9c48, 0x9c49, 0x9c4a, 0x9c4b, 0x9c4c, 0x9c4d, 0x9c4e, 0x9c4f,
+ 0x9c50, 0x9c51, 0x9c52, 0x9c53, 0x9c54, 0x9c55, 0x9c56, 0x9c57,
+ 0x9c58, 0x9c59, 0x9c5a, 0x9c5b, 0x9c5c, 0x9c5d, 0x9c5e, 0x9c5f,
+ 0x9c60, 0x9c61, 0x9c62, 0x9c63, 0x9c64, 0x9c65, 0x9c66, 0x9c67,
+ 0x9c68, 0x9c69, 0x9c6a, 0x9c6b, 0x9c6c, 0x9c6d, 0x9c6e, 0x9c6f,
+ 0x9c70, 0x9c71, 0x9c72, 0x9c73, 0x9c74, 0x9c75, 0x9c76, 0x9c77,
+ 0x9c78, 0x9c79, 0x9c7a, 0x9c7b, 0x9c7c, 0x9c7d, 0x9c7e, 0x9c80,
+ 0x9c81, 0x9c82, 0x9c83, 0x9c84, 0x9c85, 0x9c86, 0x9c87, 0x9c88,
+ 0x9c89, 0x9c8a, 0x9c8b, 0x9c8c, 0x9c8d, 0x9c8e, 0x9c8f, 0x9c90,
+ 0x9c91, 0x9c92, 0x9c93, 0x9c94, 0x9c95, 0x9c96, 0x9c97, 0x9c98,
+ 0x9c99, 0x9c9a, 0x9c9b, 0x9c9c, 0x9c9d, 0x9c9e, 0x9c9f, 0x9ca0,
+ 0x9ca1, 0x9ca2, 0x9ca3, 0x9ca4, 0x9ca5, 0x9ca6, 0x9ca7, 0x9ca8,
+ 0x9ca9, 0x9caa, 0x9cab, 0x9cac, 0x9cad, 0x9cae, 0x9caf, 0x9cb0,
+ 0x9cb1, 0x9cb2, 0x9cb3, 0x9cb4, 0x9cb5, 0x9cb6, 0x9cb7, 0x9cb8,
+ 0x9cb9, 0x9cba, 0x9cbb, 0x9cbc, 0x9cbd, 0x9cbe, 0x9cbf, 0x9cc0,
+ 0x9cc1, 0x9cc2, 0x9cc3, 0x9cc4, 0x9cc5, 0x9cc6, 0x9cc7, 0x9cc8,
+ 0x9cc9, 0x9cca, 0x9ccb, 0x9ccc, 0x9ccd, 0x9cce, 0x9ccf, 0x9cd0,
+ 0x9cd1, 0x9cd2, 0x9cd3, 0x9cd4, 0x9cd5, 0x9cd6, 0x9cd7, 0x9cd8,
+ 0x9cd9, 0x9cda, 0x9cdb, 0x9cdc, 0x9cdd, 0x9cde, 0x9cdf, 0x9ce0,
+ 0x9ce1, 0x9ce2, 0x9ce3, 0x9ce4, 0x9ce5, 0x9ce6, 0x9ce7, 0x9ce8,
+ 0x9ce9, 0x9cea, 0x9ceb, 0x9cec, 0x9ced, 0x9cee, 0x9cef, 0x9cf0,
+ 0x9cf1, 0x9cf2, 0x9cf3, 0x9cf4, 0x9cf5, 0x9cf6, 0x9cf7, 0x9cf8,
+ 0x9cf9, 0x9cfa, 0x9cfb, 0x9cfc, 0x9cfd, 0x9cfe, 0x9d40, 0x9d41,
+ 0x9d42, 0x9d43, 0x9d44, 0x9d45, 0x9d46, 0x9d47, 0x9d48, 0x9d49,
+ 0x9d4a, 0x9d4b, 0x9d4c, 0x9d4d, 0x9d4e, 0x9d4f, 0x9d50, 0x9d51,
+ 0x9d52, 0x9d53, 0x9d54, 0x9d55, 0x9d56, 0x9d57, 0x9d58, 0x9d59,
+ 0x9d5a, 0x9d5b, 0x9d5c, 0x9d5d, 0x9d5e, 0x9d5f, 0x9d60, 0x9d61,
+ 0x9d62, 0x9d63, 0x9d64, 0x9d65, 0x9d66, 0x9d67, 0x9d68, 0x9d69,
+ 0x9d6a, 0x9d6b, 0x9d6c, 0x9d6d, 0x9d6e, 0x9d6f, 0x9d70, 0x9d71,
+ 0x9d72, 0x9d73, 0x9d74, 0x9d75, 0x9d76, 0x9d77, 0x9d78, 0x9d79,
+ 0x9d7a, 0x9d7b, 0x9d7c, 0x9d7d, 0x9d7e, 0x9d80, 0x9d81, 0x9d82,
+ 0x9d83, 0x9d84, 0x9d85, 0x9d86, 0x9d87, 0x9d88, 0x9d89, 0x9d8a,
+ 0x9d8b, 0x9d8c, 0x9d8d, 0x9d8e, 0x9d8f, 0x9d90, 0x9d91, 0x9d92,
+ 0x9d93, 0x9d94, 0x9d95, 0x9d96, 0x9d97, 0x9d98, 0x9d99, 0x9d9a,
+ 0x9d9b, 0x9d9c, 0x9d9d, 0x9d9e, 0x9d9f, 0x9da0, 0x9da1, 0x9da2,
+ 0x9da3, 0x9da4, 0x9da5, 0x9da6, 0x9da7, 0x9da8, 0x9da9, 0x9daa,
+ 0x9dab, 0x9dac, 0x9dad, 0x9dae, 0x9daf, 0x9db0, 0x9db1, 0x9db2,
+ 0x9db3, 0x9db4, 0x9db5, 0x9db6, 0x9db7, 0x9db8, 0x9db9, 0x9dba,
+ 0x9dbb, 0x9dbc, 0x9dbd, 0x9dbe, 0x9dbf, 0x9dc0, 0x9dc1, 0x9dc2,
+ 0x9dc3, 0x9dc4, 0x9dc5, 0x9dc6, 0x9dc7, 0x9dc8, 0x9dc9, 0x9dca,
+ 0x9dcb, 0x9dcc, 0x9dcd, 0x9dce, 0x9dcf, 0x9dd0, 0x9dd1, 0x9dd2,
+ 0x9dd3, 0x9dd4, 0x9dd5, 0x9dd6, 0x9dd7, 0x9dd8, 0x9dd9, 0x9dda,
+ 0x9ddb, 0x9ddc, 0x9ddd, 0x9dde, 0x9ddf, 0x9de0, 0x9de1, 0x9de2,
+ 0x9de3, 0x9de4, 0x9de5, 0x9de6, 0x9de7, 0x9de8, 0x9de9, 0x9dea,
+ 0x9deb, 0x9dec, 0x9ded, 0x9dee, 0x9def, 0x9df0, 0x9df1, 0x9df2,
+ 0x9df3, 0x9df4, 0x9df5, 0x9df6, 0x9df7, 0x9df8, 0x9df9, 0x9dfa,
+ 0x9dfb, 0x9dfc, 0x9dfd, 0x9dfe, 0x9e40, 0x9e41, 0x9e42, 0x9e43,
+ 0x9e44, 0x9e45, 0x9e46, 0x9e47, 0x9e48, 0x9e49, 0x9e4a, 0x9e4b,
+ 0x9e4c, 0x9e4d, 0x9e4e, 0x9e4f, 0x9e50, 0x9e51, 0x9e52, 0x9e53,
+ 0x9e54, 0x9e55, 0x9e56, 0x9e57, 0x9e58, 0x9e59, 0x9e5a, 0x9e5b,
+ 0x9e5c, 0x9e5d, 0x9e5e, 0x9e5f, 0x9e60, 0x9e61, 0x9e62, 0x9e63,
+ 0x9e64, 0x9e65, 0x9e66, 0x9e67, 0x9e68, 0x9e69, 0x9e6a, 0x9e6b,
+ 0x9e6c, 0x9e6d, 0x9e6e, 0x9e6f, 0x9e70, 0x9e71, 0x9e72, 0x9e73,
+ 0x9e74, 0x9e75, 0x9e76, 0x9e77, 0x9e78, 0x9e79, 0x9e7a, 0x9e7b,
+ 0x9e7c, 0x9e7d, 0x9e7e, 0x9e80, 0x9e81, 0x9e82, 0x9e83, 0x9e84,
+ 0x9e85, 0x9e86, 0x9e87, 0x9e88, 0x9e89, 0x9e8a, 0x9e8b, 0x9e8c,
+ 0x9e8d, 0x9e8e, 0x9e8f, 0x9e90, 0x9e91, 0x9e92, 0x9e93, 0x9e94,
+ 0x9e95, 0x9e96, 0x9e97, 0x9e98, 0x9e99, 0x9e9a, 0x9e9b, 0x9e9c,
+ 0x9e9d, 0x9e9e, 0x9e9f, 0x9ea0, 0x9ea1, 0x9ea2, 0x9ea3, 0x9ea4,
+ 0x9ea5, 0x9ea6, 0x9ea7, 0x9ea8, 0x9ea9, 0x9eaa, 0x9eab, 0x9eac,
+ 0x9ead, 0x9eae, 0x9eaf, 0x9eb0, 0x9eb1, 0x9eb2, 0x9eb3, 0x9eb4,
+ 0x9eb5, 0x9eb6, 0x9eb7, 0x9eb8, 0x9eb9, 0x9eba, 0x9ebb, 0x9ebc,
+ 0x9ebd, 0x9ebe, 0x9ebf, 0x9ec0, 0x9ec1, 0x9ec2, 0x9ec3, 0x9ec4,
+ 0x9ec5, 0x9ec6, 0x9ec7, 0x9ec8, 0x9ec9, 0x9eca, 0x9ecb, 0x9ecc,
+ 0x9ecd, 0x9ece, 0x9ecf, 0x9ed0, 0x9ed1, 0x9ed2, 0x9ed3, 0x9ed4,
+ 0x9ed5, 0x9ed6, 0x9ed7, 0x9ed8, 0x9ed9, 0x9eda, 0x9edb, 0x9edc,
+ 0x9edd, 0x9ede, 0x9edf, 0x9ee0, 0x9ee1, 0x9ee2, 0x9ee3, 0x9ee4,
+ 0x9ee5, 0x9ee6, 0x9ee7, 0x9ee8, 0x9ee9, 0x9eea, 0x9eeb, 0x9eec,
+ 0x9eed, 0x9eee, 0x9eef, 0x9ef0, 0x9ef1, 0x9ef2, 0x9ef3, 0x9ef4,
+ 0x9ef5, 0x9ef6, 0x9ef7, 0x9ef8, 0x9ef9, 0x9efa, 0x9efb, 0x9efc,
+ 0x9efd, 0x9efe, 0x9f40, 0x9f41, 0x9f42, 0x9f43, 0x9f44, 0x9f45,
+ 0x9f46, 0x9f47, 0x9f48, 0x9f49, 0x9f4a, 0x9f4b, 0x9f4c, 0x9f4d,
+ 0x9f4e, 0x9f4f, 0x9f50, 0x9f51, 0x9f52, 0x9f53, 0x9f54, 0x9f55,
+ 0x9f56, 0x9f57, 0x9f58, 0x9f59, 0x9f5a, 0x9f5b, 0x9f5c, 0x9f5d,
+ 0x9f5e, 0x9f5f, 0x9f60, 0x9f61, 0x9f62, 0x9f63, 0x9f64, 0x9f65,
+ 0x9f66, 0x9f67, 0x9f68, 0x9f69, 0x9f6a, 0x9f6b, 0x9f6c, 0x9f6d,
+ 0x9f6e, 0x9f6f, 0x9f70, 0x9f71, 0x9f72, 0x9f73, 0x9f74, 0x9f75,
+ 0x9f76, 0x9f77, 0x9f78, 0x9f79, 0x9f7a, 0x9f7b, 0x9f7c, 0x9f7d,
+ 0x9f7e, 0x9f80, 0x9f81, 0x9f82, 0x9f83, 0x9f84, 0x9f85, 0x9f86,
+ 0x9f87, 0x9f88, 0x9f89, 0x9f8a, 0x9f8b, 0x9f8c, 0x9f8d, 0x9f8e,
+ 0x9f8f, 0x9f90, 0x9f91, 0x9f92, 0x9f93, 0x9f94, 0x9f95, 0x9f96,
+ 0x9f97, 0x9f98, 0x9f99, 0x9f9a, 0x9f9b, 0x9f9c, 0x9f9d, 0x9f9e,
+ 0x9f9f, 0x9fa0, 0x9fa1, 0x9fa2, 0x9fa3, 0x9fa4, 0x9fa5, 0x9fa6,
+ 0x9fa7, 0x9fa8, 0x9fa9, 0x9faa, 0x9fab, 0x9fac, 0x9fad, 0x9fae,
+ 0x9faf, 0x9fb0, 0x9fb1, 0x9fb2, 0x9fb3, 0x9fb4, 0x9fb5, 0x9fb6,
+ 0x9fb7, 0x9fb8, 0x9fb9, 0x9fba, 0x9fbb, 0x9fbc, 0x9fbd, 0x9fbe,
+ 0x9fbf, 0x9fc0, 0x9fc1, 0x9fc2, 0x9fc3, 0x9fc4, 0x9fc5, 0x9fc6,
+ 0x9fc7, 0x9fc8, 0x9fc9, 0x9fca, 0x9fcb, 0x9fcc, 0x9fcd, 0x9fce,
+ 0x9fcf, 0x9fd0, 0x9fd1, 0x9fd2, 0x9fd3, 0x9fd4, 0x9fd5, 0x9fd6,
+ 0x9fd7, 0x9fd8, 0x9fd9, 0x9fda, 0x9fdb, 0x9fdc, 0x9fdd, 0x9fde,
+ 0x9fdf, 0x9fe0, 0x9fe1, 0x9fe2, 0x9fe3, 0x9fe4, 0x9fe5, 0x9fe6,
+ 0x9fe7, 0x9fe8, 0x9fe9, 0x9fea, 0x9feb, 0x9fec, 0x9fed, 0x9fee,
+ 0x9fef, 0x9ff0, 0x9ff1, 0x9ff2, 0x9ff3, 0x9ff4, 0x9ff5, 0x9ff6,
+ 0x9ff7, 0x9ff8, 0x9ff9, 0x9ffa, 0x9ffb, 0x9ffc, 0x9ffd, 0x9ffe,
+ 0xa040, 0xa041, 0xa042, 0xa043, 0xa044, 0xa045, 0xa046, 0xa047,
+ 0xa048, 0xa049, 0xa04a, 0xa04b, 0xa04c, 0xa04d, 0xa04e, 0xa04f,
+ 0xa050, 0xa051, 0xa052, 0xa053, 0xa054, 0xa055, 0xa056, 0xa057,
+ 0xa058, 0xa059, 0xa05a, 0xa05b, 0xa05c, 0xa05d, 0xa05e, 0xa05f,
+ 0xa060, 0xa061, 0xa062, 0xa063, 0xa064, 0xa065, 0xa066, 0xa067,
+ 0xa068, 0xa069, 0xa06a, 0xa06b, 0xa06c, 0xa06d, 0xa06e, 0xa06f,
+ 0xa070, 0xa071, 0xa072, 0xa073, 0xa074, 0xa075, 0xa076, 0xa077,
+ 0xa078, 0xa079, 0xa07a, 0xa07b, 0xa07c, 0xa07d, 0xa07e, 0xa080,
+ 0xa081, 0xa082, 0xa083, 0xa084, 0xa085, 0xa086, 0xa087, 0xa088,
+ 0xa089, 0xa08a, 0xa08b, 0xa08c, 0xa08d, 0xa08e, 0xa08f, 0xa090,
+ 0xa091, 0xa092, 0xa093, 0xa094, 0xa095, 0xa096, 0xa097, 0xa098,
+ 0xa099, 0xa09a, 0xa09b, 0xa09c, 0xa09d, 0xa09e, 0xa09f, 0xa0a0,
+ 0xa0a1, 0xa0a2, 0xa0a3, 0xa0a4, 0xa0a5, 0xa0a6, 0xa0a7, 0xa0a8,
+ 0xa0a9, 0xa0aa, 0xa0ab, 0xa0ac, 0xa0ad, 0xa0ae, 0xa0af, 0xa0b0,
+ 0xa0b1, 0xa0b2, 0xa0b3, 0xa0b4, 0xa0b5, 0xa0b6, 0xa0b7, 0xa0b8,
+ 0xa0b9, 0xa0ba, 0xa0bb, 0xa0bc, 0xa0bd, 0xa0be, 0xa0bf, 0xa0c0,
+ 0xa0c1, 0xa0c2, 0xa0c3, 0xa0c4, 0xa0c5, 0xa0c6, 0xa0c7, 0xa0c8,
+ 0xa0c9, 0xa0ca, 0xa0cb, 0xa0cc, 0xa0cd, 0xa0ce, 0xa0cf, 0xa0d0,
+ 0xa0d1, 0xa0d2, 0xa0d3, 0xa0d4, 0xa0d5, 0xa0d6, 0xa0d7, 0xa0d8,
+ 0xa0d9, 0xa0da, 0xa0db, 0xa0dc, 0xa0dd, 0xa0de, 0xa0df, 0xa0e0,
+ 0xa0e1, 0xa0e2, 0xa0e3, 0xa0e4, 0xa0e5, 0xa0e6, 0xa0e7, 0xa0e8,
+ 0xa0e9, 0xa0ea, 0xa0eb, 0xa0ec, 0xa0ed, 0xa0ee, 0xa0ef, 0xa0f0,
+ 0xa0f1, 0xa0f2, 0xa0f3, 0xa0f4, 0xa0f5, 0xa0f6, 0xa0f7, 0xa0f8,
+ 0xa0f9, 0xa0fa, 0xa0fb, 0xa0fc, 0xa0fd, 0xa0fe, 0xaa40, 0xaa41,
+ 0xaa42, 0xaa43, 0xaa44, 0xaa45, 0xaa46, 0xaa47, 0xaa48, 0xaa49,
+ 0xaa4a, 0xaa4b, 0xaa4c, 0xaa4d, 0xaa4e, 0xaa4f, 0xaa50, 0xaa51,
+ 0xaa52, 0xaa53, 0xaa54, 0xaa55, 0xaa56, 0xaa57, 0xaa58, 0xaa59,
+ 0xaa5a, 0xaa5b, 0xaa5c, 0xaa5d, 0xaa5e, 0xaa5f, 0xaa60, 0xaa61,
+ 0xaa62, 0xaa63, 0xaa64, 0xaa65, 0xaa66, 0xaa67, 0xaa68, 0xaa69,
+ 0xaa6a, 0xaa6b, 0xaa6c, 0xaa6d, 0xaa6e, 0xaa6f, 0xaa70, 0xaa71,
+ 0xaa72, 0xaa73, 0xaa74, 0xaa75, 0xaa76, 0xaa77, 0xaa78, 0xaa79,
+ 0xaa7a, 0xaa7b, 0xaa7c, 0xaa7d, 0xaa7e, 0xaa80, 0xaa81, 0xaa82,
+ 0xaa83, 0xaa84, 0xaa85, 0xaa86, 0xaa87, 0xaa88, 0xaa89, 0xaa8a,
+ 0xaa8b, 0xaa8c, 0xaa8d, 0xaa8e, 0xaa8f, 0xaa90, 0xaa91, 0xaa92,
+ 0xaa93, 0xaa94, 0xaa95, 0xaa96, 0xaa97, 0xaa98, 0xaa99, 0xaa9a,
+ 0xaa9b, 0xaa9c, 0xaa9d, 0xaa9e, 0xaa9f, 0xaaa0, 0xab40, 0xab41,
+ 0xab42, 0xab43, 0xab44, 0xab45, 0xab46, 0xab47, 0xab48, 0xab49,
+ 0xab4a, 0xab4b, 0xab4c, 0xab4d, 0xab4e, 0xab4f, 0xab50, 0xab51,
+ 0xab52, 0xab53, 0xab54, 0xab55, 0xab56, 0xab57, 0xab58, 0xab59,
+ 0xab5a, 0xab5b, 0xab5c, 0xab5d, 0xab5e, 0xab5f, 0xab60, 0xab61,
+ 0xab62, 0xab63, 0xab64, 0xab65, 0xab66, 0xab67, 0xab68, 0xab69,
+ 0xab6a, 0xab6b, 0xab6c, 0xab6d, 0xab6e, 0xab6f, 0xab70, 0xab71,
+ 0xab72, 0xab73, 0xab74, 0xab75, 0xab76, 0xab77, 0xab78, 0xab79,
+ 0xab7a, 0xab7b, 0xab7c, 0xab7d, 0xab7e, 0xab80, 0xab81, 0xab82,
+ 0xab83, 0xab84, 0xab85, 0xab86, 0xab87, 0xab88, 0xab89, 0xab8a,
+ 0xab8b, 0xab8c, 0xab8d, 0xab8e, 0xab8f, 0xab90, 0xab91, 0xab92,
+ 0xab93, 0xab94, 0xab95, 0xab96, 0xab97, 0xab98, 0xab99, 0xab9a,
+ 0xab9b, 0xab9c, 0xab9d, 0xab9e, 0xab9f, 0xaba0, 0xac40, 0xac41,
+ 0xac42, 0xac43, 0xac44, 0xac45, 0xac46, 0xac47, 0xac48, 0xac49,
+ 0xac4a, 0xac4b, 0xac4c, 0xac4d, 0xac4e, 0xac4f, 0xac50, 0xac51,
+ 0xac52, 0xac53, 0xac54, 0xac55, 0xac56, 0xac57, 0xac58, 0xac59,
+ 0xac5a, 0xac5b, 0xac5c, 0xac5d, 0xac5e, 0xac5f, 0xac60, 0xac61,
+ 0xac62, 0xac63, 0xac64, 0xac65, 0xac66, 0xac67, 0xac68, 0xac69,
+ 0xac6a, 0xac6b, 0xac6c, 0xac6d, 0xac6e, 0xac6f, 0xac70, 0xac71,
+ 0xac72, 0xac73, 0xac74, 0xac75, 0xac76, 0xac77, 0xac78, 0xac79,
+ 0xac7a, 0xac7b, 0xac7c, 0xac7d, 0xac7e, 0xac80, 0xac81, 0xac82,
+ 0xac83, 0xac84, 0xac85, 0xac86, 0xac87, 0xac88, 0xac89, 0xac8a,
+ 0xac8b, 0xac8c, 0xac8d, 0xac8e, 0xac8f, 0xac90, 0xac91, 0xac92,
+ 0xac93, 0xac94, 0xac95, 0xac96, 0xac97, 0xac98, 0xac99, 0xac9a,
+ 0xac9b, 0xac9c, 0xac9d, 0xac9e, 0xac9f, 0xaca0, 0xad40, 0xad41,
+ 0xad42, 0xad43, 0xad44, 0xad45, 0xad46, 0xad47, 0xad48, 0xad49,
+ 0xad4a, 0xad4b, 0xad4c, 0xad4d, 0xad4e, 0xad4f, 0xad50, 0xad51,
+ 0xad52, 0xad53, 0xad54, 0xad55, 0xad56, 0xad57, 0xad58, 0xad59,
+ 0xad5a, 0xad5b, 0xad5c, 0xad5d, 0xad5e, 0xad5f, 0xad60, 0xad61,
+ 0xad62, 0xad63, 0xad64, 0xad65, 0xad66, 0xad67, 0xad68, 0xad69,
+ 0xad6a, 0xad6b, 0xad6c, 0xad6d, 0xad6e, 0xad6f, 0xad70, 0xad71,
+ 0xad72, 0xad73, 0xad74, 0xad75, 0xad76, 0xad77, 0xad78, 0xad79,
+ 0xad7a, 0xad7b, 0xad7c, 0xad7d, 0xad7e, 0xad80, 0xad81, 0xad82,
+ 0xad83, 0xad84, 0xad85, 0xad86, 0xad87, 0xad88, 0xad89, 0xad8a,
+ 0xad8b, 0xad8c, 0xad8d, 0xad8e, 0xad8f, 0xad90, 0xad91, 0xad92,
+ 0xad93, 0xad94, 0xad95, 0xad96, 0xad97, 0xad98, 0xad99, 0xad9a,
+ 0xad9b, 0xad9c, 0xad9d, 0xad9e, 0xad9f, 0xada0, 0xae40, 0xae41,
+ 0xae42, 0xae43, 0xae44, 0xae45, 0xae46, 0xae47, 0xae48, 0xae49,
+ 0xae4a, 0xae4b, 0xae4c, 0xae4d, 0xae4e, 0xae4f, 0xae50, 0xae51,
+ 0xae52, 0xae53, 0xae54, 0xae55, 0xae56, 0xae57, 0xae58, 0xae59,
+ 0xae5a, 0xae5b, 0xae5c, 0xae5d, 0xae5e, 0xae5f, 0xae60, 0xae61,
+ 0xae62, 0xae63, 0xae64, 0xae65, 0xae66, 0xae67, 0xae68, 0xae69,
+ 0xae6a, 0xae6b, 0xae6c, 0xae6d, 0xae6e, 0xae6f, 0xae70, 0xae71,
+ 0xae72, 0xae73, 0xae74, 0xae75, 0xae76, 0xae77, 0xae78, 0xae79,
+ 0xae7a, 0xae7b, 0xae7c, 0xae7d, 0xae7e, 0xae80, 0xae81, 0xae82,
+ 0xae83, 0xae84, 0xae85, 0xae86, 0xae87, 0xae88, 0xae89, 0xae8a,
+ 0xae8b, 0xae8c, 0xae8d, 0xae8e, 0xae8f, 0xae90, 0xae91, 0xae92,
+ 0xae93, 0xae94, 0xae95, 0xae96, 0xae97, 0xae98, 0xae99, 0xae9a,
+ 0xae9b, 0xae9c, 0xae9d, 0xae9e, 0xae9f, 0xaea0, 0xaf40, 0xaf41,
+ 0xaf42, 0xaf43, 0xaf44, 0xaf45, 0xaf46, 0xaf47, 0xaf48, 0xaf49,
+ 0xaf4a, 0xaf4b, 0xaf4c, 0xaf4d, 0xaf4e, 0xaf4f, 0xaf50, 0xaf51,
+ 0xaf52, 0xaf53, 0xaf54, 0xaf55, 0xaf56, 0xaf57, 0xaf58, 0xaf59,
+ 0xaf5a, 0xaf5b, 0xaf5c, 0xaf5d, 0xaf5e, 0xaf5f, 0xaf60, 0xaf61,
+ 0xaf62, 0xaf63, 0xaf64, 0xaf65, 0xaf66, 0xaf67, 0xaf68, 0xaf69,
+ 0xaf6a, 0xaf6b, 0xaf6c, 0xaf6d, 0xaf6e, 0xaf6f, 0xaf70, 0xaf71,
+ 0xaf72, 0xaf73, 0xaf74, 0xaf75, 0xaf76, 0xaf77, 0xaf78, 0xaf79,
+ 0xaf7a, 0xaf7b, 0xaf7c, 0xaf7d, 0xaf7e, 0xaf80, 0xaf81, 0xaf82,
+ 0xaf83, 0xaf84, 0xaf85, 0xaf86, 0xaf87, 0xaf88, 0xaf89, 0xaf8a,
+ 0xaf8b, 0xaf8c, 0xaf8d, 0xaf8e, 0xaf8f, 0xaf90, 0xaf91, 0xaf92,
+ 0xaf93, 0xaf94, 0xaf95, 0xaf96, 0xaf97, 0xaf98, 0xaf99, 0xaf9a,
+ 0xaf9b, 0xaf9c, 0xaf9d, 0xaf9e, 0xaf9f, 0xafa0, 0xb040, 0xb041,
+ 0xb042, 0xb043, 0xb044, 0xb045, 0xb046, 0xb047, 0xb048, 0xb049,
+ 0xb04a, 0xb04b, 0xb04c, 0xb04d, 0xb04e, 0xb04f, 0xb050, 0xb051,
+ 0xb052, 0xb053, 0xb054, 0xb055, 0xb056, 0xb057, 0xb058, 0xb059,
+ 0xb05a, 0xb05b, 0xb05c, 0xb05d, 0xb05e, 0xb05f, 0xb060, 0xb061,
+ 0xb062, 0xb063, 0xb064, 0xb065, 0xb066, 0xb067, 0xb068, 0xb069,
+ 0xb06a, 0xb06b, 0xb06c, 0xb06d, 0xb06e, 0xb06f, 0xb070, 0xb071,
+ 0xb072, 0xb073, 0xb074, 0xb075, 0xb076, 0xb077, 0xb078, 0xb079,
+ 0xb07a, 0xb07b, 0xb07c, 0xb07d, 0xb07e, 0xb080, 0xb081, 0xb082,
+ 0xb083, 0xb084, 0xb085, 0xb086, 0xb087, 0xb088, 0xb089, 0xb08a,
+ 0xb08b, 0xb08c, 0xb08d, 0xb08e, 0xb08f, 0xb090, 0xb091, 0xb092,
+ 0xb093, 0xb094, 0xb095, 0xb096, 0xb097, 0xb098, 0xb099, 0xb09a,
+ 0xb09b, 0xb09c, 0xb09d, 0xb09e, 0xb09f, 0xb0a0, 0xb140, 0xb141,
+ 0xb142, 0xb143, 0xb144, 0xb145, 0xb146, 0xb147, 0xb148, 0xb149,
+ 0xb14a, 0xb14b, 0xb14c, 0xb14d, 0xb14e, 0xb14f, 0xb150, 0xb151,
+ 0xb152, 0xb153, 0xb154, 0xb155, 0xb156, 0xb157, 0xb158, 0xb159,
+ 0xb15a, 0xb15b, 0xb15c, 0xb15d, 0xb15e, 0xb15f, 0xb160, 0xb161,
+ 0xb162, 0xb163, 0xb164, 0xb165, 0xb166, 0xb167, 0xb168, 0xb169,
+ 0xb16a, 0xb16b, 0xb16c, 0xb16d, 0xb16e, 0xb16f, 0xb170, 0xb171,
+ 0xb172, 0xb173, 0xb174, 0xb175, 0xb176, 0xb177, 0xb178, 0xb179,
+ 0xb17a, 0xb17b, 0xb17c, 0xb17d, 0xb17e, 0xb180, 0xb181, 0xb182,
+ 0xb183, 0xb184, 0xb185, 0xb186, 0xb187, 0xb188, 0xb189, 0xb18a,
+ 0xb18b, 0xb18c, 0xb18d, 0xb18e, 0xb18f, 0xb190, 0xb191, 0xb192,
+ 0xb193, 0xb194, 0xb195, 0xb196, 0xb197, 0xb198, 0xb199, 0xb19a,
+ 0xb19b, 0xb19c, 0xb19d, 0xb19e, 0xb19f, 0xb1a0, 0xb240, 0xb241,
+ 0xb242, 0xb243, 0xb244, 0xb245, 0xb246, 0xb247, 0xb248, 0xb249,
+ 0xb24a, 0xb24b, 0xb24c, 0xb24d, 0xb24e, 0xb24f, 0xb250, 0xb251,
+ 0xb252, 0xb253, 0xb254, 0xb255, 0xb256, 0xb257, 0xb258, 0xb259,
+ 0xb25a, 0xb25b, 0xb25c, 0xb25d, 0xb25e, 0xb25f, 0xb260, 0xb261,
+ 0xb262, 0xb263, 0xb264, 0xb265, 0xb266, 0xb267, 0xb268, 0xb269,
+ 0xb26a, 0xb26b, 0xb26c, 0xb26d, 0xb26e, 0xb26f, 0xb270, 0xb271,
+ 0xb272, 0xb273, 0xb274, 0xb275, 0xb276, 0xb277, 0xb278, 0xb279,
+ 0xb27a, 0xb27b, 0xb27c, 0xb27d, 0xb27e, 0xb280, 0xb281, 0xb282,
+ 0xb283, 0xb284, 0xb285, 0xb286, 0xb287, 0xb288, 0xb289, 0xb28a,
+ 0xb28b, 0xb28c, 0xb28d, 0xb28e, 0xb28f, 0xb290, 0xb291, 0xb292,
+ 0xb293, 0xb294, 0xb295, 0xb296, 0xb297, 0xb298, 0xb299, 0xb29a,
+ 0xb29b, 0xb29c, 0xb29d, 0xb29e, 0xb29f, 0xb2a0, 0xb340, 0xb341,
+ 0xb342, 0xb343, 0xb344, 0xb345, 0xb346, 0xb347, 0xb348, 0xb349,
+ 0xb34a, 0xb34b, 0xb34c, 0xb34d, 0xb34e, 0xb34f, 0xb350, 0xb351,
+ 0xb352, 0xb353, 0xb354, 0xb355, 0xb356, 0xb357, 0xb358, 0xb359,
+ 0xb35a, 0xb35b, 0xb35c, 0xb35d, 0xb35e, 0xb35f, 0xb360, 0xb361,
+ 0xb362, 0xb363, 0xb364, 0xb365, 0xb366, 0xb367, 0xb368, 0xb369,
+ 0xb36a, 0xb36b, 0xb36c, 0xb36d, 0xb36e, 0xb36f, 0xb370, 0xb371,
+ 0xb372, 0xb373, 0xb374, 0xb375, 0xb376, 0xb377, 0xb378, 0xb379,
+ 0xb37a, 0xb37b, 0xb37c, 0xb37d, 0xb37e, 0xb380, 0xb381, 0xb382,
+ 0xb383, 0xb384, 0xb385, 0xb386, 0xb387, 0xb388, 0xb389, 0xb38a,
+ 0xb38b, 0xb38c, 0xb38d, 0xb38e, 0xb38f, 0xb390, 0xb391, 0xb392,
+ 0xb393, 0xb394, 0xb395, 0xb396, 0xb397, 0xb398, 0xb399, 0xb39a,
+ 0xb39b, 0xb39c, 0xb39d, 0xb39e, 0xb39f, 0xb3a0, 0xb440, 0xb441,
+ 0xb442, 0xb443, 0xb444, 0xb445, 0xb446, 0xb447, 0xb448, 0xb449,
+ 0xb44a, 0xb44b, 0xb44c, 0xb44d, 0xb44e, 0xb44f, 0xb450, 0xb451,
+ 0xb452, 0xb453, 0xb454, 0xb455, 0xb456, 0xb457, 0xb458, 0xb459,
+ 0xb45a, 0xb45b, 0xb45c, 0xb45d, 0xb45e, 0xb45f, 0xb460, 0xb461,
+ 0xb462, 0xb463, 0xb464, 0xb465, 0xb466, 0xb467, 0xb468, 0xb469,
+ 0xb46a, 0xb46b, 0xb46c, 0xb46d, 0xb46e, 0xb46f, 0xb470, 0xb471,
+ 0xb472, 0xb473, 0xb474, 0xb475, 0xb476, 0xb477, 0xb478, 0xb479,
+ 0xb47a, 0xb47b, 0xb47c, 0xb47d, 0xb47e, 0xb480, 0xb481, 0xb482,
+ 0xb483, 0xb484, 0xb485, 0xb486, 0xb487, 0xb488, 0xb489, 0xb48a,
+ 0xb48b, 0xb48c, 0xb48d, 0xb48e, 0xb48f, 0xb490, 0xb491, 0xb492,
+ 0xb493, 0xb494, 0xb495, 0xb496, 0xb497, 0xb498, 0xb499, 0xb49a,
+ 0xb49b, 0xb49c, 0xb49d, 0xb49e, 0xb49f, 0xb4a0, 0xb540, 0xb541,
+ 0xb542, 0xb543, 0xb544, 0xb545, 0xb546, 0xb547, 0xb548, 0xb549,
+ 0xb54a, 0xb54b, 0xb54c, 0xb54d, 0xb54e, 0xb54f, 0xb550, 0xb551,
+ 0xb552, 0xb553, 0xb554, 0xb555, 0xb556, 0xb557, 0xb558, 0xb559,
+ 0xb55a, 0xb55b, 0xb55c, 0xb55d, 0xb55e, 0xb55f, 0xb560, 0xb561,
+ 0xb562, 0xb563, 0xb564, 0xb565, 0xb566, 0xb567, 0xb568, 0xb569,
+ 0xb56a, 0xb56b, 0xb56c, 0xb56d, 0xb56e, 0xb56f, 0xb570, 0xb571,
+ 0xb572, 0xb573, 0xb574, 0xb575, 0xb576, 0xb577, 0xb578, 0xb579,
+ 0xb57a, 0xb57b, 0xb57c, 0xb57d, 0xb57e, 0xb580, 0xb581, 0xb582,
+ 0xb583, 0xb584, 0xb585, 0xb586, 0xb587, 0xb588, 0xb589, 0xb58a,
+ 0xb58b, 0xb58c, 0xb58d, 0xb58e, 0xb58f, 0xb590, 0xb591, 0xb592,
+ 0xb593, 0xb594, 0xb595, 0xb596, 0xb597, 0xb598, 0xb599, 0xb59a,
+ 0xb59b, 0xb59c, 0xb59d, 0xb59e, 0xb59f, 0xb5a0, 0xb640, 0xb641,
+ 0xb642, 0xb643, 0xb644, 0xb645, 0xb646, 0xb647, 0xb648, 0xb649,
+ 0xb64a, 0xb64b, 0xb64c, 0xb64d, 0xb64e, 0xb64f, 0xb650, 0xb651,
+ 0xb652, 0xb653, 0xb654, 0xb655, 0xb656, 0xb657, 0xb658, 0xb659,
+ 0xb65a, 0xb65b, 0xb65c, 0xb65d, 0xb65e, 0xb65f, 0xb660, 0xb661,
+ 0xb662, 0xb663, 0xb664, 0xb665, 0xb666, 0xb667, 0xb668, 0xb669,
+ 0xb66a, 0xb66b, 0xb66c, 0xb66d, 0xb66e, 0xb66f, 0xb670, 0xb671,
+ 0xb672, 0xb673, 0xb674, 0xb675, 0xb676, 0xb677, 0xb678, 0xb679,
+ 0xb67a, 0xb67b, 0xb67c, 0xb67d, 0xb67e, 0xb680, 0xb681, 0xb682,
+ 0xb683, 0xb684, 0xb685, 0xb686, 0xb687, 0xb688, 0xb689, 0xb68a,
+ 0xb68b, 0xb68c, 0xb68d, 0xb68e, 0xb68f, 0xb690, 0xb691, 0xb692,
+ 0xb693, 0xb694, 0xb695, 0xb696, 0xb697, 0xb698, 0xb699, 0xb69a,
+ 0xb69b, 0xb69c, 0xb69d, 0xb69e, 0xb69f, 0xb6a0, 0xb740, 0xb741,
+ 0xb742, 0xb743, 0xb744, 0xb745, 0xb746, 0xb747, 0xb748, 0xb749,
+ 0xb74a, 0xb74b, 0xb74c, 0xb74d, 0xb74e, 0xb74f, 0xb750, 0xb751,
+ 0xb752, 0xb753, 0xb754, 0xb755, 0xb756, 0xb757, 0xb758, 0xb759,
+ 0xb75a, 0xb75b, 0xb75c, 0xb75d, 0xb75e, 0xb75f, 0xb760, 0xb761,
+ 0xb762, 0xb763, 0xb764, 0xb765, 0xb766, 0xb767, 0xb768, 0xb769,
+ 0xb76a, 0xb76b, 0xb76c, 0xb76d, 0xb76e, 0xb76f, 0xb770, 0xb771,
+ 0xb772, 0xb773, 0xb774, 0xb775, 0xb776, 0xb777, 0xb778, 0xb779,
+ 0xb77a, 0xb77b, 0xb77c, 0xb77d, 0xb77e, 0xb780, 0xb781, 0xb782,
+ 0xb783, 0xb784, 0xb785, 0xb786, 0xb787, 0xb788, 0xb789, 0xb78a,
+ 0xb78b, 0xb78c, 0xb78d, 0xb78e, 0xb78f, 0xb790, 0xb791, 0xb792,
+ 0xb793, 0xb794, 0xb795, 0xb796, 0xb797, 0xb798, 0xb799, 0xb79a,
+ 0xb79b, 0xb79c, 0xb79d, 0xb79e, 0xb79f, 0xb7a0, 0xb840, 0xb841,
+ 0xb842, 0xb843, 0xb844, 0xb845, 0xb846, 0xb847, 0xb848, 0xb849,
+ 0xb84a, 0xb84b, 0xb84c, 0xb84d, 0xb84e, 0xb84f, 0xb850, 0xb851,
+ 0xb852, 0xb853, 0xb854, 0xb855, 0xb856, 0xb857, 0xb858, 0xb859,
+ 0xb85a, 0xb85b, 0xb85c, 0xb85d, 0xb85e, 0xb85f, 0xb860, 0xb861,
+ 0xb862, 0xb863, 0xb864, 0xb865, 0xb866, 0xb867, 0xb868, 0xb869,
+ 0xb86a, 0xb86b, 0xb86c, 0xb86d, 0xb86e, 0xb86f, 0xb870, 0xb871,
+ 0xb872, 0xb873, 0xb874, 0xb875, 0xb876, 0xb877, 0xb878, 0xb879,
+ 0xb87a, 0xb87b, 0xb87c, 0xb87d, 0xb87e, 0xb880, 0xb881, 0xb882,
+ 0xb883, 0xb884, 0xb885, 0xb886, 0xb887, 0xb888, 0xb889, 0xb88a,
+ 0xb88b, 0xb88c, 0xb88d, 0xb88e, 0xb88f, 0xb890, 0xb891, 0xb892,
+ 0xb893, 0xb894, 0xb895, 0xb896, 0xb897, 0xb898, 0xb899, 0xb89a,
+ 0xb89b, 0xb89c, 0xb89d, 0xb89e, 0xb89f, 0xb8a0, 0xb940, 0xb941,
+ 0xb942, 0xb943, 0xb944, 0xb945, 0xb946, 0xb947, 0xb948, 0xb949,
+ 0xb94a, 0xb94b, 0xb94c, 0xb94d, 0xb94e, 0xb94f, 0xb950, 0xb951,
+ 0xb952, 0xb953, 0xb954, 0xb955, 0xb956, 0xb957, 0xb958, 0xb959,
+ 0xb95a, 0xb95b, 0xb95c, 0xb95d, 0xb95e, 0xb95f, 0xb960, 0xb961,
+ 0xb962, 0xb963, 0xb964, 0xb965, 0xb966, 0xb967, 0xb968, 0xb969,
+ 0xb96a, 0xb96b, 0xb96c, 0xb96d, 0xb96e, 0xb96f, 0xb970, 0xb971,
+ 0xb972, 0xb973, 0xb974, 0xb975, 0xb976, 0xb977, 0xb978, 0xb979,
+ 0xb97a, 0xb97b, 0xb97c, 0xb97d, 0xb97e, 0xb980, 0xb981, 0xb982,
+ 0xb983, 0xb984, 0xb985, 0xb986, 0xb987, 0xb988, 0xb989, 0xb98a,
+ 0xb98b, 0xb98c, 0xb98d, 0xb98e, 0xb98f, 0xb990, 0xb991, 0xb992,
+ 0xb993, 0xb994, 0xb995, 0xb996, 0xb997, 0xb998, 0xb999, 0xb99a,
+ 0xb99b, 0xb99c, 0xb99d, 0xb99e, 0xb99f, 0xb9a0, 0xba40, 0xba41,
+ 0xba42, 0xba43, 0xba44, 0xba45, 0xba46, 0xba47, 0xba48, 0xba49,
+ 0xba4a, 0xba4b, 0xba4c, 0xba4d, 0xba4e, 0xba4f, 0xba50, 0xba51,
+ 0xba52, 0xba53, 0xba54, 0xba55, 0xba56, 0xba57, 0xba58, 0xba59,
+ 0xba5a, 0xba5b, 0xba5c, 0xba5d, 0xba5e, 0xba5f, 0xba60, 0xba61,
+ 0xba62, 0xba63, 0xba64, 0xba65, 0xba66, 0xba67, 0xba68, 0xba69,
+ 0xba6a, 0xba6b, 0xba6c, 0xba6d, 0xba6e, 0xba6f, 0xba70, 0xba71,
+ 0xba72, 0xba73, 0xba74, 0xba75, 0xba76, 0xba77, 0xba78, 0xba79,
+ 0xba7a, 0xba7b, 0xba7c, 0xba7d, 0xba7e, 0xba80, 0xba81, 0xba82,
+ 0xba83, 0xba84, 0xba85, 0xba86, 0xba87, 0xba88, 0xba89, 0xba8a,
+ 0xba8b, 0xba8c, 0xba8d, 0xba8e, 0xba8f, 0xba90, 0xba91, 0xba92,
+ 0xba93, 0xba94, 0xba95, 0xba96, 0xba97, 0xba98, 0xba99, 0xba9a,
+ 0xba9b, 0xba9c, 0xba9d, 0xba9e, 0xba9f, 0xbaa0, 0xbb40, 0xbb41,
+ 0xbb42, 0xbb43, 0xbb44, 0xbb45, 0xbb46, 0xbb47, 0xbb48, 0xbb49,
+ 0xbb4a, 0xbb4b, 0xbb4c, 0xbb4d, 0xbb4e, 0xbb4f, 0xbb50, 0xbb51,
+ 0xbb52, 0xbb53, 0xbb54, 0xbb55, 0xbb56, 0xbb57, 0xbb58, 0xbb59,
+ 0xbb5a, 0xbb5b, 0xbb5c, 0xbb5d, 0xbb5e, 0xbb5f, 0xbb60, 0xbb61,
+ 0xbb62, 0xbb63, 0xbb64, 0xbb65, 0xbb66, 0xbb67, 0xbb68, 0xbb69,
+ 0xbb6a, 0xbb6b, 0xbb6c, 0xbb6d, 0xbb6e, 0xbb6f, 0xbb70, 0xbb71,
+ 0xbb72, 0xbb73, 0xbb74, 0xbb75, 0xbb76, 0xbb77, 0xbb78, 0xbb79,
+ 0xbb7a, 0xbb7b, 0xbb7c, 0xbb7d, 0xbb7e, 0xbb80, 0xbb81, 0xbb82,
+ 0xbb83, 0xbb84, 0xbb85, 0xbb86, 0xbb87, 0xbb88, 0xbb89, 0xbb8a,
+ 0xbb8b, 0xbb8c, 0xbb8d, 0xbb8e, 0xbb8f, 0xbb90, 0xbb91, 0xbb92,
+ 0xbb93, 0xbb94, 0xbb95, 0xbb96, 0xbb97, 0xbb98, 0xbb99, 0xbb9a,
+ 0xbb9b, 0xbb9c, 0xbb9d, 0xbb9e, 0xbb9f, 0xbba0, 0xbc40, 0xbc41,
+ 0xbc42, 0xbc43, 0xbc44, 0xbc45, 0xbc46, 0xbc47, 0xbc48, 0xbc49,
+ 0xbc4a, 0xbc4b, 0xbc4c, 0xbc4d, 0xbc4e, 0xbc4f, 0xbc50, 0xbc51,
+ 0xbc52, 0xbc53, 0xbc54, 0xbc55, 0xbc56, 0xbc57, 0xbc58, 0xbc59,
+ 0xbc5a, 0xbc5b, 0xbc5c, 0xbc5d, 0xbc5e, 0xbc5f, 0xbc60, 0xbc61,
+ 0xbc62, 0xbc63, 0xbc64, 0xbc65, 0xbc66, 0xbc67, 0xbc68, 0xbc69,
+ 0xbc6a, 0xbc6b, 0xbc6c, 0xbc6d, 0xbc6e, 0xbc6f, 0xbc70, 0xbc71,
+ 0xbc72, 0xbc73, 0xbc74, 0xbc75, 0xbc76, 0xbc77, 0xbc78, 0xbc79,
+ 0xbc7a, 0xbc7b, 0xbc7c, 0xbc7d, 0xbc7e, 0xbc80, 0xbc81, 0xbc82,
+ 0xbc83, 0xbc84, 0xbc85, 0xbc86, 0xbc87, 0xbc88, 0xbc89, 0xbc8a,
+ 0xbc8b, 0xbc8c, 0xbc8d, 0xbc8e, 0xbc8f, 0xbc90, 0xbc91, 0xbc92,
+ 0xbc93, 0xbc94, 0xbc95, 0xbc96, 0xbc97, 0xbc98, 0xbc99, 0xbc9a,
+ 0xbc9b, 0xbc9c, 0xbc9d, 0xbc9e, 0xbc9f, 0xbca0, 0xbd40, 0xbd41,
+ 0xbd42, 0xbd43, 0xbd44, 0xbd45, 0xbd46, 0xbd47, 0xbd48, 0xbd49,
+ 0xbd4a, 0xbd4b, 0xbd4c, 0xbd4d, 0xbd4e, 0xbd4f, 0xbd50, 0xbd51,
+ 0xbd52, 0xbd53, 0xbd54, 0xbd55, 0xbd56, 0xbd57, 0xbd58, 0xbd59,
+ 0xbd5a, 0xbd5b, 0xbd5c, 0xbd5d, 0xbd5e, 0xbd5f, 0xbd60, 0xbd61,
+ 0xbd62, 0xbd63, 0xbd64, 0xbd65, 0xbd66, 0xbd67, 0xbd68, 0xbd69,
+ 0xbd6a, 0xbd6b, 0xbd6c, 0xbd6d, 0xbd6e, 0xbd6f, 0xbd70, 0xbd71,
+ 0xbd72, 0xbd73, 0xbd74, 0xbd75, 0xbd76, 0xbd77, 0xbd78, 0xbd79,
+ 0xbd7a, 0xbd7b, 0xbd7c, 0xbd7d, 0xbd7e, 0xbd80, 0xbd81, 0xbd82,
+ 0xbd83, 0xbd84, 0xbd85, 0xbd86, 0xbd87, 0xbd88, 0xbd89, 0xbd8a,
+ 0xbd8b, 0xbd8c, 0xbd8d, 0xbd8e, 0xbd8f, 0xbd90, 0xbd91, 0xbd92,
+ 0xbd93, 0xbd94, 0xbd95, 0xbd96, 0xbd97, 0xbd98, 0xbd99, 0xbd9a,
+ 0xbd9b, 0xbd9c, 0xbd9d, 0xbd9e, 0xbd9f, 0xbda0, 0xbe40, 0xbe41,
+ 0xbe42, 0xbe43, 0xbe44, 0xbe45, 0xbe46, 0xbe47, 0xbe48, 0xbe49,
+ 0xbe4a, 0xbe4b, 0xbe4c, 0xbe4d, 0xbe4e, 0xbe4f, 0xbe50, 0xbe51,
+ 0xbe52, 0xbe53, 0xbe54, 0xbe55, 0xbe56, 0xbe57, 0xbe58, 0xbe59,
+ 0xbe5a, 0xbe5b, 0xbe5c, 0xbe5d, 0xbe5e, 0xbe5f, 0xbe60, 0xbe61,
+ 0xbe62, 0xbe63, 0xbe64, 0xbe65, 0xbe66, 0xbe67, 0xbe68, 0xbe69,
+ 0xbe6a, 0xbe6b, 0xbe6c, 0xbe6d, 0xbe6e, 0xbe6f, 0xbe70, 0xbe71,
+ 0xbe72, 0xbe73, 0xbe74, 0xbe75, 0xbe76, 0xbe77, 0xbe78, 0xbe79,
+ 0xbe7a, 0xbe7b, 0xbe7c, 0xbe7d, 0xbe7e, 0xbe80, 0xbe81, 0xbe82,
+ 0xbe83, 0xbe84, 0xbe85, 0xbe86, 0xbe87, 0xbe88, 0xbe89, 0xbe8a,
+ 0xbe8b, 0xbe8c, 0xbe8d, 0xbe8e, 0xbe8f, 0xbe90, 0xbe91, 0xbe92,
+ 0xbe93, 0xbe94, 0xbe95, 0xbe96, 0xbe97, 0xbe98, 0xbe99, 0xbe9a,
+ 0xbe9b, 0xbe9c, 0xbe9d, 0xbe9e, 0xbe9f, 0xbea0, 0xbf40, 0xbf41,
+ 0xbf42, 0xbf43, 0xbf44, 0xbf45, 0xbf46, 0xbf47, 0xbf48, 0xbf49,
+ 0xbf4a, 0xbf4b, 0xbf4c, 0xbf4d, 0xbf4e, 0xbf4f, 0xbf50, 0xbf51,
+ 0xbf52, 0xbf53, 0xbf54, 0xbf55, 0xbf56, 0xbf57, 0xbf58, 0xbf59,
+ 0xbf5a, 0xbf5b, 0xbf5c, 0xbf5d, 0xbf5e, 0xbf5f, 0xbf60, 0xbf61,
+ 0xbf62, 0xbf63, 0xbf64, 0xbf65, 0xbf66, 0xbf67, 0xbf68, 0xbf69,
+ 0xbf6a, 0xbf6b, 0xbf6c, 0xbf6d, 0xbf6e, 0xbf6f, 0xbf70, 0xbf71,
+ 0xbf72, 0xbf73, 0xbf74, 0xbf75, 0xbf76, 0xbf77, 0xbf78, 0xbf79,
+ 0xbf7a, 0xbf7b, 0xbf7c, 0xbf7d, 0xbf7e, 0xbf80, 0xbf81, 0xbf82,
+ 0xbf83, 0xbf84, 0xbf85, 0xbf86, 0xbf87, 0xbf88, 0xbf89, 0xbf8a,
+ 0xbf8b, 0xbf8c, 0xbf8d, 0xbf8e, 0xbf8f, 0xbf90, 0xbf91, 0xbf92,
+ 0xbf93, 0xbf94, 0xbf95, 0xbf96, 0xbf97, 0xbf98, 0xbf99, 0xbf9a,
+ 0xbf9b, 0xbf9c, 0xbf9d, 0xbf9e, 0xbf9f, 0xbfa0, 0xc040, 0xc041,
+ 0xc042, 0xc043, 0xc044, 0xc045, 0xc046, 0xc047, 0xc048, 0xc049,
+ 0xc04a, 0xc04b, 0xc04c, 0xc04d, 0xc04e, 0xc04f, 0xc050, 0xc051,
+ 0xc052, 0xc053, 0xc054, 0xc055, 0xc056, 0xc057, 0xc058, 0xc059,
+ 0xc05a, 0xc05b, 0xc05c, 0xc05d, 0xc05e, 0xc05f, 0xc060, 0xc061,
+ 0xc062, 0xc063, 0xc064, 0xc065, 0xc066, 0xc067, 0xc068, 0xc069,
+ 0xc06a, 0xc06b, 0xc06c, 0xc06d, 0xc06e, 0xc06f, 0xc070, 0xc071,
+ 0xc072, 0xc073, 0xc074, 0xc075, 0xc076, 0xc077, 0xc078, 0xc079,
+ 0xc07a, 0xc07b, 0xc07c, 0xc07d, 0xc07e, 0xc080, 0xc081, 0xc082,
+ 0xc083, 0xc084, 0xc085, 0xc086, 0xc087, 0xc088, 0xc089, 0xc08a,
+ 0xc08b, 0xc08c, 0xc08d, 0xc08e, 0xc08f, 0xc090, 0xc091, 0xc092,
+ 0xc093, 0xc094, 0xc095, 0xc096, 0xc097, 0xc098, 0xc099, 0xc09a,
+ 0xc09b, 0xc09c, 0xc09d, 0xc09e, 0xc09f, 0xc0a0, 0xc140, 0xc141,
+ 0xc142, 0xc143, 0xc144, 0xc145, 0xc146, 0xc147, 0xc148, 0xc149,
+ 0xc14a, 0xc14b, 0xc14c, 0xc14d, 0xc14e, 0xc14f, 0xc150, 0xc151,
+ 0xc152, 0xc153, 0xc154, 0xc155, 0xc156, 0xc157, 0xc158, 0xc159,
+ 0xc15a, 0xc15b, 0xc15c, 0xc15d, 0xc15e, 0xc15f, 0xc160, 0xc161,
+ 0xc162, 0xc163, 0xc164, 0xc165, 0xc166, 0xc167, 0xc168, 0xc169,
+ 0xc16a, 0xc16b, 0xc16c, 0xc16d, 0xc16e, 0xc16f, 0xc170, 0xc171,
+ 0xc172, 0xc173, 0xc174, 0xc175, 0xc176, 0xc177, 0xc178, 0xc179,
+ 0xc17a, 0xc17b, 0xc17c, 0xc17d, 0xc17e, 0xc180, 0xc181, 0xc182,
+ 0xc183, 0xc184, 0xc185, 0xc186, 0xc187, 0xc188, 0xc189, 0xc18a,
+ 0xc18b, 0xc18c, 0xc18d, 0xc18e, 0xc18f, 0xc190, 0xc191, 0xc192,
+ 0xc193, 0xc194, 0xc195, 0xc196, 0xc197, 0xc198, 0xc199, 0xc19a,
+ 0xc19b, 0xc19c, 0xc19d, 0xc19e, 0xc19f, 0xc1a0, 0xc240, 0xc241,
+ 0xc242, 0xc243, 0xc244, 0xc245, 0xc246, 0xc247, 0xc248, 0xc249,
+ 0xc24a, 0xc24b, 0xc24c, 0xc24d, 0xc24e, 0xc24f, 0xc250, 0xc251,
+ 0xc252, 0xc253, 0xc254, 0xc255, 0xc256, 0xc257, 0xc258, 0xc259,
+ 0xc25a, 0xc25b, 0xc25c, 0xc25d, 0xc25e, 0xc25f, 0xc260, 0xc261,
+ 0xc262, 0xc263, 0xc264, 0xc265, 0xc266, 0xc267, 0xc268, 0xc269,
+ 0xc26a, 0xc26b, 0xc26c, 0xc26d, 0xc26e, 0xc26f, 0xc270, 0xc271,
+ 0xc272, 0xc273, 0xc274, 0xc275, 0xc276, 0xc277, 0xc278, 0xc279,
+ 0xc27a, 0xc27b, 0xc27c, 0xc27d, 0xc27e, 0xc280, 0xc281, 0xc282,
+ 0xc283, 0xc284, 0xc285, 0xc286, 0xc287, 0xc288, 0xc289, 0xc28a,
+ 0xc28b, 0xc28c, 0xc28d, 0xc28e, 0xc28f, 0xc290, 0xc291, 0xc292,
+ 0xc293, 0xc294, 0xc295, 0xc296, 0xc297, 0xc298, 0xc299, 0xc29a,
+ 0xc29b, 0xc29c, 0xc29d, 0xc29e, 0xc29f, 0xc2a0, 0xc340, 0xc341,
+ 0xc342, 0xc343, 0xc344, 0xc345, 0xc346, 0xc347, 0xc348, 0xc349,
+ 0xc34a, 0xc34b, 0xc34c, 0xc34d, 0xc34e, 0xc34f, 0xc350, 0xc351,
+ 0xc352, 0xc353, 0xc354, 0xc355, 0xc356, 0xc357, 0xc358, 0xc359,
+ 0xc35a, 0xc35b, 0xc35c, 0xc35d, 0xc35e, 0xc35f, 0xc360, 0xc361,
+ 0xc362, 0xc363, 0xc364, 0xc365, 0xc366, 0xc367, 0xc368, 0xc369,
+ 0xc36a, 0xc36b, 0xc36c, 0xc36d, 0xc36e, 0xc36f, 0xc370, 0xc371,
+ 0xc372, 0xc373, 0xc374, 0xc375, 0xc376, 0xc377, 0xc378, 0xc379,
+ 0xc37a, 0xc37b, 0xc37c, 0xc37d, 0xc37e, 0xc380, 0xc381, 0xc382,
+ 0xc383, 0xc384, 0xc385, 0xc386, 0xc387, 0xc388, 0xc389, 0xc38a,
+ 0xc38b, 0xc38c, 0xc38d, 0xc38e, 0xc38f, 0xc390, 0xc391, 0xc392,
+ 0xc393, 0xc394, 0xc395, 0xc396, 0xc397, 0xc398, 0xc399, 0xc39a,
+ 0xc39b, 0xc39c, 0xc39d, 0xc39e, 0xc39f, 0xc3a0, 0xc440, 0xc441,
+ 0xc442, 0xc443, 0xc444, 0xc445, 0xc446, 0xc447, 0xc448, 0xc449,
+ 0xc44a, 0xc44b, 0xc44c, 0xc44d, 0xc44e, 0xc44f, 0xc450, 0xc451,
+ 0xc452, 0xc453, 0xc454, 0xc455, 0xc456, 0xc457, 0xc458, 0xc459,
+ 0xc45a, 0xc45b, 0xc45c, 0xc45d, 0xc45e, 0xc45f, 0xc460, 0xc461,
+ 0xc462, 0xc463, 0xc464, 0xc465, 0xc466, 0xc467, 0xc468, 0xc469,
+ 0xc46a, 0xc46b, 0xc46c, 0xc46d, 0xc46e, 0xc46f, 0xc470, 0xc471,
+ 0xc472, 0xc473, 0xc474, 0xc475, 0xc476, 0xc477, 0xc478, 0xc479,
+ 0xc47a, 0xc47b, 0xc47c, 0xc47d, 0xc47e, 0xc480, 0xc481, 0xc482,
+ 0xc483, 0xc484, 0xc485, 0xc486, 0xc487, 0xc488, 0xc489, 0xc48a,
+ 0xc48b, 0xc48c, 0xc48d, 0xc48e, 0xc48f, 0xc490, 0xc491, 0xc492,
+ 0xc493, 0xc494, 0xc495, 0xc496, 0xc497, 0xc498, 0xc499, 0xc49a,
+ 0xc49b, 0xc49c, 0xc49d, 0xc49e, 0xc49f, 0xc4a0, 0xc540, 0xc541,
+ 0xc542, 0xc543, 0xc544, 0xc545, 0xc546, 0xc547, 0xc548, 0xc549,
+ 0xc54a, 0xc54b, 0xc54c, 0xc54d, 0xc54e, 0xc54f, 0xc550, 0xc551,
+ 0xc552, 0xc553, 0xc554, 0xc555, 0xc556, 0xc557, 0xc558, 0xc559,
+ 0xc55a, 0xc55b, 0xc55c, 0xc55d, 0xc55e, 0xc55f, 0xc560, 0xc561,
+ 0xc562, 0xc563, 0xc564, 0xc565, 0xc566, 0xc567, 0xc568, 0xc569,
+ 0xc56a, 0xc56b, 0xc56c, 0xc56d, 0xc56e, 0xc56f, 0xc570, 0xc571,
+ 0xc572, 0xc573, 0xc574, 0xc575, 0xc576, 0xc577, 0xc578, 0xc579,
+ 0xc57a, 0xc57b, 0xc57c, 0xc57d, 0xc57e, 0xc580, 0xc581, 0xc582,
+ 0xc583, 0xc584, 0xc585, 0xc586, 0xc587, 0xc588, 0xc589, 0xc58a,
+ 0xc58b, 0xc58c, 0xc58d, 0xc58e, 0xc58f, 0xc590, 0xc591, 0xc592,
+ 0xc593, 0xc594, 0xc595, 0xc596, 0xc597, 0xc598, 0xc599, 0xc59a,
+ 0xc59b, 0xc59c, 0xc59d, 0xc59e, 0xc59f, 0xc5a0, 0xc640, 0xc641,
+ 0xc642, 0xc643, 0xc644, 0xc645, 0xc646, 0xc647, 0xc648, 0xc649,
+ 0xc64a, 0xc64b, 0xc64c, 0xc64d, 0xc64e, 0xc64f, 0xc650, 0xc651,
+ 0xc652, 0xc653, 0xc654, 0xc655, 0xc656, 0xc657, 0xc658, 0xc659,
+ 0xc65a, 0xc65b, 0xc65c, 0xc65d, 0xc65e, 0xc65f, 0xc660, 0xc661,
+ 0xc662, 0xc663, 0xc664, 0xc665, 0xc666, 0xc667, 0xc668, 0xc669,
+ 0xc66a, 0xc66b, 0xc66c, 0xc66d, 0xc66e, 0xc66f, 0xc670, 0xc671,
+ 0xc672, 0xc673, 0xc674, 0xc675, 0xc676, 0xc677, 0xc678, 0xc679,
+ 0xc67a, 0xc67b, 0xc67c, 0xc67d, 0xc67e, 0xc680, 0xc681, 0xc682,
+ 0xc683, 0xc684, 0xc685, 0xc686, 0xc687, 0xc688, 0xc689, 0xc68a,
+ 0xc68b, 0xc68c, 0xc68d, 0xc68e, 0xc68f, 0xc690, 0xc691, 0xc692,
+ 0xc693, 0xc694, 0xc695, 0xc696, 0xc697, 0xc698, 0xc699, 0xc69a,
+ 0xc69b, 0xc69c, 0xc69d, 0xc69e, 0xc69f, 0xc6a0, 0xc740, 0xc741,
+ 0xc742, 0xc743, 0xc744, 0xc745, 0xc746, 0xc747, 0xc748, 0xc749,
+ 0xc74a, 0xc74b, 0xc74c, 0xc74d, 0xc74e, 0xc74f, 0xc750, 0xc751,
+ 0xc752, 0xc753, 0xc754, 0xc755, 0xc756, 0xc757, 0xc758, 0xc759,
+ 0xc75a, 0xc75b, 0xc75c, 0xc75d, 0xc75e, 0xc75f, 0xc760, 0xc761,
+ 0xc762, 0xc763, 0xc764, 0xc765, 0xc766, 0xc767, 0xc768, 0xc769,
+ 0xc76a, 0xc76b, 0xc76c, 0xc76d, 0xc76e, 0xc76f, 0xc770, 0xc771,
+ 0xc772, 0xc773, 0xc774, 0xc775, 0xc776, 0xc777, 0xc778, 0xc779,
+ 0xc77a, 0xc77b, 0xc77c, 0xc77d, 0xc77e, 0xc780, 0xc781, 0xc782,
+ 0xc783, 0xc784, 0xc785, 0xc786, 0xc787, 0xc788, 0xc789, 0xc78a,
+ 0xc78b, 0xc78c, 0xc78d, 0xc78e, 0xc78f, 0xc790, 0xc791, 0xc792,
+ 0xc793, 0xc794, 0xc795, 0xc796, 0xc797, 0xc798, 0xc799, 0xc79a,
+ 0xc79b, 0xc79c, 0xc79d, 0xc79e, 0xc79f, 0xc7a0, 0xc840, 0xc841,
+ 0xc842, 0xc843, 0xc844, 0xc845, 0xc846, 0xc847, 0xc848, 0xc849,
+ 0xc84a, 0xc84b, 0xc84c, 0xc84d, 0xc84e, 0xc84f, 0xc850, 0xc851,
+ 0xc852, 0xc853, 0xc854, 0xc855, 0xc856, 0xc857, 0xc858, 0xc859,
+ 0xc85a, 0xc85b, 0xc85c, 0xc85d, 0xc85e, 0xc85f, 0xc860, 0xc861,
+ 0xc862, 0xc863, 0xc864, 0xc865, 0xc866, 0xc867, 0xc868, 0xc869,
+ 0xc86a, 0xc86b, 0xc86c, 0xc86d, 0xc86e, 0xc86f, 0xc870, 0xc871,
+ 0xc872, 0xc873, 0xc874, 0xc875, 0xc876, 0xc877, 0xc878, 0xc879,
+ 0xc87a, 0xc87b, 0xc87c, 0xc87d, 0xc87e, 0xc880, 0xc881, 0xc882,
+ 0xc883, 0xc884, 0xc885, 0xc886, 0xc887, 0xc888, 0xc889, 0xc88a,
+ 0xc88b, 0xc88c, 0xc88d, 0xc88e, 0xc88f, 0xc890, 0xc891, 0xc892,
+ 0xc893, 0xc894, 0xc895, 0xc896, 0xc897, 0xc898, 0xc899, 0xc89a,
+ 0xc89b, 0xc89c, 0xc89d, 0xc89e, 0xc89f, 0xc8a0, 0xc940, 0xc941,
+ 0xc942, 0xc943, 0xc944, 0xc945, 0xc946, 0xc947, 0xc948, 0xc949,
+ 0xc94a, 0xc94b, 0xc94c, 0xc94d, 0xc94e, 0xc94f, 0xc950, 0xc951,
+ 0xc952, 0xc953, 0xc954, 0xc955, 0xc956, 0xc957, 0xc958, 0xc959,
+ 0xc95a, 0xc95b, 0xc95c, 0xc95d, 0xc95e, 0xc95f, 0xc960, 0xc961,
+ 0xc962, 0xc963, 0xc964, 0xc965, 0xc966, 0xc967, 0xc968, 0xc969,
+ 0xc96a, 0xc96b, 0xc96c, 0xc96d, 0xc96e, 0xc96f, 0xc970, 0xc971,
+ 0xc972, 0xc973, 0xc974, 0xc975, 0xc976, 0xc977, 0xc978, 0xc979,
+ 0xc97a, 0xc97b, 0xc97c, 0xc97d, 0xc97e, 0xc980, 0xc981, 0xc982,
+ 0xc983, 0xc984, 0xc985, 0xc986, 0xc987, 0xc988, 0xc989, 0xc98a,
+ 0xc98b, 0xc98c, 0xc98d, 0xc98e, 0xc98f, 0xc990, 0xc991, 0xc992,
+ 0xc993, 0xc994, 0xc995, 0xc996, 0xc997, 0xc998, 0xc999, 0xc99a,
+ 0xc99b, 0xc99c, 0xc99d, 0xc99e, 0xc99f, 0xc9a0, 0xca40, 0xca41,
+ 0xca42, 0xca43, 0xca44, 0xca45, 0xca46, 0xca47, 0xca48, 0xca49,
+ 0xca4a, 0xca4b, 0xca4c, 0xca4d, 0xca4e, 0xca4f, 0xca50, 0xca51,
+ 0xca52, 0xca53, 0xca54, 0xca55, 0xca56, 0xca57, 0xca58, 0xca59,
+ 0xca5a, 0xca5b, 0xca5c, 0xca5d, 0xca5e, 0xca5f, 0xca60, 0xca61,
+ 0xca62, 0xca63, 0xca64, 0xca65, 0xca66, 0xca67, 0xca68, 0xca69,
+ 0xca6a, 0xca6b, 0xca6c, 0xca6d, 0xca6e, 0xca6f, 0xca70, 0xca71,
+ 0xca72, 0xca73, 0xca74, 0xca75, 0xca76, 0xca77, 0xca78, 0xca79,
+ 0xca7a, 0xca7b, 0xca7c, 0xca7d, 0xca7e, 0xca80, 0xca81, 0xca82,
+ 0xca83, 0xca84, 0xca85, 0xca86, 0xca87, 0xca88, 0xca89, 0xca8a,
+ 0xca8b, 0xca8c, 0xca8d, 0xca8e, 0xca8f, 0xca90, 0xca91, 0xca92,
+ 0xca93, 0xca94, 0xca95, 0xca96, 0xca97, 0xca98, 0xca99, 0xca9a,
+ 0xca9b, 0xca9c, 0xca9d, 0xca9e, 0xca9f, 0xcaa0, 0xcb40, 0xcb41,
+ 0xcb42, 0xcb43, 0xcb44, 0xcb45, 0xcb46, 0xcb47, 0xcb48, 0xcb49,
+ 0xcb4a, 0xcb4b, 0xcb4c, 0xcb4d, 0xcb4e, 0xcb4f, 0xcb50, 0xcb51,
+ 0xcb52, 0xcb53, 0xcb54, 0xcb55, 0xcb56, 0xcb57, 0xcb58, 0xcb59,
+ 0xcb5a, 0xcb5b, 0xcb5c, 0xcb5d, 0xcb5e, 0xcb5f, 0xcb60, 0xcb61,
+ 0xcb62, 0xcb63, 0xcb64, 0xcb65, 0xcb66, 0xcb67, 0xcb68, 0xcb69,
+ 0xcb6a, 0xcb6b, 0xcb6c, 0xcb6d, 0xcb6e, 0xcb6f, 0xcb70, 0xcb71,
+ 0xcb72, 0xcb73, 0xcb74, 0xcb75, 0xcb76, 0xcb77, 0xcb78, 0xcb79,
+ 0xcb7a, 0xcb7b, 0xcb7c, 0xcb7d, 0xcb7e, 0xcb80, 0xcb81, 0xcb82,
+ 0xcb83, 0xcb84, 0xcb85, 0xcb86, 0xcb87, 0xcb88, 0xcb89, 0xcb8a,
+ 0xcb8b, 0xcb8c, 0xcb8d, 0xcb8e, 0xcb8f, 0xcb90, 0xcb91, 0xcb92,
+ 0xcb93, 0xcb94, 0xcb95, 0xcb96, 0xcb97, 0xcb98, 0xcb99, 0xcb9a,
+ 0xcb9b, 0xcb9c, 0xcb9d, 0xcb9e, 0xcb9f, 0xcba0, 0xcc40, 0xcc41,
+ 0xcc42, 0xcc43, 0xcc44, 0xcc45, 0xcc46, 0xcc47, 0xcc48, 0xcc49,
+ 0xcc4a, 0xcc4b, 0xcc4c, 0xcc4d, 0xcc4e, 0xcc4f, 0xcc50, 0xcc51,
+ 0xcc52, 0xcc53, 0xcc54, 0xcc55, 0xcc56, 0xcc57, 0xcc58, 0xcc59,
+ 0xcc5a, 0xcc5b, 0xcc5c, 0xcc5d, 0xcc5e, 0xcc5f, 0xcc60, 0xcc61,
+ 0xcc62, 0xcc63, 0xcc64, 0xcc65, 0xcc66, 0xcc67, 0xcc68, 0xcc69,
+ 0xcc6a, 0xcc6b, 0xcc6c, 0xcc6d, 0xcc6e, 0xcc6f, 0xcc70, 0xcc71,
+ 0xcc72, 0xcc73, 0xcc74, 0xcc75, 0xcc76, 0xcc77, 0xcc78, 0xcc79,
+ 0xcc7a, 0xcc7b, 0xcc7c, 0xcc7d, 0xcc7e, 0xcc80, 0xcc81, 0xcc82,
+ 0xcc83, 0xcc84, 0xcc85, 0xcc86, 0xcc87, 0xcc88, 0xcc89, 0xcc8a,
+ 0xcc8b, 0xcc8c, 0xcc8d, 0xcc8e, 0xcc8f, 0xcc90, 0xcc91, 0xcc92,
+ 0xcc93, 0xcc94, 0xcc95, 0xcc96, 0xcc97, 0xcc98, 0xcc99, 0xcc9a,
+ 0xcc9b, 0xcc9c, 0xcc9d, 0xcc9e, 0xcc9f, 0xcca0, 0xcd40, 0xcd41,
+ 0xcd42, 0xcd43, 0xcd44, 0xcd45, 0xcd46, 0xcd47, 0xcd48, 0xcd49,
+ 0xcd4a, 0xcd4b, 0xcd4c, 0xcd4d, 0xcd4e, 0xcd4f, 0xcd50, 0xcd51,
+ 0xcd52, 0xcd53, 0xcd54, 0xcd55, 0xcd56, 0xcd57, 0xcd58, 0xcd59,
+ 0xcd5a, 0xcd5b, 0xcd5c, 0xcd5d, 0xcd5e, 0xcd5f, 0xcd60, 0xcd61,
+ 0xcd62, 0xcd63, 0xcd64, 0xcd65, 0xcd66, 0xcd67, 0xcd68, 0xcd69,
+ 0xcd6a, 0xcd6b, 0xcd6c, 0xcd6d, 0xcd6e, 0xcd6f, 0xcd70, 0xcd71,
+ 0xcd72, 0xcd73, 0xcd74, 0xcd75, 0xcd76, 0xcd77, 0xcd78, 0xcd79,
+ 0xcd7a, 0xcd7b, 0xcd7c, 0xcd7d, 0xcd7e, 0xcd80, 0xcd81, 0xcd82,
+ 0xcd83, 0xcd84, 0xcd85, 0xcd86, 0xcd87, 0xcd88, 0xcd89, 0xcd8a,
+ 0xcd8b, 0xcd8c, 0xcd8d, 0xcd8e, 0xcd8f, 0xcd90, 0xcd91, 0xcd92,
+ 0xcd93, 0xcd94, 0xcd95, 0xcd96, 0xcd97, 0xcd98, 0xcd99, 0xcd9a,
+ 0xcd9b, 0xcd9c, 0xcd9d, 0xcd9e, 0xcd9f, 0xcda0, 0xce40, 0xce41,
+ 0xce42, 0xce43, 0xce44, 0xce45, 0xce46, 0xce47, 0xce48, 0xce49,
+ 0xce4a, 0xce4b, 0xce4c, 0xce4d, 0xce4e, 0xce4f, 0xce50, 0xce51,
+ 0xce52, 0xce53, 0xce54, 0xce55, 0xce56, 0xce57, 0xce58, 0xce59,
+ 0xce5a, 0xce5b, 0xce5c, 0xce5d, 0xce5e, 0xce5f, 0xce60, 0xce61,
+ 0xce62, 0xce63, 0xce64, 0xce65, 0xce66, 0xce67, 0xce68, 0xce69,
+ 0xce6a, 0xce6b, 0xce6c, 0xce6d, 0xce6e, 0xce6f, 0xce70, 0xce71,
+ 0xce72, 0xce73, 0xce74, 0xce75, 0xce76, 0xce77, 0xce78, 0xce79,
+ 0xce7a, 0xce7b, 0xce7c, 0xce7d, 0xce7e, 0xce80, 0xce81, 0xce82,
+ 0xce83, 0xce84, 0xce85, 0xce86, 0xce87, 0xce88, 0xce89, 0xce8a,
+ 0xce8b, 0xce8c, 0xce8d, 0xce8e, 0xce8f, 0xce90, 0xce91, 0xce92,
+ 0xce93, 0xce94, 0xce95, 0xce96, 0xce97, 0xce98, 0xce99, 0xce9a,
+ 0xce9b, 0xce9c, 0xce9d, 0xce9e, 0xce9f, 0xcea0, 0xcf40, 0xcf41,
+ 0xcf42, 0xcf43, 0xcf44, 0xcf45, 0xcf46, 0xcf47, 0xcf48, 0xcf49,
+ 0xcf4a, 0xcf4b, 0xcf4c, 0xcf4d, 0xcf4e, 0xcf4f, 0xcf50, 0xcf51,
+ 0xcf52, 0xcf53, 0xcf54, 0xcf55, 0xcf56, 0xcf57, 0xcf58, 0xcf59,
+ 0xcf5a, 0xcf5b, 0xcf5c, 0xcf5d, 0xcf5e, 0xcf5f, 0xcf60, 0xcf61,
+ 0xcf62, 0xcf63, 0xcf64, 0xcf65, 0xcf66, 0xcf67, 0xcf68, 0xcf69,
+ 0xcf6a, 0xcf6b, 0xcf6c, 0xcf6d, 0xcf6e, 0xcf6f, 0xcf70, 0xcf71,
+ 0xcf72, 0xcf73, 0xcf74, 0xcf75, 0xcf76, 0xcf77, 0xcf78, 0xcf79,
+ 0xcf7a, 0xcf7b, 0xcf7c, 0xcf7d, 0xcf7e, 0xcf80, 0xcf81, 0xcf82,
+ 0xcf83, 0xcf84, 0xcf85, 0xcf86, 0xcf87, 0xcf88, 0xcf89, 0xcf8a,
+ 0xcf8b, 0xcf8c, 0xcf8d, 0xcf8e, 0xcf8f, 0xcf90, 0xcf91, 0xcf92,
+ 0xcf93, 0xcf94, 0xcf95, 0xcf96, 0xcf97, 0xcf98, 0xcf99, 0xcf9a,
+ 0xcf9b, 0xcf9c, 0xcf9d, 0xcf9e, 0xcf9f, 0xcfa0, 0xd040, 0xd041,
+ 0xd042, 0xd043, 0xd044, 0xd045, 0xd046, 0xd047, 0xd048, 0xd049,
+ 0xd04a, 0xd04b, 0xd04c, 0xd04d, 0xd04e, 0xd04f, 0xd050, 0xd051,
+ 0xd052, 0xd053, 0xd054, 0xd055, 0xd056, 0xd057, 0xd058, 0xd059,
+ 0xd05a, 0xd05b, 0xd05c, 0xd05d, 0xd05e, 0xd05f, 0xd060, 0xd061,
+ 0xd062, 0xd063, 0xd064, 0xd065, 0xd066, 0xd067, 0xd068, 0xd069,
+ 0xd06a, 0xd06b, 0xd06c, 0xd06d, 0xd06e, 0xd06f, 0xd070, 0xd071,
+ 0xd072, 0xd073, 0xd074, 0xd075, 0xd076, 0xd077, 0xd078, 0xd079,
+ 0xd07a, 0xd07b, 0xd07c, 0xd07d, 0xd07e, 0xd080, 0xd081, 0xd082,
+ 0xd083, 0xd084, 0xd085, 0xd086, 0xd087, 0xd088, 0xd089, 0xd08a,
+ 0xd08b, 0xd08c, 0xd08d, 0xd08e, 0xd08f, 0xd090, 0xd091, 0xd092,
+ 0xd093, 0xd094, 0xd095, 0xd096, 0xd097, 0xd098, 0xd099, 0xd09a,
+ 0xd09b, 0xd09c, 0xd09d, 0xd09e, 0xd09f, 0xd0a0, 0xd140, 0xd141,
+ 0xd142, 0xd143, 0xd144, 0xd145, 0xd146, 0xd147, 0xd148, 0xd149,
+ 0xd14a, 0xd14b, 0xd14c, 0xd14d, 0xd14e, 0xd14f, 0xd150, 0xd151,
+ 0xd152, 0xd153, 0xd154, 0xd155, 0xd156, 0xd157, 0xd158, 0xd159,
+ 0xd15a, 0xd15b, 0xd15c, 0xd15d, 0xd15e, 0xd15f, 0xd160, 0xd161,
+ 0xd162, 0xd163, 0xd164, 0xd165, 0xd166, 0xd167, 0xd168, 0xd169,
+ 0xd16a, 0xd16b, 0xd16c, 0xd16d, 0xd16e, 0xd16f, 0xd170, 0xd171,
+ 0xd172, 0xd173, 0xd174, 0xd175, 0xd176, 0xd177, 0xd178, 0xd179,
+ 0xd17a, 0xd17b, 0xd17c, 0xd17d, 0xd17e, 0xd180, 0xd181, 0xd182,
+ 0xd183, 0xd184, 0xd185, 0xd186, 0xd187, 0xd188, 0xd189, 0xd18a,
+ 0xd18b, 0xd18c, 0xd18d, 0xd18e, 0xd18f, 0xd190, 0xd191, 0xd192,
+ 0xd193, 0xd194, 0xd195, 0xd196, 0xd197, 0xd198, 0xd199, 0xd19a,
+ 0xd19b, 0xd19c, 0xd19d, 0xd19e, 0xd19f, 0xd1a0, 0xd240, 0xd241,
+ 0xd242, 0xd243, 0xd244, 0xd245, 0xd246, 0xd247, 0xd248, 0xd249,
+ 0xd24a, 0xd24b, 0xd24c, 0xd24d, 0xd24e, 0xd24f, 0xd250, 0xd251,
+ 0xd252, 0xd253, 0xd254, 0xd255, 0xd256, 0xd257, 0xd258, 0xd259,
+ 0xd25a, 0xd25b, 0xd25c, 0xd25d, 0xd25e, 0xd25f, 0xd260, 0xd261,
+ 0xd262, 0xd263, 0xd264, 0xd265, 0xd266, 0xd267, 0xd268, 0xd269,
+ 0xd26a, 0xd26b, 0xd26c, 0xd26d, 0xd26e, 0xd26f, 0xd270, 0xd271,
+ 0xd272, 0xd273, 0xd274, 0xd275, 0xd276, 0xd277, 0xd278, 0xd279,
+ 0xd27a, 0xd27b, 0xd27c, 0xd27d, 0xd27e, 0xd280, 0xd281, 0xd282,
+ 0xd283, 0xd284, 0xd285, 0xd286, 0xd287, 0xd288, 0xd289, 0xd28a,
+ 0xd28b, 0xd28c, 0xd28d, 0xd28e, 0xd28f, 0xd290, 0xd291, 0xd292,
+ 0xd293, 0xd294, 0xd295, 0xd296, 0xd297, 0xd298, 0xd299, 0xd29a,
+ 0xd29b, 0xd29c, 0xd29d, 0xd29e, 0xd29f, 0xd2a0, 0xd340, 0xd341,
+ 0xd342, 0xd343, 0xd344, 0xd345, 0xd346, 0xd347, 0xd348, 0xd349,
+ 0xd34a, 0xd34b, 0xd34c, 0xd34d, 0xd34e, 0xd34f, 0xd350, 0xd351,
+ 0xd352, 0xd353, 0xd354, 0xd355, 0xd356, 0xd357, 0xd358, 0xd359,
+ 0xd35a, 0xd35b, 0xd35c, 0xd35d, 0xd35e, 0xd35f, 0xd360, 0xd361,
+ 0xd362, 0xd363, 0xd364, 0xd365, 0xd366, 0xd367, 0xd368, 0xd369,
+ 0xd36a, 0xd36b, 0xd36c, 0xd36d, 0xd36e, 0xd36f, 0xd370, 0xd371,
+ 0xd372, 0xd373, 0xd374, 0xd375, 0xd376, 0xd377, 0xd378, 0xd379,
+ 0xd37a, 0xd37b, 0xd37c, 0xd37d, 0xd37e, 0xd380, 0xd381, 0xd382,
+ 0xd383, 0xd384, 0xd385, 0xd386, 0xd387, 0xd388, 0xd389, 0xd38a,
+ 0xd38b, 0xd38c, 0xd38d, 0xd38e, 0xd38f, 0xd390, 0xd391, 0xd392,
+ 0xd393, 0xd394, 0xd395, 0xd396, 0xd397, 0xd398, 0xd399, 0xd39a,
+ 0xd39b, 0xd39c, 0xd39d, 0xd39e, 0xd39f, 0xd3a0, 0xd440, 0xd441,
+ 0xd442, 0xd443, 0xd444, 0xd445, 0xd446, 0xd447, 0xd448, 0xd449,
+ 0xd44a, 0xd44b, 0xd44c, 0xd44d, 0xd44e, 0xd44f, 0xd450, 0xd451,
+ 0xd452, 0xd453, 0xd454, 0xd455, 0xd456, 0xd457, 0xd458, 0xd459,
+ 0xd45a, 0xd45b, 0xd45c, 0xd45d, 0xd45e, 0xd45f, 0xd460, 0xd461,
+ 0xd462, 0xd463, 0xd464, 0xd465, 0xd466, 0xd467, 0xd468, 0xd469,
+ 0xd46a, 0xd46b, 0xd46c, 0xd46d, 0xd46e, 0xd46f, 0xd470, 0xd471,
+ 0xd472, 0xd473, 0xd474, 0xd475, 0xd476, 0xd477, 0xd478, 0xd479,
+ 0xd47a, 0xd47b, 0xd47c, 0xd47d, 0xd47e, 0xd480, 0xd481, 0xd482,
+ 0xd483, 0xd484, 0xd485, 0xd486, 0xd487, 0xd488, 0xd489, 0xd48a,
+ 0xd48b, 0xd48c, 0xd48d, 0xd48e, 0xd48f, 0xd490, 0xd491, 0xd492,
+ 0xd493, 0xd494, 0xd495, 0xd496, 0xd497, 0xd498, 0xd499, 0xd49a,
+ 0xd49b, 0xd49c, 0xd49d, 0xd49e, 0xd49f, 0xd4a0, 0xd540, 0xd541,
+ 0xd542, 0xd543, 0xd544, 0xd545, 0xd546, 0xd547, 0xd548, 0xd549,
+ 0xd54a, 0xd54b, 0xd54c, 0xd54d, 0xd54e, 0xd54f, 0xd550, 0xd551,
+ 0xd552, 0xd553, 0xd554, 0xd555, 0xd556, 0xd557, 0xd558, 0xd559,
+ 0xd55a, 0xd55b, 0xd55c, 0xd55d, 0xd55e, 0xd55f, 0xd560, 0xd561,
+ 0xd562, 0xd563, 0xd564, 0xd565, 0xd566, 0xd567, 0xd568, 0xd569,
+ 0xd56a, 0xd56b, 0xd56c, 0xd56d, 0xd56e, 0xd56f, 0xd570, 0xd571,
+ 0xd572, 0xd573, 0xd574, 0xd575, 0xd576, 0xd577, 0xd578, 0xd579,
+ 0xd57a, 0xd57b, 0xd57c, 0xd57d, 0xd57e, 0xd580, 0xd581, 0xd582,
+ 0xd583, 0xd584, 0xd585, 0xd586, 0xd587, 0xd588, 0xd589, 0xd58a,
+ 0xd58b, 0xd58c, 0xd58d, 0xd58e, 0xd58f, 0xd590, 0xd591, 0xd592,
+ 0xd593, 0xd594, 0xd595, 0xd596, 0xd597, 0xd598, 0xd599, 0xd59a,
+ 0xd59b, 0xd59c, 0xd59d, 0xd59e, 0xd59f, 0xd5a0, 0xd640, 0xd641,
+ 0xd642, 0xd643, 0xd644, 0xd645, 0xd646, 0xd647, 0xd648, 0xd649,
+ 0xd64a, 0xd64b, 0xd64c, 0xd64d, 0xd64e, 0xd64f, 0xd650, 0xd651,
+ 0xd652, 0xd653, 0xd654, 0xd655, 0xd656, 0xd657, 0xd658, 0xd659,
+ 0xd65a, 0xd65b, 0xd65c, 0xd65d, 0xd65e, 0xd65f, 0xd660, 0xd661,
+ 0xd662, 0xd663, 0xd664, 0xd665, 0xd666, 0xd667, 0xd668, 0xd669,
+ 0xd66a, 0xd66b, 0xd66c, 0xd66d, 0xd66e, 0xd66f, 0xd670, 0xd671,
+ 0xd672, 0xd673, 0xd674, 0xd675, 0xd676, 0xd677, 0xd678, 0xd679,
+ 0xd67a, 0xd67b, 0xd67c, 0xd67d, 0xd67e, 0xd680, 0xd681, 0xd682,
+ 0xd683, 0xd684, 0xd685, 0xd686, 0xd687, 0xd688, 0xd689, 0xd68a,
+ 0xd68b, 0xd68c, 0xd68d, 0xd68e, 0xd68f, 0xd690, 0xd691, 0xd692,
+ 0xd693, 0xd694, 0xd695, 0xd696, 0xd697, 0xd698, 0xd699, 0xd69a,
+ 0xd69b, 0xd69c, 0xd69d, 0xd69e, 0xd69f, 0xd6a0, 0xd740, 0xd741,
+ 0xd742, 0xd743, 0xd744, 0xd745, 0xd746, 0xd747, 0xd748, 0xd749,
+ 0xd74a, 0xd74b, 0xd74c, 0xd74d, 0xd74e, 0xd74f, 0xd750, 0xd751,
+ 0xd752, 0xd753, 0xd754, 0xd755, 0xd756, 0xd757, 0xd758, 0xd759,
+ 0xd75a, 0xd75b, 0xd75c, 0xd75d, 0xd75e, 0xd75f, 0xd760, 0xd761,
+ 0xd762, 0xd763, 0xd764, 0xd765, 0xd766, 0xd767, 0xd768, 0xd769,
+ 0xd76a, 0xd76b, 0xd76c, 0xd76d, 0xd76e, 0xd76f, 0xd770, 0xd771,
+ 0xd772, 0xd773, 0xd774, 0xd775, 0xd776, 0xd777, 0xd778, 0xd779,
+ 0xd77a, 0xd77b, 0xd77c, 0xd77d, 0xd77e, 0xd780, 0xd781, 0xd782,
+ 0xd783, 0xd784, 0xd785, 0xd786, 0xd787, 0xd788, 0xd789, 0xd78a,
+ 0xd78b, 0xd78c, 0xd78d, 0xd78e, 0xd78f, 0xd790, 0xd791, 0xd792,
+ 0xd793, 0xd794, 0xd795, 0xd796, 0xd797, 0xd798, 0xd799, 0xd79a,
+ 0xd79b, 0xd79c, 0xd79d, 0xd79e, 0xd79f, 0xd7a0, 0xd840, 0xd841,
+ 0xd842, 0xd843, 0xd844, 0xd845, 0xd846, 0xd847, 0xd848, 0xd849,
+ 0xd84a, 0xd84b, 0xd84c, 0xd84d, 0xd84e, 0xd84f, 0xd850, 0xd851,
+ 0xd852, 0xd853, 0xd854, 0xd855, 0xd856, 0xd857, 0xd858, 0xd859,
+ 0xd85a, 0xd85b, 0xd85c, 0xd85d, 0xd85e, 0xd85f, 0xd860, 0xd861,
+ 0xd862, 0xd863, 0xd864, 0xd865, 0xd866, 0xd867, 0xd868, 0xd869,
+ 0xd86a, 0xd86b, 0xd86c, 0xd86d, 0xd86e, 0xd86f, 0xd870, 0xd871,
+ 0xd872, 0xd873, 0xd874, 0xd875, 0xd876, 0xd877, 0xd878, 0xd879,
+ 0xd87a, 0xd87b, 0xd87c, 0xd87d, 0xd87e, 0xd880, 0xd881, 0xd882,
+ 0xd883, 0xd884, 0xd885, 0xd886, 0xd887, 0xd888, 0xd889, 0xd88a,
+ 0xd88b, 0xd88c, 0xd88d, 0xd88e, 0xd88f, 0xd890, 0xd891, 0xd892,
+ 0xd893, 0xd894, 0xd895, 0xd896, 0xd897, 0xd898, 0xd899, 0xd89a,
+ 0xd89b, 0xd89c, 0xd89d, 0xd89e, 0xd89f, 0xd8a0, 0xd940, 0xd941,
+ 0xd942, 0xd943, 0xd944, 0xd945, 0xd946, 0xd947, 0xd948, 0xd949,
+ 0xd94a, 0xd94b, 0xd94c, 0xd94d, 0xd94e, 0xd94f, 0xd950, 0xd951,
+ 0xd952, 0xd953, 0xd954, 0xd955, 0xd956, 0xd957, 0xd958, 0xd959,
+ 0xd95a, 0xd95b, 0xd95c, 0xd95d, 0xd95e, 0xd95f, 0xd960, 0xd961,
+ 0xd962, 0xd963, 0xd964, 0xd965, 0xd966, 0xd967, 0xd968, 0xd969,
+ 0xd96a, 0xd96b, 0xd96c, 0xd96d, 0xd96e, 0xd96f, 0xd970, 0xd971,
+ 0xd972, 0xd973, 0xd974, 0xd975, 0xd976, 0xd977, 0xd978, 0xd979,
+ 0xd97a, 0xd97b, 0xd97c, 0xd97d, 0xd97e, 0xd980, 0xd981, 0xd982,
+ 0xd983, 0xd984, 0xd985, 0xd986, 0xd987, 0xd988, 0xd989, 0xd98a,
+ 0xd98b, 0xd98c, 0xd98d, 0xd98e, 0xd98f, 0xd990, 0xd991, 0xd992,
+ 0xd993, 0xd994, 0xd995, 0xd996, 0xd997, 0xd998, 0xd999, 0xd99a,
+ 0xd99b, 0xd99c, 0xd99d, 0xd99e, 0xd99f, 0xd9a0, 0xda40, 0xda41,
+ 0xda42, 0xda43, 0xda44, 0xda45, 0xda46, 0xda47, 0xda48, 0xda49,
+ 0xda4a, 0xda4b, 0xda4c, 0xda4d, 0xda4e, 0xda4f, 0xda50, 0xda51,
+ 0xda52, 0xda53, 0xda54, 0xda55, 0xda56, 0xda57, 0xda58, 0xda59,
+ 0xda5a, 0xda5b, 0xda5c, 0xda5d, 0xda5e, 0xda5f, 0xda60, 0xda61,
+ 0xda62, 0xda63, 0xda64, 0xda65, 0xda66, 0xda67, 0xda68, 0xda69,
+ 0xda6a, 0xda6b, 0xda6c, 0xda6d, 0xda6e, 0xda6f, 0xda70, 0xda71,
+ 0xda72, 0xda73, 0xda74, 0xda75, 0xda76, 0xda77, 0xda78, 0xda79,
+ 0xda7a, 0xda7b, 0xda7c, 0xda7d, 0xda7e, 0xda80, 0xda81, 0xda82,
+ 0xda83, 0xda84, 0xda85, 0xda86, 0xda87, 0xda88, 0xda89, 0xda8a,
+ 0xda8b, 0xda8c, 0xda8d, 0xda8e, 0xda8f, 0xda90, 0xda91, 0xda92,
+ 0xda93, 0xda94, 0xda95, 0xda96, 0xda97, 0xda98, 0xda99, 0xda9a,
+ 0xda9b, 0xda9c, 0xda9d, 0xda9e, 0xda9f, 0xdaa0, 0xdb40, 0xdb41,
+ 0xdb42, 0xdb43, 0xdb44, 0xdb45, 0xdb46, 0xdb47, 0xdb48, 0xdb49,
+ 0xdb4a, 0xdb4b, 0xdb4c, 0xdb4d, 0xdb4e, 0xdb4f, 0xdb50, 0xdb51,
+ 0xdb52, 0xdb53, 0xdb54, 0xdb55, 0xdb56, 0xdb57, 0xdb58, 0xdb59,
+ 0xdb5a, 0xdb5b, 0xdb5c, 0xdb5d, 0xdb5e, 0xdb5f, 0xdb60, 0xdb61,
+ 0xdb62, 0xdb63, 0xdb64, 0xdb65, 0xdb66, 0xdb67, 0xdb68, 0xdb69,
+ 0xdb6a, 0xdb6b, 0xdb6c, 0xdb6d, 0xdb6e, 0xdb6f, 0xdb70, 0xdb71,
+ 0xdb72, 0xdb73, 0xdb74, 0xdb75, 0xdb76, 0xdb77, 0xdb78, 0xdb79,
+ 0xdb7a, 0xdb7b, 0xdb7c, 0xdb7d, 0xdb7e, 0xdb80, 0xdb81, 0xdb82,
+ 0xdb83, 0xdb84, 0xdb85, 0xdb86, 0xdb87, 0xdb88, 0xdb89, 0xdb8a,
+ 0xdb8b, 0xdb8c, 0xdb8d, 0xdb8e, 0xdb8f, 0xdb90, 0xdb91, 0xdb92,
+ 0xdb93, 0xdb94, 0xdb95, 0xdb96, 0xdb97, 0xdb98, 0xdb99, 0xdb9a,
+ 0xdb9b, 0xdb9c, 0xdb9d, 0xdb9e, 0xdb9f, 0xdba0, 0xdc40, 0xdc41,
+ 0xdc42, 0xdc43, 0xdc44, 0xdc45, 0xdc46, 0xdc47, 0xdc48, 0xdc49,
+ 0xdc4a, 0xdc4b, 0xdc4c, 0xdc4d, 0xdc4e, 0xdc4f, 0xdc50, 0xdc51,
+ 0xdc52, 0xdc53, 0xdc54, 0xdc55, 0xdc56, 0xdc57, 0xdc58, 0xdc59,
+ 0xdc5a, 0xdc5b, 0xdc5c, 0xdc5d, 0xdc5e, 0xdc5f, 0xdc60, 0xdc61,
+ 0xdc62, 0xdc63, 0xdc64, 0xdc65, 0xdc66, 0xdc67, 0xdc68, 0xdc69,
+ 0xdc6a, 0xdc6b, 0xdc6c, 0xdc6d, 0xdc6e, 0xdc6f, 0xdc70, 0xdc71,
+ 0xdc72, 0xdc73, 0xdc74, 0xdc75, 0xdc76, 0xdc77, 0xdc78, 0xdc79,
+ 0xdc7a, 0xdc7b, 0xdc7c, 0xdc7d, 0xdc7e, 0xdc80, 0xdc81, 0xdc82,
+ 0xdc83, 0xdc84, 0xdc85, 0xdc86, 0xdc87, 0xdc88, 0xdc89, 0xdc8a,
+ 0xdc8b, 0xdc8c, 0xdc8d, 0xdc8e, 0xdc8f, 0xdc90, 0xdc91, 0xdc92,
+ 0xdc93, 0xdc94, 0xdc95, 0xdc96, 0xdc97, 0xdc98, 0xdc99, 0xdc9a,
+ 0xdc9b, 0xdc9c, 0xdc9d, 0xdc9e, 0xdc9f, 0xdca0, 0xdd40, 0xdd41,
+ 0xdd42, 0xdd43, 0xdd44, 0xdd45, 0xdd46, 0xdd47, 0xdd48, 0xdd49,
+ 0xdd4a, 0xdd4b, 0xdd4c, 0xdd4d, 0xdd4e, 0xdd4f, 0xdd50, 0xdd51,
+ 0xdd52, 0xdd53, 0xdd54, 0xdd55, 0xdd56, 0xdd57, 0xdd58, 0xdd59,
+ 0xdd5a, 0xdd5b, 0xdd5c, 0xdd5d, 0xdd5e, 0xdd5f, 0xdd60, 0xdd61,
+ 0xdd62, 0xdd63, 0xdd64, 0xdd65, 0xdd66, 0xdd67, 0xdd68, 0xdd69,
+ 0xdd6a, 0xdd6b, 0xdd6c, 0xdd6d, 0xdd6e, 0xdd6f, 0xdd70, 0xdd71,
+ 0xdd72, 0xdd73, 0xdd74, 0xdd75, 0xdd76, 0xdd77, 0xdd78, 0xdd79,
+ 0xdd7a, 0xdd7b, 0xdd7c, 0xdd7d, 0xdd7e, 0xdd80, 0xdd81, 0xdd82,
+ 0xdd83, 0xdd84, 0xdd85, 0xdd86, 0xdd87, 0xdd88, 0xdd89, 0xdd8a,
+ 0xdd8b, 0xdd8c, 0xdd8d, 0xdd8e, 0xdd8f, 0xdd90, 0xdd91, 0xdd92,
+ 0xdd93, 0xdd94, 0xdd95, 0xdd96, 0xdd97, 0xdd98, 0xdd99, 0xdd9a,
+ 0xdd9b, 0xdd9c, 0xdd9d, 0xdd9e, 0xdd9f, 0xdda0, 0xde40, 0xde41,
+ 0xde42, 0xde43, 0xde44, 0xde45, 0xde46, 0xde47, 0xde48, 0xde49,
+ 0xde4a, 0xde4b, 0xde4c, 0xde4d, 0xde4e, 0xde4f, 0xde50, 0xde51,
+ 0xde52, 0xde53, 0xde54, 0xde55, 0xde56, 0xde57, 0xde58, 0xde59,
+ 0xde5a, 0xde5b, 0xde5c, 0xde5d, 0xde5e, 0xde5f, 0xde60, 0xde61,
+ 0xde62, 0xde63, 0xde64, 0xde65, 0xde66, 0xde67, 0xde68, 0xde69,
+ 0xde6a, 0xde6b, 0xde6c, 0xde6d, 0xde6e, 0xde6f, 0xde70, 0xde71,
+ 0xde72, 0xde73, 0xde74, 0xde75, 0xde76, 0xde77, 0xde78, 0xde79,
+ 0xde7a, 0xde7b, 0xde7c, 0xde7d, 0xde7e, 0xde80, 0xde81, 0xde82,
+ 0xde83, 0xde84, 0xde85, 0xde86, 0xde87, 0xde88, 0xde89, 0xde8a,
+ 0xde8b, 0xde8c, 0xde8d, 0xde8e, 0xde8f, 0xde90, 0xde91, 0xde92,
+ 0xde93, 0xde94, 0xde95, 0xde96, 0xde97, 0xde98, 0xde99, 0xde9a,
+ 0xde9b, 0xde9c, 0xde9d, 0xde9e, 0xde9f, 0xdea0, 0xdf40, 0xdf41,
+ 0xdf42, 0xdf43, 0xdf44, 0xdf45, 0xdf46, 0xdf47, 0xdf48, 0xdf49,
+ 0xdf4a, 0xdf4b, 0xdf4c, 0xdf4d, 0xdf4e, 0xdf4f, 0xdf50, 0xdf51,
+ 0xdf52, 0xdf53, 0xdf54, 0xdf55, 0xdf56, 0xdf57, 0xdf58, 0xdf59,
+ 0xdf5a, 0xdf5b, 0xdf5c, 0xdf5d, 0xdf5e, 0xdf5f, 0xdf60, 0xdf61,
+ 0xdf62, 0xdf63, 0xdf64, 0xdf65, 0xdf66, 0xdf67, 0xdf68, 0xdf69,
+ 0xdf6a, 0xdf6b, 0xdf6c, 0xdf6d, 0xdf6e, 0xdf6f, 0xdf70, 0xdf71,
+ 0xdf72, 0xdf73, 0xdf74, 0xdf75, 0xdf76, 0xdf77, 0xdf78, 0xdf79,
+ 0xdf7a, 0xdf7b, 0xdf7c, 0xdf7d, 0xdf7e, 0xdf80, 0xdf81, 0xdf82,
+ 0xdf83, 0xdf84, 0xdf85, 0xdf86, 0xdf87, 0xdf88, 0xdf89, 0xdf8a,
+ 0xdf8b, 0xdf8c, 0xdf8d, 0xdf8e, 0xdf8f, 0xdf90, 0xdf91, 0xdf92,
+ 0xdf93, 0xdf94, 0xdf95, 0xdf96, 0xdf97, 0xdf98, 0xdf99, 0xdf9a,
+ 0xdf9b, 0xdf9c, 0xdf9d, 0xdf9e, 0xdf9f, 0xdfa0, 0xe040, 0xe041,
+ 0xe042, 0xe043, 0xe044, 0xe045, 0xe046, 0xe047, 0xe048, 0xe049,
+ 0xe04a, 0xe04b, 0xe04c, 0xe04d, 0xe04e, 0xe04f, 0xe050, 0xe051,
+ 0xe052, 0xe053, 0xe054, 0xe055, 0xe056, 0xe057, 0xe058, 0xe059,
+ 0xe05a, 0xe05b, 0xe05c, 0xe05d, 0xe05e, 0xe05f, 0xe060, 0xe061,
+ 0xe062, 0xe063, 0xe064, 0xe065, 0xe066, 0xe067, 0xe068, 0xe069,
+ 0xe06a, 0xe06b, 0xe06c, 0xe06d, 0xe06e, 0xe06f, 0xe070, 0xe071,
+ 0xe072, 0xe073, 0xe074, 0xe075, 0xe076, 0xe077, 0xe078, 0xe079,
+ 0xe07a, 0xe07b, 0xe07c, 0xe07d, 0xe07e, 0xe080, 0xe081, 0xe082,
+ 0xe083, 0xe084, 0xe085, 0xe086, 0xe087, 0xe088, 0xe089, 0xe08a,
+ 0xe08b, 0xe08c, 0xe08d, 0xe08e, 0xe08f, 0xe090, 0xe091, 0xe092,
+ 0xe093, 0xe094, 0xe095, 0xe096, 0xe097, 0xe098, 0xe099, 0xe09a,
+ 0xe09b, 0xe09c, 0xe09d, 0xe09e, 0xe09f, 0xe0a0, 0xe140, 0xe141,
+ 0xe142, 0xe143, 0xe144, 0xe145, 0xe146, 0xe147, 0xe148, 0xe149,
+ 0xe14a, 0xe14b, 0xe14c, 0xe14d, 0xe14e, 0xe14f, 0xe150, 0xe151,
+ 0xe152, 0xe153, 0xe154, 0xe155, 0xe156, 0xe157, 0xe158, 0xe159,
+ 0xe15a, 0xe15b, 0xe15c, 0xe15d, 0xe15e, 0xe15f, 0xe160, 0xe161,
+ 0xe162, 0xe163, 0xe164, 0xe165, 0xe166, 0xe167, 0xe168, 0xe169,
+ 0xe16a, 0xe16b, 0xe16c, 0xe16d, 0xe16e, 0xe16f, 0xe170, 0xe171,
+ 0xe172, 0xe173, 0xe174, 0xe175, 0xe176, 0xe177, 0xe178, 0xe179,
+ 0xe17a, 0xe17b, 0xe17c, 0xe17d, 0xe17e, 0xe180, 0xe181, 0xe182,
+ 0xe183, 0xe184, 0xe185, 0xe186, 0xe187, 0xe188, 0xe189, 0xe18a,
+ 0xe18b, 0xe18c, 0xe18d, 0xe18e, 0xe18f, 0xe190, 0xe191, 0xe192,
+ 0xe193, 0xe194, 0xe195, 0xe196, 0xe197, 0xe198, 0xe199, 0xe19a,
+ 0xe19b, 0xe19c, 0xe19d, 0xe19e, 0xe19f, 0xe1a0, 0xe240, 0xe241,
+ 0xe242, 0xe243, 0xe244, 0xe245, 0xe246, 0xe247, 0xe248, 0xe249,
+ 0xe24a, 0xe24b, 0xe24c, 0xe24d, 0xe24e, 0xe24f, 0xe250, 0xe251,
+ 0xe252, 0xe253, 0xe254, 0xe255, 0xe256, 0xe257, 0xe258, 0xe259,
+ 0xe25a, 0xe25b, 0xe25c, 0xe25d, 0xe25e, 0xe25f, 0xe260, 0xe261,
+ 0xe262, 0xe263, 0xe264, 0xe265, 0xe266, 0xe267, 0xe268, 0xe269,
+ 0xe26a, 0xe26b, 0xe26c, 0xe26d, 0xe26e, 0xe26f, 0xe270, 0xe271,
+ 0xe272, 0xe273, 0xe274, 0xe275, 0xe276, 0xe277, 0xe278, 0xe279,
+ 0xe27a, 0xe27b, 0xe27c, 0xe27d, 0xe27e, 0xe280, 0xe281, 0xe282,
+ 0xe283, 0xe284, 0xe285, 0xe286, 0xe287, 0xe288, 0xe289, 0xe28a,
+ 0xe28b, 0xe28c, 0xe28d, 0xe28e, 0xe28f, 0xe290, 0xe291, 0xe292,
+ 0xe293, 0xe294, 0xe295, 0xe296, 0xe297, 0xe298, 0xe299, 0xe29a,
+ 0xe29b, 0xe29c, 0xe29d, 0xe29e, 0xe29f, 0xe2a0, 0xe340, 0xe341,
+ 0xe342, 0xe343, 0xe344, 0xe345, 0xe346, 0xe347, 0xe348, 0xe349,
+ 0xe34a, 0xe34b, 0xe34c, 0xe34d, 0xe34e, 0xe34f, 0xe350, 0xe351,
+ 0xe352, 0xe353, 0xe354, 0xe355, 0xe356, 0xe357, 0xe358, 0xe359,
+ 0xe35a, 0xe35b, 0xe35c, 0xe35d, 0xe35e, 0xe35f, 0xe360, 0xe361,
+ 0xe362, 0xe363, 0xe364, 0xe365, 0xe366, 0xe367, 0xe368, 0xe369,
+ 0xe36a, 0xe36b, 0xe36c, 0xe36d, 0xe36e, 0xe36f, 0xe370, 0xe371,
+ 0xe372, 0xe373, 0xe374, 0xe375, 0xe376, 0xe377, 0xe378, 0xe379,
+ 0xe37a, 0xe37b, 0xe37c, 0xe37d, 0xe37e, 0xe380, 0xe381, 0xe382,
+ 0xe383, 0xe384, 0xe385, 0xe386, 0xe387, 0xe388, 0xe389, 0xe38a,
+ 0xe38b, 0xe38c, 0xe38d, 0xe38e, 0xe38f, 0xe390, 0xe391, 0xe392,
+ 0xe393, 0xe394, 0xe395, 0xe396, 0xe397, 0xe398, 0xe399, 0xe39a,
+ 0xe39b, 0xe39c, 0xe39d, 0xe39e, 0xe39f, 0xe3a0, 0xe440, 0xe441,
+ 0xe442, 0xe443, 0xe444, 0xe445, 0xe446, 0xe447, 0xe448, 0xe449,
+ 0xe44a, 0xe44b, 0xe44c, 0xe44d, 0xe44e, 0xe44f, 0xe450, 0xe451,
+ 0xe452, 0xe453, 0xe454, 0xe455, 0xe456, 0xe457, 0xe458, 0xe459,
+ 0xe45a, 0xe45b, 0xe45c, 0xe45d, 0xe45e, 0xe45f, 0xe460, 0xe461,
+ 0xe462, 0xe463, 0xe464, 0xe465, 0xe466, 0xe467, 0xe468, 0xe469,
+ 0xe46a, 0xe46b, 0xe46c, 0xe46d, 0xe46e, 0xe46f, 0xe470, 0xe471,
+ 0xe472, 0xe473, 0xe474, 0xe475, 0xe476, 0xe477, 0xe478, 0xe479,
+ 0xe47a, 0xe47b, 0xe47c, 0xe47d, 0xe47e, 0xe480, 0xe481, 0xe482,
+ 0xe483, 0xe484, 0xe485, 0xe486, 0xe487, 0xe488, 0xe489, 0xe48a,
+ 0xe48b, 0xe48c, 0xe48d, 0xe48e, 0xe48f, 0xe490, 0xe491, 0xe492,
+ 0xe493, 0xe494, 0xe495, 0xe496, 0xe497, 0xe498, 0xe499, 0xe49a,
+ 0xe49b, 0xe49c, 0xe49d, 0xe49e, 0xe49f, 0xe4a0, 0xe540, 0xe541,
+ 0xe542, 0xe543, 0xe544, 0xe545, 0xe546, 0xe547, 0xe548, 0xe549,
+ 0xe54a, 0xe54b, 0xe54c, 0xe54d, 0xe54e, 0xe54f, 0xe550, 0xe551,
+ 0xe552, 0xe553, 0xe554, 0xe555, 0xe556, 0xe557, 0xe558, 0xe559,
+ 0xe55a, 0xe55b, 0xe55c, 0xe55d, 0xe55e, 0xe55f, 0xe560, 0xe561,
+ 0xe562, 0xe563, 0xe564, 0xe565, 0xe566, 0xe567, 0xe568, 0xe569,
+ 0xe56a, 0xe56b, 0xe56c, 0xe56d, 0xe56e, 0xe56f, 0xe570, 0xe571,
+ 0xe572, 0xe573, 0xe574, 0xe575, 0xe576, 0xe577, 0xe578, 0xe579,
+ 0xe57a, 0xe57b, 0xe57c, 0xe57d, 0xe57e, 0xe580, 0xe581, 0xe582,
+ 0xe583, 0xe584, 0xe585, 0xe586, 0xe587, 0xe588, 0xe589, 0xe58a,
+ 0xe58b, 0xe58c, 0xe58d, 0xe58e, 0xe58f, 0xe590, 0xe591, 0xe592,
+ 0xe593, 0xe594, 0xe595, 0xe596, 0xe597, 0xe598, 0xe599, 0xe59a,
+ 0xe59b, 0xe59c, 0xe59d, 0xe59e, 0xe59f, 0xe5a0, 0xe640, 0xe641,
+ 0xe642, 0xe643, 0xe644, 0xe645, 0xe646, 0xe647, 0xe648, 0xe649,
+ 0xe64a, 0xe64b, 0xe64c, 0xe64d, 0xe64e, 0xe64f, 0xe650, 0xe651,
+ 0xe652, 0xe653, 0xe654, 0xe655, 0xe656, 0xe657, 0xe658, 0xe659,
+ 0xe65a, 0xe65b, 0xe65c, 0xe65d, 0xe65e, 0xe65f, 0xe660, 0xe661,
+ 0xe662, 0xe663, 0xe664, 0xe665, 0xe666, 0xe667, 0xe668, 0xe669,
+ 0xe66a, 0xe66b, 0xe66c, 0xe66d, 0xe66e, 0xe66f, 0xe670, 0xe671,
+ 0xe672, 0xe673, 0xe674, 0xe675, 0xe676, 0xe677, 0xe678, 0xe679,
+ 0xe67a, 0xe67b, 0xe67c, 0xe67d, 0xe67e, 0xe680, 0xe681, 0xe682,
+ 0xe683, 0xe684, 0xe685, 0xe686, 0xe687, 0xe688, 0xe689, 0xe68a,
+ 0xe68b, 0xe68c, 0xe68d, 0xe68e, 0xe68f, 0xe690, 0xe691, 0xe692,
+ 0xe693, 0xe694, 0xe695, 0xe696, 0xe697, 0xe698, 0xe699, 0xe69a,
+ 0xe69b, 0xe69c, 0xe69d, 0xe69e, 0xe69f, 0xe6a0, 0xe740, 0xe741,
+ 0xe742, 0xe743, 0xe744, 0xe745, 0xe746, 0xe747, 0xe748, 0xe749,
+ 0xe74a, 0xe74b, 0xe74c, 0xe74d, 0xe74e, 0xe74f, 0xe750, 0xe751,
+ 0xe752, 0xe753, 0xe754, 0xe755, 0xe756, 0xe757, 0xe758, 0xe759,
+ 0xe75a, 0xe75b, 0xe75c, 0xe75d, 0xe75e, 0xe75f, 0xe760, 0xe761,
+ 0xe762, 0xe763, 0xe764, 0xe765, 0xe766, 0xe767, 0xe768, 0xe769,
+ 0xe76a, 0xe76b, 0xe76c, 0xe76d, 0xe76e, 0xe76f, 0xe770, 0xe771,
+ 0xe772, 0xe773, 0xe774, 0xe775, 0xe776, 0xe777, 0xe778, 0xe779,
+ 0xe77a, 0xe77b, 0xe77c, 0xe77d, 0xe77e, 0xe780, 0xe781, 0xe782,
+ 0xe783, 0xe784, 0xe785, 0xe786, 0xe787, 0xe788, 0xe789, 0xe78a,
+ 0xe78b, 0xe78c, 0xe78d, 0xe78e, 0xe78f, 0xe790, 0xe791, 0xe792,
+ 0xe793, 0xe794, 0xe795, 0xe796, 0xe797, 0xe798, 0xe799, 0xe79a,
+ 0xe79b, 0xe79c, 0xe79d, 0xe79e, 0xe79f, 0xe7a0, 0xe840, 0xe841,
+ 0xe842, 0xe843, 0xe844, 0xe845, 0xe846, 0xe847, 0xe848, 0xe849,
+ 0xe84a, 0xe84b, 0xe84c, 0xe84d, 0xe84e, 0xe84f, 0xe850, 0xe851,
+ 0xe852, 0xe853, 0xe854, 0xe855, 0xe856, 0xe857, 0xe858, 0xe859,
+ 0xe85a, 0xe85b, 0xe85c, 0xe85d, 0xe85e, 0xe85f, 0xe860, 0xe861,
+ 0xe862, 0xe863, 0xe864, 0xe865, 0xe866, 0xe867, 0xe868, 0xe869,
+ 0xe86a, 0xe86b, 0xe86c, 0xe86d, 0xe86e, 0xe86f, 0xe870, 0xe871,
+ 0xe872, 0xe873, 0xe874, 0xe875, 0xe876, 0xe877, 0xe878, 0xe879,
+ 0xe87a, 0xe87b, 0xe87c, 0xe87d, 0xe87e, 0xe880, 0xe881, 0xe882,
+ 0xe883, 0xe884, 0xe885, 0xe886, 0xe887, 0xe888, 0xe889, 0xe88a,
+ 0xe88b, 0xe88c, 0xe88d, 0xe88e, 0xe88f, 0xe890, 0xe891, 0xe892,
+ 0xe893, 0xe894, 0xe895, 0xe896, 0xe897, 0xe898, 0xe899, 0xe89a,
+ 0xe89b, 0xe89c, 0xe89d, 0xe89e, 0xe89f, 0xe8a0, 0xe940, 0xe941,
+ 0xe942, 0xe943, 0xe944, 0xe945, 0xe946, 0xe947, 0xe948, 0xe949,
+ 0xe94a, 0xe94b, 0xe94c, 0xe94d, 0xe94e, 0xe94f, 0xe950, 0xe951,
+ 0xe952, 0xe953, 0xe954, 0xe955, 0xe956, 0xe957, 0xe958, 0xe959,
+ 0xe95a, 0xe95b, 0xe95c, 0xe95d, 0xe95e, 0xe95f, 0xe960, 0xe961,
+ 0xe962, 0xe963, 0xe964, 0xe965, 0xe966, 0xe967, 0xe968, 0xe969,
+ 0xe96a, 0xe96b, 0xe96c, 0xe96d, 0xe96e, 0xe96f, 0xe970, 0xe971,
+ 0xe972, 0xe973, 0xe974, 0xe975, 0xe976, 0xe977, 0xe978, 0xe979,
+ 0xe97a, 0xe97b, 0xe97c, 0xe97d, 0xe97e, 0xe980, 0xe981, 0xe982,
+ 0xe983, 0xe984, 0xe985, 0xe986, 0xe987, 0xe988, 0xe989, 0xe98a,
+ 0xe98b, 0xe98c, 0xe98d, 0xe98e, 0xe98f, 0xe990, 0xe991, 0xe992,
+ 0xe993, 0xe994, 0xe995, 0xe996, 0xe997, 0xe998, 0xe999, 0xe99a,
+ 0xe99b, 0xe99c, 0xe99d, 0xe99e, 0xe99f, 0xe9a0, 0xea40, 0xea41,
+ 0xea42, 0xea43, 0xea44, 0xea45, 0xea46, 0xea47, 0xea48, 0xea49,
+ 0xea4a, 0xea4b, 0xea4c, 0xea4d, 0xea4e, 0xea4f, 0xea50, 0xea51,
+ 0xea52, 0xea53, 0xea54, 0xea55, 0xea56, 0xea57, 0xea58, 0xea59,
+ 0xea5a, 0xea5b, 0xea5c, 0xea5d, 0xea5e, 0xea5f, 0xea60, 0xea61,
+ 0xea62, 0xea63, 0xea64, 0xea65, 0xea66, 0xea67, 0xea68, 0xea69,
+ 0xea6a, 0xea6b, 0xea6c, 0xea6d, 0xea6e, 0xea6f, 0xea70, 0xea71,
+ 0xea72, 0xea73, 0xea74, 0xea75, 0xea76, 0xea77, 0xea78, 0xea79,
+ 0xea7a, 0xea7b, 0xea7c, 0xea7d, 0xea7e, 0xea80, 0xea81, 0xea82,
+ 0xea83, 0xea84, 0xea85, 0xea86, 0xea87, 0xea88, 0xea89, 0xea8a,
+ 0xea8b, 0xea8c, 0xea8d, 0xea8e, 0xea8f, 0xea90, 0xea91, 0xea92,
+ 0xea93, 0xea94, 0xea95, 0xea96, 0xea97, 0xea98, 0xea99, 0xea9a,
+ 0xea9b, 0xea9c, 0xea9d, 0xea9e, 0xea9f, 0xeaa0, 0xeb40, 0xeb41,
+ 0xeb42, 0xeb43, 0xeb44, 0xeb45, 0xeb46, 0xeb47, 0xeb48, 0xeb49,
+ 0xeb4a, 0xeb4b, 0xeb4c, 0xeb4d, 0xeb4e, 0xeb4f, 0xeb50, 0xeb51,
+ 0xeb52, 0xeb53, 0xeb54, 0xeb55, 0xeb56, 0xeb57, 0xeb58, 0xeb59,
+ 0xeb5a, 0xeb5b, 0xeb5c, 0xeb5d, 0xeb5e, 0xeb5f, 0xeb60, 0xeb61,
+ 0xeb62, 0xeb63, 0xeb64, 0xeb65, 0xeb66, 0xeb67, 0xeb68, 0xeb69,
+ 0xeb6a, 0xeb6b, 0xeb6c, 0xeb6d, 0xeb6e, 0xeb6f, 0xeb70, 0xeb71,
+ 0xeb72, 0xeb73, 0xeb74, 0xeb75, 0xeb76, 0xeb77, 0xeb78, 0xeb79,
+ 0xeb7a, 0xeb7b, 0xeb7c, 0xeb7d, 0xeb7e, 0xeb80, 0xeb81, 0xeb82,
+ 0xeb83, 0xeb84, 0xeb85, 0xeb86, 0xeb87, 0xeb88, 0xeb89, 0xeb8a,
+ 0xeb8b, 0xeb8c, 0xeb8d, 0xeb8e, 0xeb8f, 0xeb90, 0xeb91, 0xeb92,
+ 0xeb93, 0xeb94, 0xeb95, 0xeb96, 0xeb97, 0xeb98, 0xeb99, 0xeb9a,
+ 0xeb9b, 0xeb9c, 0xeb9d, 0xeb9e, 0xeb9f, 0xeba0, 0xec40, 0xec41,
+ 0xec42, 0xec43, 0xec44, 0xec45, 0xec46, 0xec47, 0xec48, 0xec49,
+ 0xec4a, 0xec4b, 0xec4c, 0xec4d, 0xec4e, 0xec4f, 0xec50, 0xec51,
+ 0xec52, 0xec53, 0xec54, 0xec55, 0xec56, 0xec57, 0xec58, 0xec59,
+ 0xec5a, 0xec5b, 0xec5c, 0xec5d, 0xec5e, 0xec5f, 0xec60, 0xec61,
+ 0xec62, 0xec63, 0xec64, 0xec65, 0xec66, 0xec67, 0xec68, 0xec69,
+ 0xec6a, 0xec6b, 0xec6c, 0xec6d, 0xec6e, 0xec6f, 0xec70, 0xec71,
+ 0xec72, 0xec73, 0xec74, 0xec75, 0xec76, 0xec77, 0xec78, 0xec79,
+ 0xec7a, 0xec7b, 0xec7c, 0xec7d, 0xec7e, 0xec80, 0xec81, 0xec82,
+ 0xec83, 0xec84, 0xec85, 0xec86, 0xec87, 0xec88, 0xec89, 0xec8a,
+ 0xec8b, 0xec8c, 0xec8d, 0xec8e, 0xec8f, 0xec90, 0xec91, 0xec92,
+ 0xec93, 0xec94, 0xec95, 0xec96, 0xec97, 0xec98, 0xec99, 0xec9a,
+ 0xec9b, 0xec9c, 0xec9d, 0xec9e, 0xec9f, 0xeca0, 0xed40, 0xed41,
+ 0xed42, 0xed43, 0xed44, 0xed45, 0xed46, 0xed47, 0xed48, 0xed49,
+ 0xed4a, 0xed4b, 0xed4c, 0xed4d, 0xed4e, 0xed4f, 0xed50, 0xed51,
+ 0xed52, 0xed53, 0xed54, 0xed55, 0xed56, 0xed57, 0xed58, 0xed59,
+ 0xed5a, 0xed5b, 0xed5c, 0xed5d, 0xed5e, 0xed5f, 0xed60, 0xed61,
+ 0xed62, 0xed63, 0xed64, 0xed65, 0xed66, 0xed67, 0xed68, 0xed69,
+ 0xed6a, 0xed6b, 0xed6c, 0xed6d, 0xed6e, 0xed6f, 0xed70, 0xed71,
+ 0xed72, 0xed73, 0xed74, 0xed75, 0xed76, 0xed77, 0xed78, 0xed79,
+ 0xed7a, 0xed7b, 0xed7c, 0xed7d, 0xed7e, 0xed80, 0xed81, 0xed82,
+ 0xed83, 0xed84, 0xed85, 0xed86, 0xed87, 0xed88, 0xed89, 0xed8a,
+ 0xed8b, 0xed8c, 0xed8d, 0xed8e, 0xed8f, 0xed90, 0xed91, 0xed92,
+ 0xed93, 0xed94, 0xed95, 0xed96, 0xed97, 0xed98, 0xed99, 0xed9a,
+ 0xed9b, 0xed9c, 0xed9d, 0xed9e, 0xed9f, 0xeda0, 0xee40, 0xee41,
+ 0xee42, 0xee43, 0xee44, 0xee45, 0xee46, 0xee47, 0xee48, 0xee49,
+ 0xee4a, 0xee4b, 0xee4c, 0xee4d, 0xee4e, 0xee4f, 0xee50, 0xee51,
+ 0xee52, 0xee53, 0xee54, 0xee55, 0xee56, 0xee57, 0xee58, 0xee59,
+ 0xee5a, 0xee5b, 0xee5c, 0xee5d, 0xee5e, 0xee5f, 0xee60, 0xee61,
+ 0xee62, 0xee63, 0xee64, 0xee65, 0xee66, 0xee67, 0xee68, 0xee69,
+ 0xee6a, 0xee6b, 0xee6c, 0xee6d, 0xee6e, 0xee6f, 0xee70, 0xee71,
+ 0xee72, 0xee73, 0xee74, 0xee75, 0xee76, 0xee77, 0xee78, 0xee79,
+ 0xee7a, 0xee7b, 0xee7c, 0xee7d, 0xee7e, 0xee80, 0xee81, 0xee82,
+ 0xee83, 0xee84, 0xee85, 0xee86, 0xee87, 0xee88, 0xee89, 0xee8a,
+ 0xee8b, 0xee8c, 0xee8d, 0xee8e, 0xee8f, 0xee90, 0xee91, 0xee92,
+ 0xee93, 0xee94, 0xee95, 0xee96, 0xee97, 0xee98, 0xee99, 0xee9a,
+ 0xee9b, 0xee9c, 0xee9d, 0xee9e, 0xee9f, 0xeea0, 0xef40, 0xef41,
+ 0xef42, 0xef43, 0xef44, 0xef45, 0xef46, 0xef47, 0xef48, 0xef49,
+ 0xef4a, 0xef4b, 0xef4c, 0xef4d, 0xef4e, 0xef4f, 0xef50, 0xef51,
+ 0xef52, 0xef53, 0xef54, 0xef55, 0xef56, 0xef57, 0xef58, 0xef59,
+ 0xef5a, 0xef5b, 0xef5c, 0xef5d, 0xef5e, 0xef5f, 0xef60, 0xef61,
+ 0xef62, 0xef63, 0xef64, 0xef65, 0xef66, 0xef67, 0xef68, 0xef69,
+ 0xef6a, 0xef6b, 0xef6c, 0xef6d, 0xef6e, 0xef6f, 0xef70, 0xef71,
+ 0xef72, 0xef73, 0xef74, 0xef75, 0xef76, 0xef77, 0xef78, 0xef79,
+ 0xef7a, 0xef7b, 0xef7c, 0xef7d, 0xef7e, 0xef80, 0xef81, 0xef82,
+ 0xef83, 0xef84, 0xef85, 0xef86, 0xef87, 0xef88, 0xef89, 0xef8a,
+ 0xef8b, 0xef8c, 0xef8d, 0xef8e, 0xef8f, 0xef90, 0xef91, 0xef92,
+ 0xef93, 0xef94, 0xef95, 0xef96, 0xef97, 0xef98, 0xef99, 0xef9a,
+ 0xef9b, 0xef9c, 0xef9d, 0xef9e, 0xef9f, 0xefa0, 0xf040, 0xf041,
+ 0xf042, 0xf043, 0xf044, 0xf045, 0xf046, 0xf047, 0xf048, 0xf049,
+ 0xf04a, 0xf04b, 0xf04c, 0xf04d, 0xf04e, 0xf04f, 0xf050, 0xf051,
+ 0xf052, 0xf053, 0xf054, 0xf055, 0xf056, 0xf057, 0xf058, 0xf059,
+ 0xf05a, 0xf05b, 0xf05c, 0xf05d, 0xf05e, 0xf05f, 0xf060, 0xf061,
+ 0xf062, 0xf063, 0xf064, 0xf065, 0xf066, 0xf067, 0xf068, 0xf069,
+ 0xf06a, 0xf06b, 0xf06c, 0xf06d, 0xf06e, 0xf06f, 0xf070, 0xf071,
+ 0xf072, 0xf073, 0xf074, 0xf075, 0xf076, 0xf077, 0xf078, 0xf079,
+ 0xf07a, 0xf07b, 0xf07c, 0xf07d, 0xf07e, 0xf080, 0xf081, 0xf082,
+ 0xf083, 0xf084, 0xf085, 0xf086, 0xf087, 0xf088, 0xf089, 0xf08a,
+ 0xf08b, 0xf08c, 0xf08d, 0xf08e, 0xf08f, 0xf090, 0xf091, 0xf092,
+ 0xf093, 0xf094, 0xf095, 0xf096, 0xf097, 0xf098, 0xf099, 0xf09a,
+ 0xf09b, 0xf09c, 0xf09d, 0xf09e, 0xf09f, 0xf0a0, 0xf140, 0xf141,
+ 0xf142, 0xf143, 0xf144, 0xf145, 0xf146, 0xf147, 0xf148, 0xf149,
+ 0xf14a, 0xf14b, 0xf14c, 0xf14d, 0xf14e, 0xf14f, 0xf150, 0xf151,
+ 0xf152, 0xf153, 0xf154, 0xf155, 0xf156, 0xf157, 0xf158, 0xf159,
+ 0xf15a, 0xf15b, 0xf15c, 0xf15d, 0xf15e, 0xf15f, 0xf160, 0xf161,
+ 0xf162, 0xf163, 0xf164, 0xf165, 0xf166, 0xf167, 0xf168, 0xf169,
+ 0xf16a, 0xf16b, 0xf16c, 0xf16d, 0xf16e, 0xf16f, 0xf170, 0xf171,
+ 0xf172, 0xf173, 0xf174, 0xf175, 0xf176, 0xf177, 0xf178, 0xf179,
+ 0xf17a, 0xf17b, 0xf17c, 0xf17d, 0xf17e, 0xf180, 0xf181, 0xf182,
+ 0xf183, 0xf184, 0xf185, 0xf186, 0xf187, 0xf188, 0xf189, 0xf18a,
+ 0xf18b, 0xf18c, 0xf18d, 0xf18e, 0xf18f, 0xf190, 0xf191, 0xf192,
+ 0xf193, 0xf194, 0xf195, 0xf196, 0xf197, 0xf198, 0xf199, 0xf19a,
+ 0xf19b, 0xf19c, 0xf19d, 0xf19e, 0xf19f, 0xf1a0, 0xf240, 0xf241,
+ 0xf242, 0xf243, 0xf244, 0xf245, 0xf246, 0xf247, 0xf248, 0xf249,
+ 0xf24a, 0xf24b, 0xf24c, 0xf24d, 0xf24e, 0xf24f, 0xf250, 0xf251,
+ 0xf252, 0xf253, 0xf254, 0xf255, 0xf256, 0xf257, 0xf258, 0xf259,
+ 0xf25a, 0xf25b, 0xf25c, 0xf25d, 0xf25e, 0xf25f, 0xf260, 0xf261,
+ 0xf262, 0xf263, 0xf264, 0xf265, 0xf266, 0xf267, 0xf268, 0xf269,
+ 0xf26a, 0xf26b, 0xf26c, 0xf26d, 0xf26e, 0xf26f, 0xf270, 0xf271,
+ 0xf272, 0xf273, 0xf274, 0xf275, 0xf276, 0xf277, 0xf278, 0xf279,
+ 0xf27a, 0xf27b, 0xf27c, 0xf27d, 0xf27e, 0xf280, 0xf281, 0xf282,
+ 0xf283, 0xf284, 0xf285, 0xf286, 0xf287, 0xf288, 0xf289, 0xf28a,
+ 0xf28b, 0xf28c, 0xf28d, 0xf28e, 0xf28f, 0xf290, 0xf291, 0xf292,
+ 0xf293, 0xf294, 0xf295, 0xf296, 0xf297, 0xf298, 0xf299, 0xf29a,
+ 0xf29b, 0xf29c, 0xf29d, 0xf29e, 0xf29f, 0xf2a0, 0xf340, 0xf341,
+ 0xf342, 0xf343, 0xf344, 0xf345, 0xf346, 0xf347, 0xf348, 0xf349,
+ 0xf34a, 0xf34b, 0xf34c, 0xf34d, 0xf34e, 0xf34f, 0xf350, 0xf351,
+ 0xf352, 0xf353, 0xf354, 0xf355, 0xf356, 0xf357, 0xf358, 0xf359,
+ 0xf35a, 0xf35b, 0xf35c, 0xf35d, 0xf35e, 0xf35f, 0xf360, 0xf361,
+ 0xf362, 0xf363, 0xf364, 0xf365, 0xf366, 0xf367, 0xf368, 0xf369,
+ 0xf36a, 0xf36b, 0xf36c, 0xf36d, 0xf36e, 0xf36f, 0xf370, 0xf371,
+ 0xf372, 0xf373, 0xf374, 0xf375, 0xf376, 0xf377, 0xf378, 0xf379,
+ 0xf37a, 0xf37b, 0xf37c, 0xf37d, 0xf37e, 0xf380, 0xf381, 0xf382,
+ 0xf383, 0xf384, 0xf385, 0xf386, 0xf387, 0xf388, 0xf389, 0xf38a,
+ 0xf38b, 0xf38c, 0xf38d, 0xf38e, 0xf38f, 0xf390, 0xf391, 0xf392,
+ 0xf393, 0xf394, 0xf395, 0xf396, 0xf397, 0xf398, 0xf399, 0xf39a,
+ 0xf39b, 0xf39c, 0xf39d, 0xf39e, 0xf39f, 0xf3a0, 0xf440, 0xf441,
+ 0xf442, 0xf443, 0xf444, 0xf445, 0xf446, 0xf447, 0xf448, 0xf449,
+ 0xf44a, 0xf44b, 0xf44c, 0xf44d, 0xf44e, 0xf44f, 0xf450, 0xf451,
+ 0xf452, 0xf453, 0xf454, 0xf455, 0xf456, 0xf457, 0xf458, 0xf459,
+ 0xf45a, 0xf45b, 0xf45c, 0xf45d, 0xf45e, 0xf45f, 0xf460, 0xf461,
+ 0xf462, 0xf463, 0xf464, 0xf465, 0xf466, 0xf467, 0xf468, 0xf469,
+ 0xf46a, 0xf46b, 0xf46c, 0xf46d, 0xf46e, 0xf46f, 0xf470, 0xf471,
+ 0xf472, 0xf473, 0xf474, 0xf475, 0xf476, 0xf477, 0xf478, 0xf479,
+ 0xf47a, 0xf47b, 0xf47c, 0xf47d, 0xf47e, 0xf480, 0xf481, 0xf482,
+ 0xf483, 0xf484, 0xf485, 0xf486, 0xf487, 0xf488, 0xf489, 0xf48a,
+ 0xf48b, 0xf48c, 0xf48d, 0xf48e, 0xf48f, 0xf490, 0xf491, 0xf492,
+ 0xf493, 0xf494, 0xf495, 0xf496, 0xf497, 0xf498, 0xf499, 0xf49a,
+ 0xf49b, 0xf49c, 0xf49d, 0xf49e, 0xf49f, 0xf4a0, 0xf540, 0xf541,
+ 0xf542, 0xf543, 0xf544, 0xf545, 0xf546, 0xf547, 0xf548, 0xf549,
+ 0xf54a, 0xf54b, 0xf54c, 0xf54d, 0xf54e, 0xf54f, 0xf550, 0xf551,
+ 0xf552, 0xf553, 0xf554, 0xf555, 0xf556, 0xf557, 0xf558, 0xf559,
+ 0xf55a, 0xf55b, 0xf55c, 0xf55d, 0xf55e, 0xf55f, 0xf560, 0xf561,
+ 0xf562, 0xf563, 0xf564, 0xf565, 0xf566, 0xf567, 0xf568, 0xf569,
+ 0xf56a, 0xf56b, 0xf56c, 0xf56d, 0xf56e, 0xf56f, 0xf570, 0xf571,
+ 0xf572, 0xf573, 0xf574, 0xf575, 0xf576, 0xf577, 0xf578, 0xf579,
+ 0xf57a, 0xf57b, 0xf57c, 0xf57d, 0xf57e, 0xf580, 0xf581, 0xf582,
+ 0xf583, 0xf584, 0xf585, 0xf586, 0xf587, 0xf588, 0xf589, 0xf58a,
+ 0xf58b, 0xf58c, 0xf58d, 0xf58e, 0xf58f, 0xf590, 0xf591, 0xf592,
+ 0xf593, 0xf594, 0xf595, 0xf596, 0xf597, 0xf598, 0xf599, 0xf59a,
+ 0xf59b, 0xf59c, 0xf59d, 0xf59e, 0xf59f, 0xf5a0, 0xf640, 0xf641,
+ 0xf642, 0xf643, 0xf644, 0xf645, 0xf646, 0xf647, 0xf648, 0xf649,
+ 0xf64a, 0xf64b, 0xf64c, 0xf64d, 0xf64e, 0xf64f, 0xf650, 0xf651,
+ 0xf652, 0xf653, 0xf654, 0xf655, 0xf656, 0xf657, 0xf658, 0xf659,
+ 0xf65a, 0xf65b, 0xf65c, 0xf65d, 0xf65e, 0xf65f, 0xf660, 0xf661,
+ 0xf662, 0xf663, 0xf664, 0xf665, 0xf666, 0xf667, 0xf668, 0xf669,
+ 0xf66a, 0xf66b, 0xf66c, 0xf66d, 0xf66e, 0xf66f, 0xf670, 0xf671,
+ 0xf672, 0xf673, 0xf674, 0xf675, 0xf676, 0xf677, 0xf678, 0xf679,
+ 0xf67a, 0xf67b, 0xf67c, 0xf67d, 0xf67e, 0xf680, 0xf681, 0xf682,
+ 0xf683, 0xf684, 0xf685, 0xf686, 0xf687, 0xf688, 0xf689, 0xf68a,
+ 0xf68b, 0xf68c, 0xf68d, 0xf68e, 0xf68f, 0xf690, 0xf691, 0xf692,
+ 0xf693, 0xf694, 0xf695, 0xf696, 0xf697, 0xf698, 0xf699, 0xf69a,
+ 0xf69b, 0xf69c, 0xf69d, 0xf69e, 0xf69f, 0xf6a0, 0xf740, 0xf741,
+ 0xf742, 0xf743, 0xf744, 0xf745, 0xf746, 0xf747, 0xf748, 0xf749,
+ 0xf74a, 0xf74b, 0xf74c, 0xf74d, 0xf74e, 0xf74f, 0xf750, 0xf751,
+ 0xf752, 0xf753, 0xf754, 0xf755, 0xf756, 0xf757, 0xf758, 0xf759,
+ 0xf75a, 0xf75b, 0xf75c, 0xf75d, 0xf75e, 0xf75f, 0xf760, 0xf761,
+ 0xf762, 0xf763, 0xf764, 0xf765, 0xf766, 0xf767, 0xf768, 0xf769,
+ 0xf76a, 0xf76b, 0xf76c, 0xf76d, 0xf76e, 0xf76f, 0xf770, 0xf771,
+ 0xf772, 0xf773, 0xf774, 0xf775, 0xf776, 0xf777, 0xf778, 0xf779,
+ 0xf77a, 0xf77b, 0xf77c, 0xf77d, 0xf77e, 0xf780, 0xf781, 0xf782,
+ 0xf783, 0xf784, 0xf785, 0xf786, 0xf787, 0xf788, 0xf789, 0xf78a,
+ 0xf78b, 0xf78c, 0xf78d, 0xf78e, 0xf78f, 0xf790, 0xf791, 0xf792,
+ 0xf793, 0xf794, 0xf795, 0xf796, 0xf797, 0xf798, 0xf799, 0xf79a,
+ 0xf79b, 0xf79c, 0xf79d, 0xf79e, 0xf79f, 0xf7a0, 0xf840, 0xf841,
+ 0xf842, 0xf843, 0xf844, 0xf845, 0xf846, 0xf847, 0xf848, 0xf849,
+ 0xf84a, 0xf84b, 0xf84c, 0xf84d, 0xf84e, 0xf84f, 0xf850, 0xf851,
+ 0xf852, 0xf853, 0xf854, 0xf855, 0xf856, 0xf857, 0xf858, 0xf859,
+ 0xf85a, 0xf85b, 0xf85c, 0xf85d, 0xf85e, 0xf85f, 0xf860, 0xf861,
+ 0xf862, 0xf863, 0xf864, 0xf865, 0xf866, 0xf867, 0xf868, 0xf869,
+ 0xf86a, 0xf86b, 0xf86c, 0xf86d, 0xf86e, 0xf86f, 0xf870, 0xf871,
+ 0xf872, 0xf873, 0xf874, 0xf875, 0xf876, 0xf877, 0xf878, 0xf879,
+ 0xf87a, 0xf87b, 0xf87c, 0xf87d, 0xf87e, 0xf880, 0xf881, 0xf882,
+ 0xf883, 0xf884, 0xf885, 0xf886, 0xf887, 0xf888, 0xf889, 0xf88a,
+ 0xf88b, 0xf88c, 0xf88d, 0xf88e, 0xf88f, 0xf890, 0xf891, 0xf892,
+ 0xf893, 0xf894, 0xf895, 0xf896, 0xf897, 0xf898, 0xf899, 0xf89a,
+ 0xf89b, 0xf89c, 0xf89d, 0xf89e, 0xf89f, 0xf8a0, 0xf940, 0xf941,
+ 0xf942, 0xf943, 0xf944, 0xf945, 0xf946, 0xf947, 0xf948, 0xf949,
+ 0xf94a, 0xf94b, 0xf94c, 0xf94d, 0xf94e, 0xf94f, 0xf950, 0xf951,
+ 0xf952, 0xf953, 0xf954, 0xf955, 0xf956, 0xf957, 0xf958, 0xf959,
+ 0xf95a, 0xf95b, 0xf95c, 0xf95d, 0xf95e, 0xf95f, 0xf960, 0xf961,
+ 0xf962, 0xf963, 0xf964, 0xf965, 0xf966, 0xf967, 0xf968, 0xf969,
+ 0xf96a, 0xf96b, 0xf96c, 0xf96d, 0xf96e, 0xf96f, 0xf970, 0xf971,
+ 0xf972, 0xf973, 0xf974, 0xf975, 0xf976, 0xf977, 0xf978, 0xf979,
+ 0xf97a, 0xf97b, 0xf97c, 0xf97d, 0xf97e, 0xf980, 0xf981, 0xf982,
+ 0xf983, 0xf984, 0xf985, 0xf986, 0xf987, 0xf988, 0xf989, 0xf98a,
+ 0xf98b, 0xf98c, 0xf98d, 0xf98e, 0xf98f, 0xf990, 0xf991, 0xf992,
+ 0xf993, 0xf994, 0xf995, 0xf996, 0xf997, 0xf998, 0xf999, 0xf99a,
+ 0xf99b, 0xf99c, 0xf99d, 0xf99e, 0xf99f, 0xf9a0, 0xfa40, 0xfa41,
+ 0xfa42, 0xfa43, 0xfa44, 0xfa45, 0xfa46, 0xfa47, 0xfa48, 0xfa49,
+ 0xfa4a, 0xfa4b, 0xfa4c, 0xfa4d, 0xfa4e, 0xfa4f, 0xfa50, 0xfa51,
+ 0xfa52, 0xfa53, 0xfa54, 0xfa55, 0xfa56, 0xfa57, 0xfa58, 0xfa59,
+ 0xfa5a, 0xfa5b, 0xfa5c, 0xfa5d, 0xfa5e, 0xfa5f, 0xfa60, 0xfa61,
+ 0xfa62, 0xfa63, 0xfa64, 0xfa65, 0xfa66, 0xfa67, 0xfa68, 0xfa69,
+ 0xfa6a, 0xfa6b, 0xfa6c, 0xfa6d, 0xfa6e, 0xfa6f, 0xfa70, 0xfa71,
+ 0xfa72, 0xfa73, 0xfa74, 0xfa75, 0xfa76, 0xfa77, 0xfa78, 0xfa79,
+ 0xfa7a, 0xfa7b, 0xfa7c, 0xfa7d, 0xfa7e, 0xfa80, 0xfa81, 0xfa82,
+ 0xfa83, 0xfa84, 0xfa85, 0xfa86, 0xfa87, 0xfa88, 0xfa89, 0xfa8a,
+ 0xfa8b, 0xfa8c, 0xfa8d, 0xfa8e, 0xfa8f, 0xfa90, 0xfa91, 0xfa92,
+ 0xfa93, 0xfa94, 0xfa95, 0xfa96, 0xfa97, 0xfa98, 0xfa99, 0xfa9a,
+ 0xfa9b, 0xfa9c, 0xfa9d, 0xfa9e, 0xfa9f, 0xfaa0, 0xfb40, 0xfb41,
+ 0xfb42, 0xfb43, 0xfb44, 0xfb45, 0xfb46, 0xfb47, 0xfb48, 0xfb49,
+ 0xfb4a, 0xfb4b, 0xfb4c, 0xfb4d, 0xfb4e, 0xfb4f, 0xfb50, 0xfb51,
+ 0xfb52, 0xfb53, 0xfb54, 0xfb55, 0xfb56, 0xfb57, 0xfb58, 0xfb59,
+ 0xfb5a, 0xfb5b, 0xfb5c, 0xfb5d, 0xfb5e, 0xfb5f, 0xfb60, 0xfb61,
+ 0xfb62, 0xfb63, 0xfb64, 0xfb65, 0xfb66, 0xfb67, 0xfb68, 0xfb69,
+ 0xfb6a, 0xfb6b, 0xfb6c, 0xfb6d, 0xfb6e, 0xfb6f, 0xfb70, 0xfb71,
+ 0xfb72, 0xfb73, 0xfb74, 0xfb75, 0xfb76, 0xfb77, 0xfb78, 0xfb79,
+ 0xfb7a, 0xfb7b, 0xfb7c, 0xfb7d, 0xfb7e, 0xfb80, 0xfb81, 0xfb82,
+ 0xfb83, 0xfb84, 0xfb85, 0xfb86, 0xfb87, 0xfb88, 0xfb89, 0xfb8a,
+ 0xfb8b, 0xfb8c, 0xfb8d, 0xfb8e, 0xfb8f, 0xfb90, 0xfb91, 0xfb92,
+ 0xfb93, 0xfb94, 0xfb95, 0xfb96, 0xfb97, 0xfb98, 0xfb99, 0xfb9a,
+ 0xfb9b, 0xfb9c, 0xfb9d, 0xfb9e, 0xfb9f, 0xfba0, 0xfc40, 0xfc41,
+ 0xfc42, 0xfc43, 0xfc44, 0xfc45, 0xfc46, 0xfc47, 0xfc48, 0xfc49,
+ 0xfc4a, 0xfc4b, 0xfc4c, 0xfc4d, 0xfc4e, 0xfc4f, 0xfc50, 0xfc51,
+ 0xfc52, 0xfc53, 0xfc54, 0xfc55, 0xfc56, 0xfc57, 0xfc58, 0xfc59,
+ 0xfc5a, 0xfc5b, 0xfc5c, 0xfc5d, 0xfc5e, 0xfc5f, 0xfc60, 0xfc61,
+ 0xfc62, 0xfc63, 0xfc64, 0xfc65, 0xfc66, 0xfc67, 0xfc68, 0xfc69,
+ 0xfc6a, 0xfc6b, 0xfc6c, 0xfc6d, 0xfc6e, 0xfc6f, 0xfc70, 0xfc71,
+ 0xfc72, 0xfc73, 0xfc74, 0xfc75, 0xfc76, 0xfc77, 0xfc78, 0xfc79,
+ 0xfc7a, 0xfc7b, 0xfc7c, 0xfc7d, 0xfc7e, 0xfc80, 0xfc81, 0xfc82,
+ 0xfc83, 0xfc84, 0xfc85, 0xfc86, 0xfc87, 0xfc88, 0xfc89, 0xfc8a,
+ 0xfc8b, 0xfc8c, 0xfc8d, 0xfc8e, 0xfc8f, 0xfc90, 0xfc91, 0xfc92,
+ 0xfc93, 0xfc94, 0xfc95, 0xfc96, 0xfc97, 0xfc98, 0xfc99, 0xfc9a,
+ 0xfc9b, 0xfc9c, 0xfc9d, 0xfc9e, 0xfc9f, 0xfca0, 0xfd40, 0xfd41,
+ 0xfd42, 0xfd43, 0xfd44, 0xfd45, 0xfd46, 0xfd47, 0xfd48, 0xfd49,
+ 0xfd4a, 0xfd4b, 0xfd4c, 0xfd4d, 0xfd4e, 0xfd4f, 0xfd50, 0xfd51,
+ 0xfd52, 0xfd53, 0xfd54, 0xfd55, 0xfd56, 0xfd57, 0xfd58, 0xfd59,
+ 0xfd5a, 0xfd5b, 0xfd5c, 0xfd5d, 0xfd5e, 0xfd5f, 0xfd60, 0xfd61,
+ 0xfd62, 0xfd63, 0xfd64, 0xfd65, 0xfd66, 0xfd67, 0xfd68, 0xfd69,
+ 0xfd6a, 0xfd6b, 0xfd6c, 0xfd6d, 0xfd6e, 0xfd6f, 0xfd70, 0xfd71,
+ 0xfd72, 0xfd73, 0xfd74, 0xfd75, 0xfd76, 0xfd77, 0xfd78, 0xfd79,
+ 0xfd7a, 0xfd7b, 0xfd7c, 0xfd7d, 0xfd7e, 0xfd80, 0xfd81, 0xfd82,
+ 0xfd83, 0xfd84, 0xfd85, 0xfd86, 0xfd87, 0xfd88, 0xfd89, 0xfd8a,
+ 0xfd8b, 0xfd8c, 0xfd8d, 0xfd8e, 0xfd8f, 0xfd90, 0xfd91, 0xfd92,
+ 0xfd93, 0xfd94, 0xfd95, 0xfd96, 0xfd97, 0xfd98, 0xfd99, 0xfd9a,
+ 0xfd9b, 0xfd9c, 0xfd9d, 0xfd9e, 0xfd9f, 0xfda0, 0xfe40, 0xfe41,
+ 0xfe42, 0xfe43, 0xfe44, 0xfe45, 0xfe46, 0xfe47, 0xfe48, 0xfe49,
+ 0xfe4a, 0xfe4b, 0xfe4c, 0xfe4d, 0xfe4e, 0xfe4f, 0xa955, 0xa968,
+ 0xa969, 0xa96a, 0xa96b, 0xa96c, 0xa96d, 0xa96e, 0xa96f, 0xa970,
+ 0xa971, 0xa972, 0xa973, 0xa974, 0xa975, 0xa976, 0xa977, 0xa978,
+ 0xa979, 0xa97a, 0xa97b, 0xa97c, 0xa97d, 0xa97e, 0xa980, 0xa981,
+ 0xa982, 0xa983, 0xa984, 0xa985, 0xa986, 0xa987, 0xa988, 0xa956,
+ 0xa957,
+};
+
+typedef struct {
+ unsigned short indx; /* index into big table */
+ unsigned short used; /* bitmask of used entries */
+} Summary16;
+
+static const Summary16 gbkext_inv_uni2indx_page02[14] = {
+ /* 0x0200 */
+ { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 },
+ { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 },
+ { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 },
+ { 0, 0x0c00 }, { 2, 0x0200 },
+};
+static const Summary16 gbkext_inv_uni2indx_page20[44] = {
+ /* 0x2000 */
+ { 3, 0x0000 }, { 3, 0x0029 }, { 6, 0x0020 }, { 7, 0x0020 },
+ { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 },
+ { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 },
+ { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 },
+ /* 0x2100 */
+ { 8, 0x0220 }, { 10, 0x0000 }, { 10, 0x0002 }, { 11, 0x0000 },
+ { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 },
+ { 11, 0x0000 }, { 11, 0x03c0 }, { 15, 0x0000 }, { 15, 0x0000 },
+ { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x0000 },
+ /* 0x2200 */
+ { 15, 0x0000 }, { 15, 0x8020 }, { 17, 0x0008 }, { 18, 0x0000 },
+ { 18, 0x0000 }, { 18, 0x0004 }, { 19, 0x00c0 }, { 21, 0x0000 },
+ { 21, 0x0000 }, { 21, 0x0020 }, { 22, 0x0000 }, { 22, 0x8000 },
+};
+static const Summary16 gbkext_inv_uni2indx_page25[17] = {
+ /* 0x2500 */
+ { 23, 0x0000 }, { 23, 0x0000 }, { 23, 0x0000 }, { 23, 0x0000 },
+ { 23, 0x0000 }, { 23, 0xffff }, { 39, 0xffff }, { 55, 0x000f },
+ { 59, 0xfffe }, { 74, 0x0038 }, { 77, 0x0000 }, { 77, 0x3000 },
+ { 79, 0x0000 }, { 79, 0x0000 }, { 79, 0x003c }, { 83, 0x0000 },
+ /* 0x2600 */
+ { 83, 0x0200 },
+};
+static const Summary16 gbkext_inv_uni2indx_page30[16] = {
+ /* 0x3000 */
+ { 84, 0x00c0 }, { 86, 0x6004 }, { 89, 0x03fe }, { 98, 0x0000 },
+ { 98, 0x0000 }, { 98, 0x0000 }, { 98, 0x0000 }, { 98, 0x0000 },
+ { 98, 0x0000 }, { 98, 0x7800 }, { 102, 0x0000 }, { 102, 0x0000 },
+ { 102, 0x0000 }, { 102, 0x0000 }, { 102, 0x0000 }, { 102, 0x7000 },
+};
+static const Summary16 gbkext_inv_uni2indx_page32[30] = {
+ /* 0x3200 */
+ { 105, 0x0000 }, { 105, 0x0000 }, { 105, 0x0000 }, { 105, 0x0002 },
+ { 106, 0x0000 }, { 106, 0x0000 }, { 106, 0x0000 }, { 106, 0x0000 },
+ { 106, 0x0000 }, { 106, 0x0000 }, { 106, 0x0008 }, { 107, 0x0000 },
+ { 107, 0x0000 }, { 107, 0x0000 }, { 107, 0x0000 }, { 107, 0x0000 },
+ /* 0x3300 */
+ { 107, 0x0000 }, { 107, 0x0000 }, { 107, 0x0000 }, { 107, 0x0000 },
+ { 107, 0x0000 }, { 107, 0x0000 }, { 107, 0x0000 }, { 107, 0x0000 },
+ { 107, 0xc000 }, { 109, 0x7000 }, { 112, 0x0002 }, { 113, 0x0000 },
+ { 113, 0x4010 }, { 115, 0x0026 },
+};
+static const Summary16 gbkext_inv_uni2indx_page4e[1307] = {
+ /* 0x4e00 */
+ { 118, 0x8074 }, { 123, 0x8084 }, { 126, 0xc24b }, { 133, 0x10aa },
+ { 138, 0x0457 }, { 144, 0x0ca2 }, { 149, 0xfdbc }, { 161, 0xbff4 },
+ { 173, 0x04bf }, { 181, 0x72c1 }, { 188, 0x8408 }, { 191, 0x73d3 },
+ { 201, 0x9100 }, { 204, 0x1c05 }, { 209, 0xe2c5 }, { 217, 0x5712 },
+ /* 0x4f00 */
+ { 224, 0x19fd }, { 234, 0x307c }, { 241, 0x730a }, { 248, 0xcaaa },
+ { 256, 0x1fb7 }, { 267, 0x0054 }, { 270, 0x6d46 }, { 278, 0x27a6 },
+ { 286, 0x54e7 }, { 295, 0xd76d }, { 306, 0x2816 }, { 311, 0x7fdf },
+ { 325, 0x3bc7 }, { 335, 0x0a7c }, { 342, 0x18b5 }, { 349, 0xbaf5 },
+ /* 0x5000 */
+ { 360, 0x4fff }, { 373, 0x68eb }, { 382, 0x889d }, { 389, 0xabff },
+ { 402, 0x2e77 }, { 412, 0xebdf }, { 425, 0xefdf }, { 439, 0x373f },
+ { 450, 0xdede }, { 462, 0xffff }, { 478, 0xec57 }, { 488, 0xf3fb },
+ { 501, 0x7fff }, { 516, 0xfbbf }, { 530, 0x8f3f }, { 541, 0xf7d7 },
+ /* 0x5100 */
+ { 554, 0xf73f }, { 567, 0xfffb }, { 582, 0xfffd }, { 597, 0x7fff },
+ { 612, 0xd484 }, { 618, 0xeb8d }, { 628, 0x86db }, { 637, 0xc404 },
+ { 641, 0xccd8 }, { 649, 0xe51b }, { 658, 0x67ca }, { 667, 0xc710 },
+ { 673, 0x652e }, { 681, 0xd7fd }, { 694, 0x57ec }, { 704, 0x4096 },
+ /* 0x5200 */
+ { 709, 0x9a30 }, { 715, 0xd039 }, { 722, 0x94ee }, { 731, 0x5036 },
+ { 737, 0xcbf0 }, { 746, 0xafac }, { 756, 0x795d }, { 766, 0x5ffb },
+ { 779, 0xfef9 }, { 792, 0x17f6 }, { 802, 0xc0f0 }, { 808, 0x3ff1 },
+ { 819, 0xf577 }, { 831, 0x7eba }, { 842, 0xffef }, { 857, 0x39fe },
+ /* 0x5300 */
+ { 868, 0x5e9e }, { 878, 0xd91e }, { 887, 0xbbb4 }, { 897, 0x31ff },
+ { 908, 0x3855 }, { 915, 0x2b11 }, { 921, 0x3520 }, { 926, 0x7a44 },
+ { 933, 0xc58b }, { 941, 0x5adf }, { 952, 0xbc93 }, { 961, 0x77bf },
+ { 974, 0xc0f9 }, { 982, 0x742d }, { 990, 0x0086 }, { 993, 0xc410 },
+ /* 0x5400 */
+ { 997, 0x08a5 }, { 1002, 0x1710 }, { 1007, 0x0434 }, { 1011, 0xa4c9 },
+ { 1018, 0xf2b6 }, { 1028, 0xe402 }, { 1033, 0xfeab }, { 1045, 0xc611 },
+ { 1051, 0x27aa }, { 1059, 0xd18a }, { 1066, 0x4027 }, { 1071, 0x56e5 },
+ { 1080, 0x0c28 }, { 1084, 0x0940 }, { 1087, 0x981f }, { 1095, 0x4bf3 },
+ /* 0x5500 */
+ { 1105, 0x7d3d }, { 1116, 0xf7ec }, { 1128, 0x2b62 }, { 1135, 0x2f74 },
+ { 1144, 0xf9a5 }, { 1154, 0xef9e }, { 1166, 0x8b0d }, { 1173, 0xa61f },
+ { 1182, 0x7060 }, { 1187, 0x4ced }, { 1196, 0xff7f }, { 1211, 0x9555 },
+ { 1219, 0xcdcf }, { 1230, 0x4fa1 }, { 1238, 0x6285 }, { 1244, 0x9f53 },
+ /* 0x5600 */
+ { 1254, 0x2cfc }, { 1263, 0x36ff }, { 1275, 0xcf67 }, { 1286, 0x75a9 },
+ { 1295, 0x8fff }, { 1308, 0xec6f }, { 1319, 0xe0eb }, { 1328, 0xe7bd },
+ { 1340, 0x3f9f }, { 1352, 0xfff7 }, { 1367, 0x7ff7 }, { 1381, 0xef7f },
+ { 1395, 0xfbff }, { 1410, 0x136f }, { 1419, 0xd7e8 }, { 1429, 0x19cc },
+ /* 0x5700 */
+ { 1436, 0xf8a7 }, { 1446, 0x6fff }, { 1460, 0x08f7 }, { 1468, 0xb1f6 },
+ { 1478, 0x0b7a }, { 1486, 0x037c }, { 1493, 0x50ac }, { 1499, 0xe737 },
+ { 1510, 0xe783 }, { 1519, 0xf7f3 }, { 1532, 0x9520 }, { 1537, 0xfeeb },
+ { 1550, 0x37f3 }, { 1561, 0x58cb }, { 1569, 0x5fee }, { 1581, 0xd8ef },
+ /* 0x5800 */
+ { 1592, 0xd73a }, { 1602, 0xbddd }, { 1614, 0xfbec }, { 1626, 0xffde },
+ { 1640, 0xcfef }, { 1653, 0xbeed }, { 1665, 0xe7df }, { 1678, 0xbfff },
+ { 1693, 0xfdd4 }, { 1704, 0x39f3 }, { 1714, 0xfcff }, { 1728, 0xefff },
+ { 1743, 0xffdd }, { 1757, 0xffdd }, { 1771, 0xa7ef }, { 1783, 0xfdb6 },
+ /* 0x5900 */
+ { 1795, 0x5f6b }, { 1806, 0x698f }, { 1815, 0x114f }, { 1822, 0xe86d },
+ { 1831, 0x3469 }, { 1838, 0xfa0d }, { 1847, 0xffda }, { 1860, 0xdca7 },
+ { 1870, 0xda21 }, { 1877, 0xbd33 }, { 1887, 0x30c7 }, { 1894, 0xb5fb },
+ { 1906, 0xf3bf }, { 1919, 0xca60 }, { 1925, 0xeed7 }, { 1937, 0x75ff },
+ /* 0x5a00 */
+ { 1950, 0xec05 }, { 1957, 0x6ef5 }, { 1968, 0xfdd6 }, { 1980, 0xefa9 },
+ { 1991, 0xf9be }, { 2003, 0xfbdf }, { 2017, 0xfb7b }, { 2030, 0x7b0f },
+ { 2040, 0xffff }, { 2056, 0xf3fb }, { 2069, 0xfbff }, { 2084, 0xbed3 },
+ { 2095, 0xedf9 }, { 2107, 0xeeab }, { 2118, 0xf5b4 }, { 2128, 0xfffd },
+ /* 0x5b00 */
+ { 2143, 0xfdff }, { 2158, 0xff3f }, { 2172, 0xffff }, { 2188, 0xff6b },
+ { 2201, 0xfffe }, { 2216, 0x4044 }, { 2219, 0xe983 }, { 2227, 0xdbd4 },
+ { 2237, 0x6444 }, { 2242, 0x8057 }, { 2248, 0xf380 }, { 2255, 0x1c86 },
+ { 2261, 0xef0b }, { 2271, 0x1ff2 }, { 2281, 0xbecd }, { 2292, 0x60fe },
+ /* 0x5c00 */
+ { 2301, 0x79ad }, { 2311, 0xca8d }, { 2319, 0xef4b }, { 2330, 0x00ed },
+ { 2336, 0x30d8 }, { 2342, 0xbddc }, { 2353, 0x3f94 }, { 2362, 0x79fd },
+ { 2374, 0xcef9 }, { 2385, 0xe02c }, { 2391, 0xc5f3 }, { 2401, 0x5e55 },
+ { 2410, 0xf7ed }, { 2423, 0xfdfb }, { 2437, 0xda8d }, { 2446, 0xf7fe },
+ /* 0x5d00 */
+ { 2460, 0xbf33 }, { 2471, 0xb7af }, { 2483, 0x9d2f }, { 2493, 0x9fef },
+ { 2506, 0xe37f }, { 2518, 0xd6ff }, { 2531, 0x65ff }, { 2543, 0xffef },
+ { 2558, 0xfffb }, { 2573, 0xddff }, { 2587, 0xffff }, { 2603, 0xff7f },
+ { 2618, 0xdfdf }, { 2632, 0x97ff }, { 2645, 0x3419 }, { 2651, 0x9f61 },
+ /* 0x5e00 */
+ { 2660, 0x6e91 }, { 2668, 0xc08c }, { 2673, 0x9f3f }, { 2685, 0xc67d },
+ { 2695, 0xefcb }, { 2707, 0xb7cf }, { 2719, 0xfff9 }, { 2733, 0x42a3 },
+ { 2739, 0x732e }, { 2748, 0x2904 }, { 2752, 0xdf1e }, { 2763, 0xbc17 },
+ { 2772, 0xf9ff }, { 2786, 0xf7b1 }, { 2797, 0xfaff }, { 2811, 0x3b2f },
+ /* 0x5f00 */
+ { 2821, 0x72e0 }, { 2828, 0x7655 }, { 2837, 0x591e }, { 2845, 0xe9fd },
+ { 2857, 0xfffe }, { 2872, 0xde12 }, { 2880, 0xc9a9 }, { 2888, 0xe574 },
+ { 2897, 0xe048 }, { 2902, 0xec5a }, { 2911, 0x9afd }, { 2922, 0xcf5f },
+ { 2934, 0x4d87 }, { 2942, 0xdc38 }, { 2950, 0x936c }, { 2958, 0x16dd },
+ /* 0x6000 */
+ { 2967, 0x1b80 }, { 2972, 0xc58b }, { 2980, 0x701c }, { 2986, 0x67df },
+ { 2998, 0xd7f1 }, { 3009, 0xd9da }, { 3019, 0x4063 }, { 3024, 0x40b6 },
+ { 3030, 0xcde7 }, { 3041, 0x53ab }, { 3050, 0x46b6 }, { 3058, 0xe6e9 },
+ { 3068, 0xf39f }, { 3080, 0x4add }, { 3089, 0x043e }, { 3095, 0xf9a6 },
+ /* 0x6100 */
+ { 3105, 0x1cbc }, { 3113, 0x7bdf }, { 3126, 0xf726 }, { 3136, 0x7fff },
+ { 3151, 0xaaff }, { 3163, 0xdfdd }, { 3176, 0xfe7b }, { 3189, 0xff5e },
+ { 3202, 0xb7ff }, { 3216, 0xdfef }, { 3230, 0xec7f }, { 3242, 0xbf7f },
+ { 3256, 0xf2fb }, { 3268, 0xffe9 }, { 3281, 0xffbf }, { 3296, 0x7fdf },
+ /* 0x6200 */
+ { 3310, 0x02bf }, { 3318, 0x7218 }, { 3324, 0xabc9 }, { 3333, 0x1f67 },
+ { 3343, 0x8474 }, { 3349, 0xf6e1 }, { 3359, 0x0137 }, { 3365, 0x2db6 },
+ { 3374, 0xf9ee }, { 3386, 0x7211 }, { 3392, 0xe6c8 }, { 3400, 0x45dd },
+ { 3409, 0x880b }, { 3414, 0x6022 }, { 3418, 0x0c13 }, { 3423, 0x0f25 },
+ /* 0x6300 */
+ { 3430, 0xbc79 }, { 3440, 0x13bd }, { 3449, 0x72c0 }, { 3455, 0xd9fb },
+ { 3467, 0x0593 }, { 3473, 0x3fde }, { 3485, 0x9d71 }, { 3494, 0xf33d },
+ { 3505, 0x287a }, { 3512, 0xfeba }, { 3524, 0x8852 }, { 3529, 0xaa66 },
+ { 3537, 0x1daf }, { 3547, 0xbfba }, { 3559, 0xd9f4 }, { 3569, 0x5eab },
+ /* 0x6400 */
+ { 3579, 0x67d8 }, { 3588, 0xa7e6 }, { 3598, 0xcbbc }, { 3608, 0x5bef },
+ { 3620, 0xfa0d }, { 3629, 0xbeeb }, { 3641, 0xdd7f }, { 3654, 0xf8ff },
+ { 3667, 0xff4b }, { 3679, 0xbd99 }, { 3689, 0x8def }, { 3700, 0xea5e },
+ { 3710, 0x9fda }, { 3721, 0xbe7a }, { 3732, 0xffab }, { 3745, 0xffff },
+ /* 0x6500 */
+ { 3761, 0xfdfe }, { 3775, 0xfefb }, { 3789, 0x37df }, { 3801, 0x348f },
+ { 3809, 0x6cdf }, { 3820, 0x959d }, { 3829, 0xe7b3 }, { 3840, 0xff6a },
+ { 3852, 0xe77f }, { 3865, 0x6574 }, { 3873, 0x554d }, { 3881, 0xcdfe },
+ { 3893, 0x2785 }, { 3900, 0xff3b }, { 3913, 0x0c1a }, { 3918, 0xfb3c },
+ /* 0x6600 */
+ { 3929, 0x2bb2 }, { 3937, 0x5dc7 }, { 3947, 0x5e5e }, { 3957, 0xaf8d },
+ { 3967, 0x67f5 }, { 3978, 0x7b03 }, { 3986, 0x3ead }, { 3996, 0xbb2e },
+ { 4006, 0xef6b }, { 4018, 0xdf3d }, { 4030, 0xbe7f }, { 4043, 0xbdef },
+ { 4056, 0xffff }, { 4072, 0xc5ff }, { 4084, 0xfdbf }, { 4098, 0x2d62 },
+ /* 0x6700 */
+ { 4105, 0xd0fe }, { 4115, 0x574e }, { 4124, 0x42bf }, { 4133, 0xdbcd },
+ { 4144, 0x2cb2 }, { 4151, 0x2fb4 }, { 4160, 0x58dc }, { 4168, 0x2f52 },
+ { 4176, 0xf56d }, { 4187, 0x8a5e }, { 4195, 0x5253 }, { 4202, 0xfe16 },
+ { 4212, 0x7fe5 }, { 4224, 0x88e0 }, { 4229, 0x6dda }, { 4239, 0x5fe4 },
+ /* 0x6800 */
+ { 4249, 0x205e }, { 4255, 0xdf35 }, { 4266, 0xf9fd }, { 4279, 0x8c73 },
+ { 4287, 0xa880 }, { 4291, 0xffc4 }, { 4302, 0xf400 }, { 4307, 0xff2f },
+ { 4320, 0x7f95 }, { 4331, 0xff77 }, { 4345, 0x5e3b }, { 4355, 0xffd6 },
+ { 4368, 0xd5fa }, { 4379, 0xfadb }, { 4391, 0xbff6 }, { 4404, 0xe9dc },
+ /* 0x6900 */
+ { 4414, 0x97dd }, { 4425, 0x7ffa }, { 4438, 0xdfee }, { 4451, 0x5dee },
+ { 4462, 0xfffb }, { 4477, 0x9b6f }, { 4488, 0xb7b6 }, { 4499, 0xec7d },
+ { 4510, 0xdc2a }, { 4518, 0xe6cf }, { 4529, 0xd67f }, { 4541, 0xf76d },
+ { 4553, 0xabfd }, { 4565, 0x77ee }, { 4577, 0xdffe }, { 4591, 0x5ffb },
+ /* 0x6a00 */
+ { 4604, 0xfbff }, { 4619, 0x7e7f }, { 4632, 0x7afd }, { 4644, 0x9fdd },
+ { 4656, 0xff6f }, { 4670, 0xf4fe }, { 4682, 0xffdd }, { 4696, 0xedfd },
+ { 4709, 0xbfee }, { 4722, 0xff7c }, { 4735, 0xe5fe }, { 4747, 0xffff },
+ { 4763, 0xffff }, { 4779, 0xffff }, { 4795, 0xffff }, { 4811, 0xffff },
+ /* 0x6b00 */
+ { 4827, 0xffff }, { 4843, 0xffff }, { 4859, 0xff60 }, { 4869, 0xb97b },
+ { 4880, 0xed37 }, { 4891, 0xfdff }, { 4906, 0xfb03 }, { 4915, 0xe5ff },
+ { 4928, 0xd121 }, { 4934, 0xf3b3 }, { 4945, 0xfbfd }, { 4959, 0x7f47 },
+ { 4970, 0x57d9 }, { 4980, 0xf503 }, { 4988, 0x73fd }, { 5000, 0xddd7 },
+ /* 0x6c00 */
+ { 5012, 0x5f1f }, { 5023, 0x7084 }, { 5028, 0x3829 }, { 5034, 0xdeca },
+ { 5044, 0xf938 }, { 5053, 0x074e }, { 5060, 0xf8ec }, { 5070, 0x9daa },
+ { 5079, 0x6c91 }, { 5086, 0x75e6 }, { 5096, 0x9105 }, { 5101, 0x04f1 },
+ { 5107, 0xe9cf }, { 5118, 0xb706 }, { 5126, 0x32d0 }, { 5132, 0x8214 },
+ /* 0x6d00 */
+ { 5136, 0xa76d }, { 5146, 0xb17b }, { 5156, 0xb35f }, { 5167, 0x85d1 },
+ { 5174, 0x1215 }, { 5179, 0xa9e1 }, { 5187, 0x39b6 }, { 5196, 0xee6f },
+ { 5208, 0xacdb }, { 5218, 0x17c5 }, { 5226, 0x3024 }, { 5230, 0x7edb },
+ { 5242, 0xe70e }, { 5251, 0x9cbd }, { 5261, 0xa7ac }, { 5270, 0xe575 },
+ /* 0x6e00 */
+ { 5280, 0x8bdf }, { 5291, 0xdb2c }, { 5300, 0x55c4 }, { 5307, 0xfaeb },
+ { 5319, 0x9fe7 }, { 5331, 0x76a7 }, { 5341, 0xb7ff }, { 5355, 0x3fff },
+ { 5369, 0x7d97 }, { 5380, 0x6efe }, { 5392, 0x7b5b }, { 5403, 0xd329 },
+ { 5411, 0x7779 }, { 5422, 0x3b45 }, { 5430, 0xfc88 }, { 5438, 0xfdef },
+ /* 0x6f00 */
+ { 5452, 0x7dbb }, { 5464, 0xffc7 }, { 5477, 0x51ee }, { 5486, 0xbfb5 },
+ { 5498, 0xd73f }, { 5510, 0xaeff }, { 5523, 0x9fbb }, { 5535, 0xeaeb },
+ { 5546, 0x8cef }, { 5556, 0xefff }, { 5571, 0xff7d }, { 5585, 0xfdb7 },
+ { 5598, 0xfdfa }, { 5611, 0xbff9 }, { 5624, 0x3ffc }, { 5636, 0xffff },
+ /* 0x7000 */
+ { 5652, 0xffff }, { 5668, 0xf3fd }, { 5681, 0xfff7 }, { 5696, 0xfddf },
+ { 5710, 0x6fff }, { 5724, 0xbfff }, { 5739, 0x47ff }, { 5751, 0x2e9e },
+ { 5760, 0xb9de }, { 5771, 0xcd8b }, { 5780, 0x07ff }, { 5791, 0xc475 },
+ { 5799, 0xfaf0 }, { 5809, 0x74ff }, { 5821, 0x442f }, { 5828, 0xdd7f },
+ /* 0x7100 */
+ { 5841, 0xf9ff }, { 5855, 0xf896 }, { 5864, 0x7fbf }, { 5878, 0xffbc },
+ { 5891, 0xabdf }, { 5903, 0xafff }, { 5917, 0xbe2f }, { 5928, 0xdaf3 },
+ { 5939, 0x7bef }, { 5952, 0x7cef }, { 5964, 0xeefe }, { 5977, 0xfdd7 },
+ { 5990, 0xbff7 }, { 6004, 0xffcf }, { 6018, 0xbf5e }, { 6030, 0xfdff },
+ /* 0x7200 */
+ { 6045, 0xffbf }, { 6060, 0xdfff }, { 6075, 0xeaff }, { 6088, 0x541c },
+ { 6094, 0xce7f }, { 6106, 0x55bb }, { 6116, 0x3d39 }, { 6125, 0x39db },
+ { 6135, 0x53ec }, { 6144, 0x7ffb }, { 6158, 0x4fff }, { 6171, 0xfc2e },
+ { 6181, 0x9ee1 }, { 6190, 0xbd7a }, { 6201, 0x0cfc }, { 6209, 0xe260 },
+ /* 0x7300 */
+ { 6215, 0xbbf5 }, { 6227, 0x8717 }, { 6235, 0xa1d9 }, { 6243, 0x3c6d },
+ { 6252, 0xdfff }, { 6267, 0xff7a }, { 6280, 0x4ffe }, { 6292, 0xbfff },
+ { 6307, 0xb56f }, { 6318, 0x77bd }, { 6330, 0x35fb }, { 6341, 0xf372 },
+ { 6351, 0x58fa }, { 6360, 0xbdfc }, { 6372, 0xdd5e }, { 6383, 0xfffb },
+ /* 0x7400 */
+ { 6398, 0x7997 }, { 6408, 0xf3fe }, { 6421, 0xaa9b }, { 6430, 0xef86 },
+ { 6440, 0xfffd }, { 6455, 0x215f }, { 6463, 0xdfff }, { 6478, 0xbf3e },
+ { 6490, 0xb774 }, { 6500, 0xaffe }, { 6513, 0xfc7f }, { 6526, 0xfbff },
+ { 6541, 0xffff }, { 6557, 0xaffb }, { 6570, 0x3fa2 }, { 6579, 0x7f2f },
+ /* 0x7500 */
+ { 6591, 0x5fef }, { 6604, 0x68f5 }, { 6613, 0x44df }, { 6622, 0xb250 },
+ { 6628, 0x26de }, { 6637, 0xe1ef }, { 6648, 0xfb9f }, { 6661, 0x7ceb },
+ { 6672, 0x77b7 }, { 6684, 0x5929 }, { 6691, 0x27c4 }, { 6698, 0x8cc0 },
+ { 6703, 0xd843 }, { 6710, 0xb68b }, { 6719, 0xf223 }, { 6727, 0x6dec },
+ /* 0x7600 */
+ { 6737, 0xebd4 }, { 6747, 0x745e }, { 6756, 0xd18a }, { 6763, 0x2ec6 },
+ { 6771, 0xcff6 }, { 6783, 0xafaf }, { 6795, 0x77f7 }, { 6808, 0x96ff },
+ { 6820, 0xb62b }, { 6829, 0xfdb5 }, { 6841, 0xbfef }, { 6855, 0x7fe9 },
+ { 6867, 0x1a9b }, { 6875, 0x7628 }, { 6882, 0x3fdf }, { 6895, 0xace9 },
+ /* 0x7700 */
+ { 6904, 0xd46d }, { 6913, 0x79ff }, { 6926, 0x5cba }, { 6935, 0xea1f },
+ { 6945, 0xff74 }, { 6957, 0xf3fc }, { 6969, 0xe691 }, { 6977, 0x1dff },
+ { 6989, 0x8fce }, { 6999, 0x7ff9 }, { 7012, 0xe95a }, { 7021, 0x57d6 },
+ { 7031, 0xdfff }, { 7046, 0xe77f }, { 7059, 0x8553 }, { 7066, 0x1eb7 },
+ /* 0x7800 */
+ { 7076, 0xcdf8 }, { 7086, 0x4a29 }, { 7092, 0xcd17 }, { 7101, 0xa06e },
+ { 7108, 0xaf5e }, { 7119, 0xdf1a }, { 7129, 0x83ff }, { 7140, 0xef7f },
+ { 7154, 0x8d7f }, { 7165, 0x6275 }, { 7173, 0xff55 }, { 7185, 0xbde0 },
+ { 7194, 0xf1dd }, { 7205, 0xfdce }, { 7217, 0xeeff }, { 7231, 0xfb6b },
+ /* 0x7900 */
+ { 7243, 0xffdd }, { 7257, 0xbff7 }, { 7271, 0xffef }, { 7286, 0xa3ef },
+ { 7297, 0xfcbc }, { 7308, 0x0337 }, { 7315, 0x5e5a }, { 7324, 0xfa7f },
+ { 7337, 0x7bcc }, { 7347, 0xfbff }, { 7362, 0xff7f }, { 7377, 0x91f7 },
+ { 7387, 0xd5b4 }, { 7396, 0x7ed9 }, { 7407, 0x5527 }, { 7415, 0xd6fe },
+ /* 0x7a00 */
+ { 7427, 0x97b2 }, { 7436, 0xbb6f }, { 7448, 0xfff6 }, { 7462, 0x4577 },
+ { 7471, 0xffbf }, { 7486, 0xff7d }, { 7500, 0xffff }, { 7516, 0x782e },
+ { 7524, 0xdea4 }, { 7533, 0x4e19 }, { 7540, 0xce9e }, { 7550, 0x7ff7 },
+ { 7564, 0xf7ff }, { 7579, 0x3dbf }, { 7591, 0x5f96 }, { 7601, 0x59ff },
+ /* 0x7b00 */
+ { 7613, 0x72a7 }, { 7622, 0xb5cd }, { 7632, 0xa28e }, { 7639, 0xaaf5 },
+ { 7649, 0x655f }, { 7659, 0xd2a8 }, { 7666, 0xbffa }, { 7679, 0xb559 },
+ { 7688, 0xdfde }, { 7701, 0xcf4e }, { 7711, 0xc039 }, { 7717, 0xfeed },
+ { 7730, 0xef3d }, { 7742, 0xd9f5 }, { 7753, 0xbb9d }, { 7764, 0xaf7d },
+ /* 0x7c00 */
+ { 7776, 0x677f }, { 7788, 0x7fbf }, { 7802, 0xfb3f }, { 7815, 0x7eff },
+ { 7829, 0xdffc }, { 7842, 0xffff }, { 7858, 0xffff }, { 7874, 0xc7e7 },
+ { 7885, 0xfdff }, { 7900, 0x0e59 }, { 7907, 0xbbcb }, { 7918, 0x8df1 },
+ { 7927, 0xca5d }, { 7936, 0x6d1f }, { 7946, 0x7efe }, { 7959, 0xf6ff },
+ /* 0x7d00 */
+ { 7973, 0xfbff }, { 7988, 0xffff }, { 8004, 0x777a }, { 8015, 0xffff },
+ { 8031, 0xffff }, { 8047, 0xffff }, { 8063, 0xbfff }, { 8078, 0xff7f },
+ { 8093, 0xffff }, { 8109, 0xffff }, { 8125, 0xbfbf }, { 8139, 0xffff },
+ { 8155, 0xffff }, { 8171, 0xffff }, { 8187, 0xffff }, { 8203, 0xffff },
+ /* 0x7e00 */
+ { 8219, 0xffff }, { 8235, 0xffff }, { 8251, 0xffff }, { 8267, 0xf7ff },
+ { 8282, 0xff7d }, { 8296, 0xffff }, { 8312, 0xffff }, { 8328, 0xffff },
+ { 8344, 0xfffb }, { 8359, 0x77ff }, { 8373, 0x4000 }, { 8374, 0x1810 },
+ { 8377, 0x0000 }, { 8377, 0x0040 }, { 8378, 0x1010 }, { 8380, 0x0200 },
+ /* 0x7f00 */
+ { 8381, 0x0400 }, { 8382, 0x4001 }, { 8384, 0x0000 }, { 8384, 0xfa80 },
+ { 8391, 0xffcb }, { 8404, 0x7a4c }, { 8412, 0xb8f9 }, { 8422, 0xbde9 },
+ { 8433, 0xabfd }, { 8445, 0x1bef }, { 8456, 0x7f6d }, { 8468, 0x4cfa },
+ { 8477, 0xabdd }, { 8488, 0x7ecf }, { 8500, 0xbd9c }, { 8510, 0xe7f4 },
+ /* 0x8000 */
+ { 8521, 0xc784 }, { 8528, 0xec0a }, { 8535, 0xf81a }, { 8543, 0x5615 },
+ { 8550, 0xc3b3 }, { 8559, 0xfaeb }, { 8571, 0xf9ff }, { 8585, 0x7ffd },
+ { 8599, 0xe526 }, { 8607, 0x42b7 }, { 8615, 0x11c8 }, { 8620, 0x0b69 },
+ { 8627, 0x8fa0 }, { 8634, 0x813f }, { 8642, 0x404d }, { 8647, 0xcaa0 },
+ /* 0x8100 */
+ { 8653, 0x19bb }, { 8662, 0xbaa0 }, { 8669, 0x6fff }, { 8683, 0xbeb9 },
+ { 8694, 0xe2bf }, { 8705, 0xf9c4 }, { 8714, 0x9d5e }, { 8724, 0x01ec },
+ { 8730, 0x7afa }, { 8741, 0xc6fd }, { 8752, 0xfab7 }, { 8764, 0xf3f7 },
+ { 8777, 0xebb0 }, { 8786, 0xffff }, { 8802, 0xcb77 }, { 8813, 0xa7e7 },
+ /* 0x8200 */
+ { 8824, 0xcf88 }, { 8832, 0x27ea }, { 8841, 0x42f1 }, { 8848, 0xb404 },
+ { 8853, 0x756f }, { 8864, 0x7aff }, { 8877, 0x3eff }, { 8890, 0x19e2 },
+ { 8897, 0x12eb }, { 8905, 0x4c79 }, { 8913, 0x008d }, { 8917, 0x9c64 },
+ { 8924, 0x026d }, { 8930, 0x2641 }, { 8935, 0x7784 }, { 8943, 0xf56d },
+ /* 0x8300 */
+ { 8954, 0x2c01 }, { 8958, 0xe34d }, { 8967, 0x467f }, { 8977, 0xe885 },
+ { 8984, 0x7d36 }, { 8994, 0x23e8 }, { 9001, 0x0004 }, { 9002, 0xc67f },
+ { 9013, 0xbd9f }, { 9025, 0xa6f3 }, { 9035, 0xf0fe }, { 9046, 0xc820 },
+ { 9050, 0x6b5c }, { 9059, 0x4eaf }, { 9069, 0xf9dc }, { 9080, 0xdcf8 },
+ /* 0x8400 */
+ { 9090, 0x07a5 }, { 9097, 0xcefd }, { 9109, 0xfe0f }, { 9120, 0xcefd },
+ { 9132, 0xffbf }, { 9147, 0xe17d }, { 9157, 0xc5f5 }, { 9167, 0xfa95 },
+ { 9177, 0xa47b }, { 9186, 0xed7f }, { 9199, 0x7ffd }, { 9213, 0x58eb },
+ { 9222, 0xd9ed }, { 9233, 0x5fb4 }, { 9243, 0xef96 }, { 9254, 0x6ffe },
+ /* 0x8500 */
+ { 9267, 0xefff }, { 9282, 0x7b75 }, { 9293, 0xe7fd }, { 9306, 0xc07f },
+ { 9315, 0xf8f7 }, { 9327, 0xbdbf }, { 9340, 0xfeef }, { 9354, 0xb1eb },
+ { 9364, 0x7f4f }, { 9376, 0xe7ff }, { 9390, 0x3aef }, { 9401, 0xfd7e },
+ { 9414, 0x7dfd }, { 9427, 0xefd6 }, { 9439, 0xfdef }, { 9453, 0x77ff },
+ /* 0x8600 */
+ { 9467, 0xffdf }, { 9482, 0xffbd }, { 9496, 0xfd7f }, { 9510, 0xeeff },
+ { 9524, 0x1fff }, { 9537, 0xbbec }, { 9548, 0xa7fb }, { 9560, 0x01fd },
+ { 9568, 0xc3f8 }, { 9577, 0xcfd7 }, { 9589, 0x6867 }, { 9597, 0xfb8c },
+ { 9607, 0x312e }, { 9614, 0x34ec }, { 9622, 0x9def }, { 9634, 0xbce0 },
+ /* 0x8700 */
+ { 9642, 0xd872 }, { 9650, 0xaa53 }, { 9658, 0xbdd1 }, { 9668, 0x376d },
+ { 9678, 0xac7f }, { 9689, 0xfd77 }, { 9702, 0xbfc6 }, { 9713, 0x87ae },
+ { 9722, 0xd6d3 }, { 9732, 0x7f77 }, { 9745, 0x46ff }, { 9756, 0xdbd7 },
+ { 9768, 0xf3be }, { 9780, 0xf7f1 }, { 9792, 0xbbde }, { 9804, 0xbdff },
+ /* 0x8800 */
+ { 9818, 0xfbf7 }, { 9832, 0xf797 }, { 9844, 0xfff9 }, { 9858, 0xedfb },
+ { 9871, 0xcfce }, { 9882, 0xfd6f }, { 9895, 0xa4c1 }, { 9901, 0x1f7a },
+ { 9911, 0xd6c9 }, { 9920, 0xefbb }, { 9933, 0xd7eb }, { 9945, 0xef7d },
+ { 9958, 0xbd99 }, { 9968, 0x7ccb }, { 9978, 0xfec3 }, { 9989, 0xace4 },
+ /* 0x8900 */
+ { 9997, 0xfbfb }, { 10011, 0xf1f2 }, { 10021, 0xf3dd }, { 10033, 0xffae },
+ { 10046, 0xffed }, { 10060, 0x3fff }, { 10074, 0xffbf }, { 10089, 0x77ff },
+ { 10103, 0xffb5 }, { 10116, 0xffff }, { 10132, 0xffff }, { 10148, 0xffff },
+ { 10164, 0x2009 }, { 10167, 0xabb8 }, { 10176, 0x7797 }, { 10187, 0xfff7 },
+ /* 0x8a00 */
+ { 10202, 0xff7e }, { 10216, 0xffff }, { 10232, 0xffff }, { 10248, 0xbfff },
+ { 10263, 0xfeff }, { 10278, 0xffff }, { 10294, 0xffff }, { 10310, 0xfdff },
+ { 10325, 0xf9ff }, { 10339, 0xfff7 }, { 10354, 0xffff }, { 10370, 0xffff },
+ { 10386, 0xffff }, { 10402, 0xffff }, { 10418, 0xffff }, { 10434, 0xffff },
+ /* 0x8b00 */
+ { 10450, 0xff7f }, { 10465, 0xffff }, { 10481, 0xffbf }, { 10496, 0xffff },
+ { 10512, 0xffff }, { 10528, 0xffff }, { 10544, 0xefbf }, { 10558, 0xffff },
+ { 10574, 0xffff }, { 10590, 0xffff }, { 10606, 0x1000 }, { 10607, 0x0802 },
+ { 10609, 0x0080 }, { 10610, 0x0001 }, { 10611, 0x0400 }, { 10612, 0x0000 },
+ /* 0x8c00 */
+ { 10612, 0x0200 }, { 10613, 0x4000 }, { 10614, 0x0000 }, { 10614, 0xff00 },
+ { 10622, 0xed3d }, { 10633, 0xfbdf }, { 10647, 0xf3f9 }, { 10659, 0xf8f7 },
+ { 10671, 0xe9db }, { 10682, 0xfeef }, { 10696, 0xffff }, { 10712, 0xffff },
+ { 10728, 0xffff }, { 10744, 0xffff }, { 10760, 0xffff }, { 10776, 0xffff },
+ /* 0x8d00 */
+ { 10792, 0xffff }, { 10808, 0x1fff }, { 10821, 0x0001 }, { 10822, 0x0000 },
+ { 10822, 0x0000 }, { 10822, 0x8086 }, { 10826, 0xd720 }, { 10833, 0xff06 },
+ { 10843, 0xf3cd }, { 10854, 0x7fed }, { 10867, 0xfff7 }, { 10882, 0x2ac5 },
+ { 10889, 0x27a7 }, { 10898, 0x133d }, { 10906, 0x62e7 }, { 10915, 0xd057 },
+ /* 0x8e00 */
+ { 10923, 0x69df }, { 10934, 0x1fef }, { 10946, 0x29f3 }, { 10955, 0xd9dd },
+ { 10966, 0xf068 }, { 10973, 0xfdf9 }, { 10986, 0x4dbf }, { 10997, 0x6faa },
+ { 11007, 0x7f5d }, { 11019, 0xafee }, { 11031, 0x67ff }, { 11044, 0xfbfb },
+ { 11058, 0xbfff }, { 11073, 0xffff }, { 11089, 0xffff }, { 11105, 0xffff },
+ /* 0x8f00 */
+ { 11121, 0xffff }, { 11137, 0xffff }, { 11153, 0xffff }, { 11169, 0xffff },
+ { 11185, 0xffff }, { 11201, 0xffff }, { 11217, 0x043f }, { 11224, 0x0000 },
+ { 11224, 0x1001 }, { 11226, 0x2004 }, { 11228, 0xf4f7 }, { 11240, 0x9dbc },
+ { 11250, 0xbe49 }, { 11259, 0x04c4 }, { 11263, 0x908b }, { 11269, 0xdc76 },
+ /* 0x9000 */
+ { 11279, 0x5180 }, { 11283, 0x1328 }, { 11288, 0x1fb8 }, { 11297, 0xa69f },
+ { 11307, 0x5f69 }, { 11317, 0xf670 }, { 11326, 0x9ed3 }, { 11336, 0x5fcf },
+ { 11348, 0xf6f2 }, { 11359, 0xd555 }, { 11368, 0x2bb1 }, { 11376, 0xb084 },
+ { 11381, 0x3b4d }, { 11390, 0xc774 }, { 11399, 0x5639 }, { 11407, 0x9eef },
+ /* 0x9100 */
+ { 11419, 0xffeb }, { 11433, 0xbdff }, { 11447, 0x7ff3 }, { 11460, 0xfdfd },
+ { 11474, 0x01b7 }, { 11481, 0x9b7a }, { 11491, 0x29c1 }, { 11497, 0x1c08 },
+ { 11501, 0xc55f }, { 11511, 0xf3f8 }, { 11522, 0x1bf3 }, { 11532, 0xfbcf },
+ { 11545, 0x097f }, { 11554, 0xeffd }, { 11568, 0xffff }, { 11584, 0xffff },
+ /* 0x9200 */
+ { 11600, 0xffff }, { 11616, 0xffff }, { 11632, 0xffff }, { 11648, 0xffff },
+ { 11664, 0xffff }, { 11680, 0xffff }, { 11696, 0xffff }, { 11712, 0xffef },
+ { 11727, 0xbfff }, { 11742, 0xffff }, { 11758, 0xbfff }, { 11773, 0xffff },
+ { 11789, 0xfeff }, { 11804, 0xffff }, { 11820, 0xffff }, { 11836, 0xffff },
+ /* 0x9300 */
+ { 11852, 0xffff }, { 11868, 0xffff }, { 11884, 0xffff }, { 11900, 0xbfff },
+ { 11915, 0xffff }, { 11931, 0xffff }, { 11947, 0xfbff }, { 11962, 0xffff },
+ { 11978, 0x7fff }, { 11993, 0xffff }, { 12009, 0xffff }, { 12025, 0xffff },
+ { 12041, 0xfbff }, { 12056, 0xffbf }, { 12071, 0xffff }, { 12087, 0xffff },
+ /* 0x9400 */
+ { 12103, 0xffff }, { 12119, 0xffff }, { 12135, 0xffff }, { 12151, 0xbfff },
+ { 12166, 0xffff }, { 12182, 0xffff }, { 12198, 0xf7ff }, { 12213, 0xffff },
+ { 12229, 0x001f }, { 12234, 0x0142 }, { 12237, 0x0000 }, { 12237, 0x0000 },
+ { 12237, 0x8080 }, { 12239, 0x0418 }, { 12242, 0x0040 }, { 12243, 0x0800 },
+ /* 0x9500 */
+ { 12244, 0x0000 }, { 12244, 0x1000 }, { 12245, 0x0081 }, { 12247, 0x2008 },
+ { 12249, 0x0908 }, { 12252, 0x0420 }, { 12254, 0x4001 }, { 12256, 0x7fb0 },
+ { 12266, 0xffff }, { 12282, 0xffff }, { 12298, 0xffff }, { 12314, 0xffff },
+ { 12330, 0xffff }, { 12346, 0xffff }, { 12362, 0x10ff }, { 12371, 0x8000 },
+ /* 0x9600 */
+ { 12372, 0x0080 }, { 12373, 0x4908 }, { 12377, 0xbbf9 }, { 12389, 0x4781 },
+ { 12395, 0xc40a }, { 12400, 0x77ce }, { 12411, 0xe869 }, { 12419, 0xff0b },
+ { 12430, 0x569f }, { 12440, 0xec6e }, { 12450, 0xff7f }, { 12465, 0x8db6 },
+ { 12474, 0x0d0c }, { 12479, 0xffdb }, { 12493, 0x78fe }, { 12504, 0xbd37 },
+ /* 0x9700 */
+ { 12515, 0x1c2c }, { 12521, 0xafb7 }, { 12533, 0xdbff }, { 12547, 0xbcfa },
+ { 12558, 0xffff }, { 12574, 0xb5b3 }, { 12584, 0xfdd8 }, { 12595, 0xefa7 },
+ { 12607, 0xd7df }, { 12620, 0xfee9 }, { 12632, 0x57f6 }, { 12643, 0xffeb },
+ { 12657, 0xffff }, { 12673, 0xffff }, { 12689, 0xc13f }, { 12698, 0xff97 },
+ /* 0x9800 */
+ { 12711, 0xffff }, { 12727, 0xffff }, { 12743, 0xffff }, { 12759, 0xffff },
+ { 12775, 0xffff }, { 12791, 0xffff }, { 12807, 0xffff }, { 12823, 0x001f },
+ { 12828, 0x4800 }, { 12830, 0x0224 }, { 12833, 0xff08 }, { 12842, 0xffff },
+ { 12858, 0xbfff }, { 12873, 0x38d1 }, { 12880, 0xfe7f }, { 12894, 0xffff },
+ /* 0x9900 */
+ { 12910, 0xdfff }, { 12925, 0xfffe }, { 12940, 0xbfff }, { 12955, 0xffff },
+ { 12971, 0xffff }, { 12987, 0xffcf }, { 13001, 0x0057 }, { 13006, 0x4b08 },
+ { 13011, 0x520c }, { 13016, 0xfc00 }, { 13022, 0xfedf }, { 13036, 0xffff },
+ { 13052, 0xffff }, { 13068, 0xffff }, { 13084, 0xffff }, { 13100, 0xffff },
+ /* 0x9a00 */
+ { 13116, 0xffff }, { 13132, 0xffff }, { 13148, 0xffff }, { 13164, 0xffff },
+ { 13180, 0xffff }, { 13196, 0xffff }, { 13212, 0x0fff }, { 13224, 0x0004 },
+ { 13225, 0x6208 }, { 13229, 0x0230 }, { 13232, 0xfe40 }, { 13240, 0xea3c },
+ { 13249, 0xe7d8 }, { 13259, 0x7ef5 }, { 13271, 0x57bd }, { 13282, 0xf5ff },
+ /* 0x9b00 */
+ { 13296, 0x7ef7 }, { 13309, 0x7ff7 }, { 13323, 0x7ff7 }, { 13337, 0xe7fb },
+ { 13350, 0x5c41 }, { 13356, 0xffed }, { 13370, 0xffff }, { 13386, 0xffff },
+ { 13402, 0xffff }, { 13418, 0xffff }, { 13434, 0xffff }, { 13450, 0xffff },
+ { 13466, 0xffff }, { 13482, 0xffff }, { 13498, 0xffff }, { 13514, 0xffff },
+ /* 0x9c00 */
+ { 13530, 0xffff }, { 13546, 0xffff }, { 13562, 0xffff }, { 13578, 0xffff },
+ { 13594, 0xffff }, { 13610, 0xffff }, { 13626, 0xffff }, { 13642, 0x6fff },
+ { 13656, 0x9619 }, { 13663, 0x23c8 }, { 13669, 0x9400 }, { 13672, 0xc200 },
+ { 13675, 0x0307 }, { 13680, 0x0c06 }, { 13684, 0xfffb }, { 13699, 0xffff },
+ /* 0x9d00 */
+ { 13715, 0xffff }, { 13731, 0xffff }, { 13747, 0xffff }, { 13763, 0xffff },
+ { 13779, 0xffff }, { 13795, 0xffff }, { 13811, 0xffff }, { 13827, 0xffff },
+ { 13843, 0xffff }, { 13859, 0xffff }, { 13875, 0xffff }, { 13891, 0xffff },
+ { 13907, 0xffff }, { 13923, 0xffff }, { 13939, 0xffff }, { 13955, 0xffff },
+ /* 0x9e00 */
+ { 13971, 0xffff }, { 13987, 0x7fff }, { 14002, 0x4090 }, { 14005, 0x1811 },
+ { 14009, 0x2001 }, { 14011, 0xa25d }, { 14019, 0xc027 }, { 14025, 0x3ff4 },
+ { 14036, 0xf67b }, { 14048, 0x5ff3 }, { 14060, 0xffbf }, { 14075, 0x96ef },
+ { 14086, 0x1def }, { 14097, 0x46ed }, { 14106, 0x795a }, { 14115, 0xa5ff },
+ /* 0x9f00 */
+ { 14127, 0x97ff }, { 14140, 0xfd76 }, { 14152, 0x6ffa }, { 14164, 0x957f },
+ { 14175, 0xffef }, { 14190, 0xfffc }, { 14204, 0xffff }, { 14220, 0x7fff },
+ { 14235, 0xe006 }, { 14240, 0x71ff }, { 14252, 0x003e },
+};
+static const Summary16 gbkext_inv_uni2indx_pagef9[19] = {
+ /* 0xf900 */
+ { 14257, 0x0000 }, { 14257, 0x0000 }, { 14257, 0x1000 }, { 14258, 0x0000 },
+ { 14258, 0x0000 }, { 14258, 0x0000 }, { 14258, 0x0000 }, { 14258, 0x0200 },
+ { 14259, 0x0000 }, { 14259, 0x0020 }, { 14260, 0x0000 }, { 14260, 0x0000 },
+ { 14260, 0x0000 }, { 14260, 0x0000 }, { 14260, 0x0080 }, { 14261, 0x0002 },
+ /* 0xfa00 */
+ { 14262, 0xf000 }, { 14266, 0x811a }, { 14271, 0x039b },
+};
+static const Summary16 gbkext_inv_uni2indx_pagefe[31] = {
+ /* 0xfe00 */
+ { 14278, 0x0000 }, { 14278, 0x0000 }, { 14278, 0x0000 }, { 14278, 0x0001 },
+ { 14279, 0xfe00 }, { 14286, 0xfef7 }, { 14300, 0x0f7f }, { 14311, 0x0000 },
+ { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 },
+ { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 },
+ /* 0xff00 */
+ { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 },
+ { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 },
+ { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 },
+ { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0014 },
+};
+
+static int gbkext_inv_wctomb(unsigned int* r, unsigned int wc) {
+ const Summary16 *summary = NULL;
+ if (wc >= 0x0200 && wc < 0x02e0) {
+ summary = &gbkext_inv_uni2indx_page02[(wc>>4)-0x020];
+ } else if (wc >= 0x2000 && wc < 0x22c0) {
+ summary = &gbkext_inv_uni2indx_page20[(wc>>4)-0x200];
+ } else if (wc >= 0x2500 && wc < 0x2610) {
+ summary = &gbkext_inv_uni2indx_page25[(wc>>4)-0x250];
+ } else if (wc >= 0x3000 && wc < 0x3100) {
+ summary = &gbkext_inv_uni2indx_page30[(wc>>4)-0x300];
+ } else if (wc >= 0x3200 && wc < 0x33e0) {
+ summary = &gbkext_inv_uni2indx_page32[(wc>>4)-0x320];
+ } else if (wc >= 0x4e00 && wc < 0x9fb0) {
+ summary = &gbkext_inv_uni2indx_page4e[(wc>>4)-0x4e0];
+ } else if (wc >= 0xf900 && wc < 0xfa30) {
+ summary = &gbkext_inv_uni2indx_pagef9[(wc>>4)-0xf90];
+ } else if (wc >= 0xfe00 && wc < 0xfff0) {
+ summary = &gbkext_inv_uni2indx_pagefe[(wc>>4)-0xfe0];
+ }
+ if (summary) {
+ unsigned short used = summary->used;
+ unsigned int i = wc & 0x0f;
+ if (used & ((unsigned short) 1 << i)) {
+ /* Keep in 'used' only the bits 0..i-1. */
+ used &= ((unsigned short) 1 << i) - 1;
+ /* Add 'summary->indx' and the number of bits set in 'used'. */
+ used = (used & 0x5555) + ((used & 0xaaaa) >> 1);
+ used = (used & 0x3333) + ((used & 0xcccc) >> 2);
+ used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4);
+ used = (used & 0x00ff) + (used >> 8);
+ *r = gbkext_inv_2charset[summary->indx + used];
+ return 2;
+ }
+ }
+ return 0;
+}
+
+/*
+ * GBK (libiconv-1.16/lib/gbk.h)
+ */
+
+static int gbk_wctomb(unsigned int* r, unsigned int wc) {
+ int ret;
+
+ /* ZINT: Note these mappings U+30FB and U+2015 different from GB 2312 */
+ if (wc != 0x30fb && wc != 0x2015) {
+ ret = gb2312_wctomb_zint(r, wc); /* In gb2312.c */
+ if (ret) {
+ return ret;
+ }
+ }
+ ret = gbkext_inv_wctomb(r, wc);
+ if (ret) {
+ return ret;
+ }
+ if (wc >= 0x2170 && wc <= 0x2179) {
+ *r = 0xa2a1 + (wc-0x2170);
+ return 2;
+ }
+ ret = cp936ext_wctomb(r, wc);
+ if (ret) {
+ return ret;
+ }
+ /* ZINT: gb2312_wctomb_zint() is patched to map U+00B7 to 0xA1A4 and U+2014 to 0xA1AA */
+
+ return 0;
+}
+
+/*
+ * GB18030 two-byte extension (libiconv-1.16/lib/gb18030ext.h)
+ */
+
+static const unsigned short gb18030ext_page2e[80] = {
+ 0x0000, 0xfe50, 0x0000, 0x0000, 0xfe54, 0x0000, 0x0000, 0x0000, /*0x80-0x87*/
+ 0xfe57, 0x0000, 0x0000, 0xfe58, 0xfe5d, 0x0000, 0x0000, 0x0000, /*0x88-0x8f*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe5e, /*0x90-0x97*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x98-0x9f*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe6b, /*0xa0-0xa7*/
+ 0x0000, 0x0000, 0xfe6e, 0x0000, 0x0000, 0x0000, 0xfe71, 0x0000, /*0xa8-0xaf*/
+ 0x0000, 0x0000, 0x0000, 0xfe73, 0x0000, 0x0000, 0xfe74, 0xfe75, /*0xb0-0xb7*/
+ 0x0000, 0x0000, 0x0000, 0xfe79, 0x0000, 0x0000, 0x0000, 0x0000, /*0xb8-0xbf*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xc0-0xc7*/
+ 0x0000, 0x0000, 0xfe84, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xc8-0xcf*/
+};
+static const unsigned short gb18030ext_page2f[16] = {
+ 0xa98a, 0xa98b, 0xa98c, 0xa98d, 0xa98e, 0xa98f, 0xa990, 0xa991, /*0xf0-0xf7*/
+ 0xa992, 0xa993, 0xa994, 0xa995, 0x0000, 0x0000, 0x0000, 0x0000, /*0xf8-0xff*/
+};
+static const unsigned short gb18030ext_page34[56] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe56, /*0x40-0x47*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x48-0x4f*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x50-0x57*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x58-0x5f*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x60-0x67*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x68-0x6f*/
+ 0x0000, 0x0000, 0x0000, 0xfe55, 0x0000, 0x0000, 0x0000, 0x0000, /*0x70-0x77*/
+};
+static const unsigned short gb18030ext_page36[24] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe5c, 0x0000, /*0x08-0x0f*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x10-0x17*/
+ 0x0000, 0x0000, 0xfe5b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x18-0x1f*/
+};
+static const unsigned short gb18030ext_page39[24] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe62, /*0xc8-0xcf*/
+ 0xfe65, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xd0-0xd7*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe63, /*0xd8-0xdf*/
+};
+static const unsigned short gb18030ext_page43[56] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xfe78, 0x0000, 0x0000, 0x0000, /*0xa8-0xaf*/
+ 0x0000, 0xfe77, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xb0-0xb7*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xb8-0xbf*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xc0-0xc7*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xc8-0xcf*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xd0-0xd7*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe7a, 0x0000, 0x0000, /*0xd8-0xdf*/
+};
+static const unsigned short gb18030ext_page46[32] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xfe7d, 0x0000, 0x0000, 0x0000, /*0x48-0x4f*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x50-0x57*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x58-0x5f*/
+ 0x0000, 0xfe7c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x60-0x67*/
+};
+static const unsigned short gb18030ext_page47_1[16] = {
+ 0x0000, 0x0000, 0x0000, 0xfe80, 0x0000, 0x0000, 0x0000, 0x0000, /*0x20-0x27*/
+ 0x0000, 0xfe81, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x28-0x2f*/
+};
+static const unsigned short gb18030ext_page47_2[24] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xfe82, 0x0000, 0x0000, 0x0000, /*0x78-0x7f*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x80-0x87*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe83, 0x0000, 0x0000, /*0x88-0x8f*/
+};
+static const unsigned short gb18030ext_page49[120] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe85, /*0x40-0x47*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x48-0x4f*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x50-0x57*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x58-0x5f*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x60-0x67*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x68-0x6f*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x70-0x77*/
+ 0x0000, 0x0000, 0xfe86, 0x0000, 0x0000, 0xfe87, 0x0000, 0x0000, /*0x78-0x7f*/
+ 0x0000, 0x0000, 0xfe88, 0xfe89, 0x0000, 0xfe8a, 0xfe8b, 0x0000, /*0x80-0x87*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x88-0x8f*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x90-0x97*/
+ 0x0000, 0x0000, 0x0000, 0xfe8d, 0x0000, 0x0000, 0x0000, 0xfe8c, /*0x98-0x9f*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xa0-0xa7*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xa8-0xaf*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe8f, 0xfe8e, /*0xb0-0xb7*/
+};
+static const unsigned short gb18030ext_page4c[56] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe96, /*0x70-0x77*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x78-0x7f*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x80-0x87*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x88-0x8f*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x90-0x97*/
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe93, /*0x98-0x9f*/
+ 0xfe94, 0xfe95, 0xfe97, 0xfe92, 0x0000, 0x0000, 0x0000, 0x0000, /*0xa0-0xa7*/
+};
+static const unsigned short gb18030ext_page4d[16] = {
+ 0x0000, 0x0000, 0x0000, 0xfe98, 0xfe99, 0xfe9a, 0xfe9b, 0xfe9c, /*0x10-0x17*/
+ 0xfe9d, 0xfe9e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x18-0x1f*/
+};
+static const unsigned short gb18030ext_page9f[16] = {
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xfe59, 0xfe61, 0xfe66, 0xfe67, /*0xb0-0xb7*/
+ 0xfe6d, 0xfe7e, 0xfe90, 0xfea0, 0x0000, 0x0000, 0x0000, 0x0000, /*0xb8-0xbf*/
+};
+static const unsigned short gb18030ext_pagefe[16] = {
+ 0xa6d9, 0xa6db, 0xa6da, 0xa6dc, 0xa6dd, 0xa6de, 0xa6df, 0xa6ec, /*0x10-0x17*/
+ 0xa6ed, 0xa6f3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x18-0x1f*/
+};
+
+static int gb18030ext_wctomb(unsigned int* r, unsigned int wc) {
+ unsigned short c = 0;
+ if (wc == 0x01f9) {
+ c = 0xa8bf;
+ } else if (wc == 0x1e3f) {
+ c = 0xa8bc;
+ } else if (wc == 0x20ac) {
+ c = 0xa2e3;
+ } else if (wc >= 0x2e80 && wc < 0x2ed0) {
+ c = gb18030ext_page2e[wc-0x2e80];
+ } else if (wc >= 0x2ff0 && wc < 0x3000) {
+ c = gb18030ext_page2f[wc-0x2ff0];
+ } else if (wc == 0x303e) {
+ c = 0xa989;
+ } else if (wc >= 0x3440 && wc < 0x3478) {
+ c = gb18030ext_page34[wc-0x3440];
+ } else if (wc == 0x359e) {
+ c = 0xfe5a;
+ } else if (wc >= 0x3608 && wc < 0x3620) {
+ c = gb18030ext_page36[wc-0x3608];
+ } else if (wc == 0x3918) {
+ c = 0xfe60;
+ } else if (wc == 0x396e) {
+ c = 0xfe5f;
+ } else if (wc >= 0x39c8 && wc < 0x39e0) {
+ c = gb18030ext_page39[wc-0x39c8];
+ } else if (wc == 0x3a73) {
+ c = 0xfe64;
+ } else if (wc == 0x3b4e) {
+ c = 0xfe68;
+ } else if (wc == 0x3c6e) {
+ c = 0xfe69;
+ } else if (wc == 0x3ce0) {
+ c = 0xfe6a;
+ } else if (wc == 0x4056) {
+ c = 0xfe6f;
+ } else if (wc == 0x415f) {
+ c = 0xfe70;
+ } else if (wc == 0x4337) {
+ c = 0xfe72;
+ } else if (wc >= 0x43a8 && wc < 0x43e0) {
+ c = gb18030ext_page43[wc-0x43a8];
+ } else if (wc == 0x44d6) {
+ c = 0xfe7b;
+ } else if (wc >= 0x4648 && wc < 0x4668) {
+ c = gb18030ext_page46[wc-0x4648];
+ } else if (wc >= 0x4720 && wc < 0x4730) {
+ c = gb18030ext_page47_1[wc-0x4720];
+ } else if (wc >= 0x4778 && wc < 0x4790) {
+ c = gb18030ext_page47_2[wc-0x4778];
+ } else if (wc >= 0x4940 && wc < 0x49b8) {
+ c = gb18030ext_page49[wc-0x4940];
+ } else if (wc >= 0x4c70 && wc < 0x4ca8) {
+ c = gb18030ext_page4c[wc-0x4c70];
+ } else if (wc >= 0x4d10 && wc < 0x4d20) {
+ c = gb18030ext_page4d[wc-0x4d10];
+ } else if (wc == 0x4dae) {
+ c = 0xfe9f;
+ } else if (wc >= 0x9fb4 && wc < 0x9fbc) {
+ c = gb18030ext_page9f[wc-0x9fb0];
+ } else if (wc >= 0xfe10 && wc < 0xfe1a) {
+ c = gb18030ext_pagefe[wc-0xfe10];
+ } else if (wc == 0x20087) {
+ c = 0xfe51;
+ } else if (wc == 0x20089) {
+ c = 0xfe52;
+ } else if (wc == 0x200cc) {
+ c = 0xfe53;
+ } else if (wc == 0x215d7) {
+ c = 0xfe6c;
+ } else if (wc == 0x2298f) {
+ c = 0xfe76;
+ } else if (wc == 0x241fe) {
+ c = 0xfe91;
+ }
+ if (c != 0) {
+ *r = c;
+ return 2;
+ }
+ return 0;
+}
+
+/*
+ * GB18030 four-byte extension (libiconv-1.16/lib/gb18030uni.h)
+ */
+
+static const unsigned short gb18030uni_uni2charset_ranges[412] = {
+ 0x0080, 0x00a3, 0x00a5, 0x00a6, 0x00a9, 0x00af, 0x00b2, 0x00b6,
+ 0x00b8, 0x00d6, 0x00d8, 0x00df, 0x00e2, 0x00e7, 0x00eb, 0x00eb,
+ 0x00ee, 0x00f1, 0x00f4, 0x00f6, 0x00f8, 0x00f8, 0x00fb, 0x00fb,
+ 0x00fd, 0x0100, 0x0102, 0x0112, 0x0114, 0x011a, 0x011c, 0x012a,
+ 0x012c, 0x0143, 0x0145, 0x0147, 0x0149, 0x014c, 0x014e, 0x016a,
+ 0x016c, 0x01cd, 0x01cf, 0x01cf, 0x01d1, 0x01d1, 0x01d3, 0x01d3,
+ 0x01d5, 0x01d5, 0x01d7, 0x01d7, 0x01d9, 0x01d9, 0x01db, 0x01db,
+ 0x01dd, 0x01f8, 0x01fa, 0x0250, 0x0252, 0x0260, 0x0262, 0x02c6,
+ 0x02c8, 0x02c8, 0x02cc, 0x02d8, 0x02da, 0x0390, 0x03a2, 0x03a2,
+ 0x03aa, 0x03b0, 0x03c2, 0x03c2, 0x03ca, 0x0400, 0x0402, 0x040f,
+ 0x0450, 0x0450, 0x0452, 0x200f, 0x2011, 0x2012, 0x2017, 0x2017,
+ 0x201a, 0x201b, 0x201e, 0x2024, 0x2027, 0x202f, 0x2031, 0x2031,
+ 0x2034, 0x2034, 0x2036, 0x203a, 0x203c, 0x20ab, 0x20ad, 0x2102,
+ 0x2104, 0x2104, 0x2106, 0x2108, 0x210a, 0x2115, 0x2117, 0x2120,
+ 0x2122, 0x215f, 0x216c, 0x216f, 0x217a, 0x218f, 0x2194, 0x2195,
+ 0x219a, 0x2207, 0x2209, 0x220e, 0x2210, 0x2210, 0x2212, 0x2214,
+ 0x2216, 0x2219, 0x221b, 0x221c, 0x2221, 0x2222, 0x2224, 0x2224,
+ 0x2226, 0x2226, 0x222c, 0x222d, 0x222f, 0x2233, 0x2238, 0x223c,
+ 0x223e, 0x2247, 0x2249, 0x224b, 0x224d, 0x2251, 0x2253, 0x225f,
+ 0x2262, 0x2263, 0x2268, 0x226d, 0x2270, 0x2294, 0x2296, 0x2298,
+ 0x229a, 0x22a4, 0x22a6, 0x22be, 0x22c0, 0x2311, 0x2313, 0x245f,
+ 0x246a, 0x2473, 0x249c, 0x24ff, 0x254c, 0x254f, 0x2574, 0x2580,
+ 0x2590, 0x2592, 0x2596, 0x259f, 0x25a2, 0x25b1, 0x25b4, 0x25bb,
+ 0x25be, 0x25c5, 0x25c8, 0x25ca, 0x25cc, 0x25cd, 0x25d0, 0x25e1,
+ 0x25e6, 0x2604, 0x2607, 0x2608, 0x260a, 0x263f, 0x2641, 0x2641,
+ 0x2643, 0x2e80, 0x2e82, 0x2e83, 0x2e85, 0x2e87, 0x2e89, 0x2e8a,
+ 0x2e8d, 0x2e96, 0x2e98, 0x2ea6, 0x2ea8, 0x2ea9, 0x2eab, 0x2ead,
+ 0x2eaf, 0x2eb2, 0x2eb4, 0x2eb5, 0x2eb8, 0x2eba, 0x2ebc, 0x2ec9,
+ 0x2ecb, 0x2fef, 0x2ffc, 0x2fff, 0x3004, 0x3004, 0x3018, 0x301c,
+ 0x301f, 0x3020, 0x302a, 0x303d, 0x303f, 0x3040, 0x3094, 0x309a,
+ 0x309f, 0x30a0, 0x30f7, 0x30fb, 0x30ff, 0x3104, 0x312a, 0x321f,
+ 0x322a, 0x3230, 0x3232, 0x32a2, 0x32a4, 0x338d, 0x3390, 0x339b,
+ 0x339f, 0x33a0, 0x33a2, 0x33c3, 0x33c5, 0x33cd, 0x33cf, 0x33d0,
+ 0x33d3, 0x33d4, 0x33d6, 0x3446, 0x3448, 0x3472, 0x3474, 0x359d,
+ 0x359f, 0x360d, 0x360f, 0x3619, 0x361b, 0x3917, 0x3919, 0x396d,
+ 0x396f, 0x39ce, 0x39d1, 0x39de, 0x39e0, 0x3a72, 0x3a74, 0x3b4d,
+ 0x3b4f, 0x3c6d, 0x3c6f, 0x3cdf, 0x3ce1, 0x4055, 0x4057, 0x415e,
+ 0x4160, 0x4336, 0x4338, 0x43ab, 0x43ad, 0x43b0, 0x43b2, 0x43dc,
+ 0x43de, 0x44d5, 0x44d7, 0x464b, 0x464d, 0x4660, 0x4662, 0x4722,
+ 0x4724, 0x4728, 0x472a, 0x477b, 0x477d, 0x478c, 0x478e, 0x4946,
+ 0x4948, 0x4979, 0x497b, 0x497c, 0x497e, 0x4981, 0x4984, 0x4984,
+ 0x4987, 0x499a, 0x499c, 0x499e, 0x49a0, 0x49b5, 0x49b8, 0x4c76,
+ 0x4c78, 0x4c9e, 0x4ca4, 0x4d12, 0x4d1a, 0x4dad, 0x4daf, 0x4dff,
+ 0x9fa6, 0xd7ff,
+ 0xe76c, 0xe76c, 0xe7c8, 0xe7c8, 0xe7e7, 0xe7f3,
+ 0xe815, 0xe815, 0xe819, 0xe81d, 0xe81f, 0xe825, 0xe827, 0xe82a,
+ 0xe82d, 0xe830, 0xe833, 0xe83a, 0xe83c, 0xe842, 0xe844, 0xe853,
+ 0xe856, 0xe863,
+ 0xe865, 0xf92b, 0xf92d, 0xf978, 0xf97a, 0xf994,
+ 0xf996, 0xf9e6, 0xf9e8, 0xf9f0, 0xf9f2, 0xfa0b, 0xfa10, 0xfa10,
+ 0xfa12, 0xfa12, 0xfa15, 0xfa17, 0xfa19, 0xfa1e, 0xfa22, 0xfa22,
+ 0xfa25, 0xfa26, 0xfa2a, 0xfe2f, 0xfe32, 0xfe32, 0xfe45, 0xfe48,
+ 0xfe53, 0xfe53, 0xfe58, 0xfe58, 0xfe67, 0xfe67, 0xfe6c, 0xff00,
+ 0xff5f, 0xffdf, 0xffe6, 0xffff
+};
+
+static const unsigned short gb18030uni_ranges[206] = {
+ 128, 129, 131, 133, 134, 135, 137, 140,
+ 142, 144, 145, 147, 148, 149, 150, 151,
+ 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167,
+ 168, 171, 172, 189, 196, 213, 220, 221,
+ 285, 286, 287, 291, 293, 295, 297, 298,
+ 300, 301, 302, 303, 304, 305, 306, 307,
+ 308, 320, 330, 334, 338, 339, 340, 341,
+ 342, 343, 347, 348, 349, 354, 355, 359,
+ 360, 361, 362, 363, 365, 369, 371, 372,
+ 373, 374, 375, 376, 386, 426, 502, 538,
+ 553, 556, 558, 560, 562, 564, 565, 567,
+ 571, 573, 574, 575, 576, 577, 578, 579,
+ 581, 582, 583, 584, 585, 586, 588, 589,
+ 590, 602, 606, 625, 627, 636, 637, 720,
+ 724, 810, 813, 850, 860, 861, 862, 864,
+ 867, 868, 869, 870, 872, 873, 874, 875,
+ 876, 877, 878, 879, 880, 882, 883, 884,
+ 885, 886, 887, 888, 889, 890, 891, 892,
+ 893, 894, 895, 896, 897, 898, 899, 900,
+ 901, 902, 903, 905, 907, 908, 909, 911,
+ 912, 917, 924, 925, 21827,
+ 25775, 25866, 25896,
+ 25929, 25932, 25933, 25934, 25936, 25938, 25939, 25940,
+ 25942,
+ 25943, 25944, 25945, 25946, 25947, 25948, 25952,
+ 25953, 25955, 25956, 25959, 25961, 25964, 25966, 25984,
+ 25994, 25998, 26012, 26016, 26110, 26116
+};
+
+static int gb18030uni_wctomb(unsigned int* r1, unsigned int* r2, unsigned int wc) {
+ unsigned int i = wc;
+ if (i >= 0x0080 && i <= 0xffff) {
+ if (i == 0xe7c7) {
+ i = 7457;
+ } else {
+ unsigned int k1 = 0;
+ unsigned int k2 = 205;
+ while (k1 < k2) {
+ unsigned int k = (k1 + k2) / 2;
+ if (i <= gb18030uni_uni2charset_ranges[2*k+1]) {
+ k2 = k;
+ } else if (i >= gb18030uni_uni2charset_ranges[2*k+2]) {
+ k1 = k + 1;
+ } else {
+ return 0;
+ }
+ }
+ {
+ unsigned int diff = gb18030uni_ranges[k1];
+ i -= diff;
+ }
+ }
+ *r2 = (i % 10) + 0x30; i = i / 10;
+ *r2 |= ((i % 126) + 0x81) << 8; i = i / 126;
+ *r1 = (i % 10) + 0x30; i = i / 10;
+ *r1 |= (i + 0x81) << 8;
+ return 4;
+ }
+ return 0;
+}
+
+/*
+ * GB18030 (libiconv-1.16/lib/gb18030.h)
+ */
+
+static const unsigned short gb18030_pua2charset[31*3] = {
+/* Unicode range GB18030 range */
+ 0xe766, 0xe76b, 0xa2ab, /*.. 0xa2b0, */
+ 0xe76d, 0xe76d, 0xa2e4,
+ 0xe76e, 0xe76f, 0xa2ef, /*.. 0xa2f0, */
+ 0xe770, 0xe771, 0xa2fd, /*.. 0xa2fe, */
+ 0xe772, 0xe77c, 0xa4f4, /*.. 0xa4fe, */
+ 0xe77d, 0xe784, 0xa5f7, /*.. 0xa5fe, */
+ 0xe785, 0xe78c, 0xa6b9, /*.. 0xa6c0, */
+ 0xe78d, 0xe793, 0xa6d9, /*.. 0xa6df, */
+ 0xe794, 0xe795, 0xa6ec, /*.. 0xa6ed, */
+ 0xe796, 0xe796, 0xa6f3,
+ 0xe797, 0xe79f, 0xa6f6, /*.. 0xa6fe, */
+ 0xe7a0, 0xe7ae, 0xa7c2, /*.. 0xa7d0, */
+ 0xe7af, 0xe7bb, 0xa7f2, /*.. 0xa7fe, */
+ 0xe7bc, 0xe7c6, 0xa896, /*.. 0xa8a0, */
+ 0xe7c9, 0xe7cc, 0xa8c1, /*.. 0xa8c4, */
+ 0xe7cd, 0xe7e1, 0xa8ea, /*.. 0xa8fe, */
+ 0xe7e2, 0xe7e2, 0xa958,
+ 0xe7e3, 0xe7e3, 0xa95b,
+ 0xe7e4, 0xe7e6, 0xa95d, /*.. 0xa95f, */
+ 0xe7f4, 0xe800, 0xa997, /*.. 0xa9a3, */
+ 0xe801, 0xe80f, 0xa9f0, /*.. 0xa9fe, */
+ 0xe810, 0xe814, 0xd7fa, /*.. 0xd7fe, */
+ 0xe816, 0xe818, 0xfe51, /*.. 0xfe53, */
+ 0xe81e, 0xe81e, 0xfe59,
+ 0xe826, 0xe826, 0xfe61,
+ 0xe82b, 0xe82c, 0xfe66, /*.. 0xfe67, */
+ 0xe831, 0xe832, 0xfe6c, /*.. 0xfe6d, */
+ 0xe83b, 0xe83b, 0xfe76,
+ 0xe843, 0xe843, 0xfe7e,
+ 0xe854, 0xe855, 0xfe90, /*.. 0xfe91, */
+ 0xe864, 0xe864, 0xfea0,
+};
+
+INTERNAL int gb18030_wctomb_zint(unsigned int* r1, unsigned int* r2, unsigned int wc) {
+ int ret;
+
+ /* Code set 0 (ASCII) */
+ if (wc < 0x0080) {
+ *r1 = wc;
+ return 1;
+ }
+
+ /* Code set 1 (GBK extended) */
+ ret = gbk_wctomb(r1, wc);
+ if (ret) {
+ return ret;
+ }
+
+ ret = gb18030ext_wctomb(r1, wc);
+ if (ret) {
+ return ret;
+ }
+
+ /* Code set 2 (remainder of Unicode U+0000..U+FFFF) */
+ if (wc >= 0xe000 && wc <= 0xe864) {
+ if (wc < 0xe766) {
+ /* User-defined characters range U+E000..U+E765 */
+ if (wc < 0xe4c6) {
+ unsigned int i = wc - 0xe000;
+ *r1 = (i % 94) + 0xa1; i = i / 94;
+ *r1 |= (i < 6 ? i + 0xaa : i + 0xf2) << 8;
+ return 2;
+ } else {
+ unsigned int i = wc - 0xe4c6;
+ *r1 = ((i / 96) + 0xa1) << 8; i = i % 96;
+ *r1 |= i + (i >= 0x3f ? 0x41 : 0x40);
+ return 2;
+ }
+ } else {
+ /* User-defined characters, two-byte part of range U+E766..U+E864 */
+ unsigned int k1 = 0;
+ unsigned int k2 = 31;
+ /* Invariant: We know that if wc occurs in Unicode interval in
+ gb18030_pua2charset, it does so at a k with k1 <= k < k2. */
+ while (k1 < k2) {
+ unsigned int k = (k1 + k2) / 2;
+ if (wc < gb18030_pua2charset[k*3+0]) {
+ k2 = k;
+ } else if (wc > gb18030_pua2charset[k*3+1]) {
+ k1 = k + 1;
+ } else {
+ *r1 = gb18030_pua2charset[k*3+2] + (wc - gb18030_pua2charset[k*3+0]);
+ return 2;
+ }
+ }
+ }
+ }
+ ret = gb18030uni_wctomb(r1, r2, wc);
+ if (ret) {
+ return ret;
+ }
+
+ /* Code set 3 (Unicode U+10000..U+10FFFF) */
+ if (wc >= 0x10000 && wc < 0x110000) {
+ unsigned int i = wc - 0x10000;
+ *r2 = (i % 10) + 0x30; i = i / 10;
+ *r2 |= ((i % 126) + 0x81) << 8; i = i / 126;
+ *r1 = (i % 10) + 0x30; i = i / 10;
+ *r1 |= (i + 0x90) << 8;
+ return 4;
+ }
+ return 0;
+}
+
+/* Convert UTF-8 string to GB 18030 and place in array of ints */
+INTERNAL int gb18030_utf8tomb(struct zint_symbol *symbol, const unsigned char source[], size_t* p_length, unsigned int* gbdata) {
+ int error_number, ret;
+ unsigned int i, j, length;
+#ifndef _MSC_VER
+ unsigned int utfdata[*p_length + 1];
+#else
+ unsigned int* utfdata = (unsigned int*) _alloca((*p_length + 1) * sizeof(unsigned int));
+#endif
+
+ error_number = utf8_to_unicode(symbol, source, utfdata, p_length, 0 /*disallow_4byte*/);
+ if (error_number != 0) {
+ return error_number;
+ }
+
+ for (i = 0, j = 0, length = *p_length; i < length; i++, j++) {
+ if (utfdata[i] < 0x80) {
+ gbdata[j] = utfdata[i];
+ } else {
+ ret = gb18030_wctomb_zint(gbdata + j, gbdata + j + 1, utfdata[i]);
+ if (ret == 0) {
+ strcpy(symbol->errtxt, "820: Invalid character in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ if (ret == 4) {
+ j++;
+ }
+ }
+ }
+
+ *p_length = j;
+
+ return 0;
+}
+
+/* Convert UTF-8 string to single byte ECI and place in array of ints */
+INTERNAL int gb18030_utf8tosb(int eci, const unsigned char source[], size_t* p_length, unsigned int* gbdata, int full_multibyte) {
+ int error_number;
+#ifndef _MSC_VER
+ unsigned char single_byte[*p_length + 1];
+#else
+ unsigned char* single_byte = (unsigned char*) _alloca(*p_length + 1);
+#endif
+
+ error_number = utf_to_eci(eci, source, single_byte, p_length);
+ if (error_number != 0) {
+ /* Note not setting `symbol->errtxt`, up to caller */
+ return error_number;
+ }
+
+ gb18030_cpy(single_byte, p_length, gbdata, full_multibyte);
+
+ return 0;
+}
+
+/* If `full_multibyte` set, copy byte input stream to array of ints, putting double-bytes that match HANXIN Chinese mode in single entry,
+ * and quad-bytes in 2 entries. If `full_multibyte` not set, do a straight copy */
+INTERNAL void gb18030_cpy(const unsigned char source[], size_t* p_length, unsigned int* gbdata, int full_multibyte) {
+ unsigned int i, j, length;
+ int done;
+ unsigned char c1, c2, c3, c4;
+
+ if (full_multibyte) {
+ for (i = 0, j = 0, length = *p_length; i < length; i++, j++) {
+ done = 0;
+ c1 = source[i];
+ if (length - i >= 2) {
+ if (c1 >= 0x81 && c1 <= 0xFE) {
+ c2 = source[i + 1];
+ if ((c2 >= 0x40 && c2 <= 0x7E) || (c2 >= 0x80 && c2 <= 0xFE)) {
+ gbdata[j] = (c1 << 8) | c2;
+ i++;
+ done = 1;
+ } else if (length - i >= 4 && (c2 >= 0x30 && c2 <= 0x39)) {
+ c3 = source[i + 2];
+ c4 = source[i + 3];
+ if ((c3 >= 0x81 && c3 <= 0xFE) && (c4 >= 0x30 && c4 <= 0x39)) {
+ gbdata[j++] = (c1 << 8) | c2;
+ gbdata[j] = (c3 << 8) | c4;
+ i += 3;
+ done = 1;
+ }
+ }
+ }
+ }
+ if (!done) {
+ gbdata[j] = c1;
+ }
+ }
+ *p_length = j;
+ } else {
+ /* Straight copy */
+ for (i = 0, length = *p_length; i < length; i++) {
+ gbdata[i] = source[i];
+ }
+ }
+}
diff --git a/backend/gb18030.h b/backend/gb18030.h
new file mode 100644
index 0000000..704e4bd
--- /dev/null
+++ b/backend/gb18030.h
@@ -0,0 +1,49 @@
+/* gb18030.h - Unicode to GB 18030
+
+ libzint - the open source barcode library
+ Copyright (C) 2009-2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#ifndef GB18030_H
+#define GB18030_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+INTERNAL int gb18030_wctomb_zint(unsigned int* r1, unsigned int* r2, unsigned int wc);
+INTERNAL int gb18030_utf8tomb(struct zint_symbol *symbol, const unsigned char source[], size_t* p_length, unsigned int* gbdata);
+INTERNAL int gb18030_utf8tosb(int eci, const unsigned char source[], size_t* p_length, unsigned int* gbdata, int full_multibyte);
+INTERNAL void gb18030_cpy(const unsigned char source[], size_t* p_length, unsigned int* gbdata, int full_multibyte);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GB18030_H */
diff --git a/backend/gb2312.c b/backend/gb2312.c
new file mode 100644
index 0000000..1259f68
--- /dev/null
+++ b/backend/gb2312.c
@@ -0,0 +1,1624 @@
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008-2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+/*
+ * Adapted from GNU LIBICONV library and patched to add 2 duplicate mappings
+ * for compatibility with GB 18030 subset:
+ * 1) U+00B7 to 0xA1A4 (duplicate of U+30FB)
+ * 2) U+2014 to 0xA1AA (duplicate of U+2015)
+ */
+/*
+ * Copyright (C) 1999-2001, 2012, 2016 Free Software Foundation, Inc.
+ * This file is part of the GNU LIBICONV Library.
+ *
+ * The GNU LIBICONV Library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * The GNU LIBICONV Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the GNU LIBICONV Library; see the file COPYING.LIB.
+ * If not, see <https://www.gnu.org/licenses/>.
+ */
+#include <string.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+#include "common.h"
+#include "gb2312.h"
+
+INTERNAL int utf_to_eci(const int eci, const unsigned char source[], unsigned char dest[], size_t *length); /* Convert Unicode to other encodings */
+
+/*
+ * GB2312.1980-0 (libiconv-1.16/lib/gb2312.h)
+ */
+
+/* ZINT: Table converted from GB 2312 to EUC-CN values using tools/cnv_gb2312.php:
+ *
+while ($line = fgets(STDIN)) {
+ echo preg_replace_callback('/0x([0-9a-f]{4})/', function ($matches) {
+ return '0x' . dechex(hexdec($matches[1]) + 0x8080);
+ }, $line);
+}
+ */
+static const unsigned short gb2312_2charset[7445] = {
+ 0xa1e8, 0xa1ec, 0xa1a7, 0xa1e3, 0xa1c0, 0xa1c1, 0xa8a4, 0xa8a2,
+ 0xa8a8, 0xa8a6, 0xa8ba, 0xa8ac, 0xa8aa, 0xa8b0, 0xa8ae, 0xa1c2,
+ 0xa8b4, 0xa8b2, 0xa8b9, 0xa8a1, 0xa8a5, 0xa8a7, 0xa8a9, 0xa8ad,
+ 0xa8b1, 0xa8a3, 0xa8ab, 0xa8af, 0xa8b3, 0xa8b5, 0xa8b6, 0xa8b7,
+ 0xa8b8, 0xa1a6, 0xa1a5, 0xa6a1, 0xa6a2, 0xa6a3, 0xa6a4, 0xa6a5,
+ 0xa6a6, 0xa6a7, 0xa6a8, 0xa6a9, 0xa6aa, 0xa6ab, 0xa6ac, 0xa6ad,
+ 0xa6ae, 0xa6af, 0xa6b0, 0xa6b1, 0xa6b2, 0xa6b3, 0xa6b4, 0xa6b5,
+ 0xa6b6, 0xa6b7, 0xa6b8, 0xa6c1, 0xa6c2, 0xa6c3, 0xa6c4, 0xa6c5,
+ 0xa6c6, 0xa6c7, 0xa6c8, 0xa6c9, 0xa6ca, 0xa6cb, 0xa6cc, 0xa6cd,
+ 0xa6ce, 0xa6cf, 0xa6d0, 0xa6d1, 0xa6d2, 0xa6d3, 0xa6d4, 0xa6d5,
+ 0xa6d6, 0xa6d7, 0xa6d8, 0xa7a7, 0xa7a1, 0xa7a2, 0xa7a3, 0xa7a4,
+ 0xa7a5, 0xa7a6, 0xa7a8, 0xa7a9, 0xa7aa, 0xa7ab, 0xa7ac, 0xa7ad,
+ 0xa7ae, 0xa7af, 0xa7b0, 0xa7b1, 0xa7b2, 0xa7b3, 0xa7b4, 0xa7b5,
+ 0xa7b6, 0xa7b7, 0xa7b8, 0xa7b9, 0xa7ba, 0xa7bb, 0xa7bc, 0xa7bd,
+ 0xa7be, 0xa7bf, 0xa7c0, 0xa7c1, 0xa7d1, 0xa7d2, 0xa7d3, 0xa7d4,
+ 0xa7d5, 0xa7d6, 0xa7d8, 0xa7d9, 0xa7da, 0xa7db, 0xa7dc, 0xa7dd,
+ 0xa7de, 0xa7df, 0xa7e0, 0xa7e1, 0xa7e2, 0xa7e3, 0xa7e4, 0xa7e5,
+ 0xa7e6, 0xa7e7, 0xa7e8, 0xa7e9, 0xa7ea, 0xa7eb, 0xa7ec, 0xa7ed,
+ 0xa7ee, 0xa7ef, 0xa7f0, 0xa7f1, 0xa7d7, 0xa1aa, 0xa1ac, 0xa1ae,
+ 0xa1af, 0xa1b0, 0xa1b1, 0xa1ad, 0xa1eb, 0xa1e4, 0xa1e5, 0xa1f9,
+ 0xa1e6, 0xa1ed, 0xa2f1, 0xa2f2, 0xa2f3, 0xa2f4, 0xa2f5, 0xa2f6,
+ 0xa2f7, 0xa2f8, 0xa2f9, 0xa2fa, 0xa2fb, 0xa2fc, 0xa1fb, 0xa1fc,
+ 0xa1fa, 0xa1fd, 0xa1ca, 0xa1c7, 0xa1c6, 0xa1cc, 0xa1d8, 0xa1de,
+ 0xa1cf, 0xa1ce, 0xa1c4, 0xa1c5, 0xa1c9, 0xa1c8, 0xa1d2, 0xa1d3,
+ 0xa1e0, 0xa1df, 0xa1c3, 0xa1cb, 0xa1d7, 0xa1d6, 0xa1d5, 0xa1d9,
+ 0xa1d4, 0xa1dc, 0xa1dd, 0xa1da, 0xa1db, 0xa1d1, 0xa1cd, 0xa1d0,
+ 0xa2d9, 0xa2da, 0xa2db, 0xa2dc, 0xa2dd, 0xa2de, 0xa2df, 0xa2e0,
+ 0xa2e1, 0xa2e2, 0xa2c5, 0xa2c6, 0xa2c7, 0xa2c8, 0xa2c9, 0xa2ca,
+ 0xa2cb, 0xa2cc, 0xa2cd, 0xa2ce, 0xa2cf, 0xa2d0, 0xa2d1, 0xa2d2,
+ 0xa2d3, 0xa2d4, 0xa2d5, 0xa2d6, 0xa2d7, 0xa2d8, 0xa2b1, 0xa2b2,
+ 0xa2b3, 0xa2b4, 0xa2b5, 0xa2b6, 0xa2b7, 0xa2b8, 0xa2b9, 0xa2ba,
+ 0xa2bb, 0xa2bc, 0xa2bd, 0xa2be, 0xa2bf, 0xa2c0, 0xa2c1, 0xa2c2,
+ 0xa2c3, 0xa2c4, 0xa9a4, 0xa9a5, 0xa9a6, 0xa9a7, 0xa9a8, 0xa9a9,
+ 0xa9aa, 0xa9ab, 0xa9ac, 0xa9ad, 0xa9ae, 0xa9af, 0xa9b0, 0xa9b1,
+ 0xa9b2, 0xa9b3, 0xa9b4, 0xa9b5, 0xa9b6, 0xa9b7, 0xa9b8, 0xa9b9,
+ 0xa9ba, 0xa9bb, 0xa9bc, 0xa9bd, 0xa9be, 0xa9bf, 0xa9c0, 0xa9c1,
+ 0xa9c2, 0xa9c3, 0xa9c4, 0xa9c5, 0xa9c6, 0xa9c7, 0xa9c8, 0xa9c9,
+ 0xa9ca, 0xa9cb, 0xa9cc, 0xa9cd, 0xa9ce, 0xa9cf, 0xa9d0, 0xa9d1,
+ 0xa9d2, 0xa9d3, 0xa9d4, 0xa9d5, 0xa9d6, 0xa9d7, 0xa9d8, 0xa9d9,
+ 0xa9da, 0xa9db, 0xa9dc, 0xa9dd, 0xa9de, 0xa9df, 0xa9e0, 0xa9e1,
+ 0xa9e2, 0xa9e3, 0xa9e4, 0xa9e5, 0xa9e6, 0xa9e7, 0xa9e8, 0xa9e9,
+ 0xa9ea, 0xa9eb, 0xa9ec, 0xa9ed, 0xa9ee, 0xa9ef, 0xa1f6, 0xa1f5,
+ 0xa1f8, 0xa1f7, 0xa1f4, 0xa1f3, 0xa1f0, 0xa1f2, 0xa1f1, 0xa1ef,
+ 0xa1ee, 0xa1e2, 0xa1e1, 0xa1a1, 0xa1a2, 0xa1a3, 0xa1a8, 0xa1a9,
+ 0xa1b4, 0xa1b5, 0xa1b6, 0xa1b7, 0xa1b8, 0xa1b9, 0xa1ba, 0xa1bb,
+ 0xa1be, 0xa1bf, 0xa1fe, 0xa1b2, 0xa1b3, 0xa1bc, 0xa1bd, 0xa4a1,
+ 0xa4a2, 0xa4a3, 0xa4a4, 0xa4a5, 0xa4a6, 0xa4a7, 0xa4a8, 0xa4a9,
+ 0xa4aa, 0xa4ab, 0xa4ac, 0xa4ad, 0xa4ae, 0xa4af, 0xa4b0, 0xa4b1,
+ 0xa4b2, 0xa4b3, 0xa4b4, 0xa4b5, 0xa4b6, 0xa4b7, 0xa4b8, 0xa4b9,
+ 0xa4ba, 0xa4bb, 0xa4bc, 0xa4bd, 0xa4be, 0xa4bf, 0xa4c0, 0xa4c1,
+ 0xa4c2, 0xa4c3, 0xa4c4, 0xa4c5, 0xa4c6, 0xa4c7, 0xa4c8, 0xa4c9,
+ 0xa4ca, 0xa4cb, 0xa4cc, 0xa4cd, 0xa4ce, 0xa4cf, 0xa4d0, 0xa4d1,
+ 0xa4d2, 0xa4d3, 0xa4d4, 0xa4d5, 0xa4d6, 0xa4d7, 0xa4d8, 0xa4d9,
+ 0xa4da, 0xa4db, 0xa4dc, 0xa4dd, 0xa4de, 0xa4df, 0xa4e0, 0xa4e1,
+ 0xa4e2, 0xa4e3, 0xa4e4, 0xa4e5, 0xa4e6, 0xa4e7, 0xa4e8, 0xa4e9,
+ 0xa4ea, 0xa4eb, 0xa4ec, 0xa4ed, 0xa4ee, 0xa4ef, 0xa4f0, 0xa4f1,
+ 0xa4f2, 0xa4f3, 0xa5a1, 0xa5a2, 0xa5a3, 0xa5a4, 0xa5a5, 0xa5a6,
+ 0xa5a7, 0xa5a8, 0xa5a9, 0xa5aa, 0xa5ab, 0xa5ac, 0xa5ad, 0xa5ae,
+ 0xa5af, 0xa5b0, 0xa5b1, 0xa5b2, 0xa5b3, 0xa5b4, 0xa5b5, 0xa5b6,
+ 0xa5b7, 0xa5b8, 0xa5b9, 0xa5ba, 0xa5bb, 0xa5bc, 0xa5bd, 0xa5be,
+ 0xa5bf, 0xa5c0, 0xa5c1, 0xa5c2, 0xa5c3, 0xa5c4, 0xa5c5, 0xa5c6,
+ 0xa5c7, 0xa5c8, 0xa5c9, 0xa5ca, 0xa5cb, 0xa5cc, 0xa5cd, 0xa5ce,
+ 0xa5cf, 0xa5d0, 0xa5d1, 0xa5d2, 0xa5d3, 0xa5d4, 0xa5d5, 0xa5d6,
+ 0xa5d7, 0xa5d8, 0xa5d9, 0xa5da, 0xa5db, 0xa5dc, 0xa5dd, 0xa5de,
+ 0xa5df, 0xa5e0, 0xa5e1, 0xa5e2, 0xa5e3, 0xa5e4, 0xa5e5, 0xa5e6,
+ 0xa5e7, 0xa5e8, 0xa5e9, 0xa5ea, 0xa5eb, 0xa5ec, 0xa5ed, 0xa5ee,
+ 0xa5ef, 0xa5f0, 0xa5f1, 0xa5f2, 0xa5f3, 0xa5f4, 0xa5f5, 0xa5f6,
+ 0xa1a4, 0xa8c5, 0xa8c6, 0xa8c7, 0xa8c8, 0xa8c9, 0xa8ca, 0xa8cb,
+ 0xa8cc, 0xa8cd, 0xa8ce, 0xa8cf, 0xa8d0, 0xa8d1, 0xa8d2, 0xa8d3,
+ 0xa8d4, 0xa8d5, 0xa8d6, 0xa8d7, 0xa8d8, 0xa8d9, 0xa8da, 0xa8db,
+ 0xa8dc, 0xa8dd, 0xa8de, 0xa8df, 0xa8e0, 0xa8e1, 0xa8e2, 0xa8e3,
+ 0xa8e4, 0xa8e5, 0xa8e6, 0xa8e7, 0xa8e8, 0xa8e9, 0xa2e5, 0xa2e6,
+ 0xa2e7, 0xa2e8, 0xa2e9, 0xa2ea, 0xa2eb, 0xa2ec, 0xa2ed, 0xa2ee,
+ 0xd2bb, 0xb6a1, 0xc6df, 0xcdf2, 0xd5c9, 0xc8fd, 0xc9cf, 0xcfc2,
+ 0xd8a2, 0xb2bb, 0xd3eb, 0xd8a4, 0xb3f3, 0xd7a8, 0xc7d2, 0xd8a7,
+ 0xcac0, 0xc7f0, 0xb1fb, 0xd2b5, 0xb4d4, 0xb6ab, 0xcbbf, 0xd8a9,
+ 0xb6aa, 0xc1bd, 0xd1cf, 0xc9a5, 0xd8ad, 0xb8f6, 0xd1be, 0xe3dc,
+ 0xd6d0, 0xb7e1, 0xb4ae, 0xc1d9, 0xd8bc, 0xcde8, 0xb5a4, 0xceaa,
+ 0xd6f7, 0xc0f6, 0xbed9, 0xd8af, 0xc4cb, 0xbec3, 0xd8b1, 0xc3b4,
+ 0xd2e5, 0xd6ae, 0xceda, 0xd5a7, 0xbaf5, 0xb7a6, 0xc0d6, 0xc6b9,
+ 0xc5d2, 0xc7c7, 0xb9d4, 0xb3cb, 0xd2d2, 0xd8bf, 0xbec5, 0xc6f2,
+ 0xd2b2, 0xcfb0, 0xcfe7, 0xcae9, 0xd8c0, 0xc2f2, 0xc2d2, 0xc8e9,
+ 0xc7ac, 0xc1cb, 0xd3e8, 0xd5f9, 0xcac2, 0xb6fe, 0xd8a1, 0xd3da,
+ 0xbff7, 0xd4c6, 0xbba5, 0xd8c1, 0xcee5, 0xbeae, 0xd8a8, 0xd1c7,
+ 0xd0a9, 0xd8bd, 0xd9ef, 0xcdf6, 0xbfba, 0xbdbb, 0xbaa5, 0xd2e0,
+ 0xb2fa, 0xbae0, 0xc4b6, 0xcfed, 0xbea9, 0xcda4, 0xc1c1, 0xc7d7,
+ 0xd9f1, 0xd9f4, 0xc8cb, 0xd8e9, 0xd2da, 0xcab2, 0xc8ca, 0xd8ec,
+ 0xd8ea, 0xd8c6, 0xbdf6, 0xc6cd, 0xb3f0, 0xd8eb, 0xbdf1, 0xbde9,
+ 0xc8d4, 0xb4d3, 0xc2d8, 0xb2d6, 0xd7d0, 0xcacb, 0xcbfb, 0xd5cc,
+ 0xb8b6, 0xcfc9, 0xd9da, 0xd8f0, 0xc7aa, 0xd8ee, 0xb4fa, 0xc1ee,
+ 0xd2d4, 0xd8ed, 0xd2c7, 0xd8ef, 0xc3c7, 0xd1f6, 0xd6d9, 0xd8f2,
+ 0xd8f5, 0xbcfe, 0xbcdb, 0xc8ce, 0xb7dd, 0xb7c2, 0xc6f3, 0xd8f8,
+ 0xd2c1, 0xcee9, 0xbcbf, 0xb7fc, 0xb7a5, 0xd0dd, 0xd6da, 0xd3c5,
+ 0xbbef, 0xbbe1, 0xd8f1, 0xc9a1, 0xceb0, 0xb4ab, 0xd8f3, 0xc9cb,
+ 0xd8f6, 0xc2d7, 0xd8f7, 0xceb1, 0xd8f9, 0xb2ae, 0xb9c0, 0xd9a3,
+ 0xb0e9, 0xc1e6, 0xc9ec, 0xcbc5, 0xcbc6, 0xd9a4, 0xb5e8, 0xb5ab,
+ 0xcebb, 0xb5cd, 0xd7a1, 0xd7f4, 0xd3d3, 0xcce5, 0xbace, 0xd9a2,
+ 0xd9dc, 0xd3e0, 0xd8fd, 0xb7f0, 0xd7f7, 0xd8fe, 0xd8fa, 0xd9a1,
+ 0xc4e3, 0xd3b6, 0xd8f4, 0xd9dd, 0xd8fb, 0xc5e5, 0xc0d0, 0xd1f0,
+ 0xb0db, 0xbcd1, 0xd9a6, 0xd9a5, 0xd9ac, 0xd9ae, 0xd9ab, 0xcab9,
+ 0xd9a9, 0xd6b6, 0xb3de, 0xd9a8, 0xc0fd, 0xcacc, 0xd9aa, 0xd9a7,
+ 0xd9b0, 0xb6b1, 0xb9a9, 0xd2c0, 0xcfc0, 0xc2c2, 0xbdc4, 0xd5ec,
+ 0xb2e0, 0xc7c8, 0xbfeb, 0xd9ad, 0xd9af, 0xceea, 0xbaee, 0xc7d6,
+ 0xb1e3, 0xb4d9, 0xb6ed, 0xd9b4, 0xbfa1, 0xd9de, 0xc7ce, 0xc0fe,
+ 0xd9b8, 0xcbd7, 0xb7fd, 0xd9b5, 0xd9b7, 0xb1a3, 0xd3e1, 0xd9b9,
+ 0xd0c5, 0xd9b6, 0xd9b1, 0xd9b2, 0xc1a9, 0xd9b3, 0xbcf3, 0xd0de,
+ 0xb8a9, 0xbee3, 0xd9bd, 0xd9ba, 0xb0b3, 0xd9c2, 0xd9c4, 0xb1b6,
+ 0xd9bf, 0xb5b9, 0xbef3, 0xccc8, 0xbaf2, 0xd2d0, 0xd9c3, 0xbde8,
+ 0xb3ab, 0xd9c5, 0xbeeb, 0xd9c6, 0xd9bb, 0xc4df, 0xd9be, 0xd9c1,
+ 0xd9c0, 0xd5ae, 0xd6b5, 0xc7e3, 0xd9c8, 0xbcd9, 0xd9ca, 0xd9bc,
+ 0xd9cb, 0xc6ab, 0xd9c9, 0xd7f6, 0xcda3, 0xbda1, 0xd9cc, 0xc5bc,
+ 0xcdb5, 0xd9cd, 0xd9c7, 0xb3a5, 0xbffe, 0xb8b5, 0xc0fc, 0xb0f8,
+ 0xb4f6, 0xd9ce, 0xd9cf, 0xb4a2, 0xd9d0, 0xb4df, 0xb0c1, 0xd9d1,
+ 0xc9b5, 0xcff1, 0xd9d2, 0xc1c5, 0xd9d6, 0xc9ae, 0xd9d5, 0xd9d4,
+ 0xd9d7, 0xcbdb, 0xbda9, 0xc6a7, 0xd9d3, 0xd9d8, 0xd9d9, 0xc8e5,
+ 0xc0dc, 0xb6f9, 0xd8a3, 0xd4ca, 0xd4aa, 0xd0d6, 0xb3e4, 0xd5d7,
+ 0xcfc8, 0xb9e2, 0xbfcb, 0xc3e2, 0xb6d2, 0xcdc3, 0xd9ee, 0xd9f0,
+ 0xb5b3, 0xb6b5, 0xbea4, 0xc8eb, 0xc8ab, 0xb0cb, 0xb9ab, 0xc1f9,
+ 0xd9e2, 0xc0bc, 0xb9b2, 0xb9d8, 0xd0cb, 0xb1f8, 0xc6e4, 0xbedf,
+ 0xb5e4, 0xd7c8, 0xd1f8, 0xbce6, 0xcade, 0xbcbd, 0xd9e6, 0xd8e7,
+ 0xc4da, 0xb8d4, 0xc8bd, 0xb2e1, 0xd4d9, 0xc3b0, 0xc3e1, 0xdaa2,
+ 0xc8df, 0xd0b4, 0xbefc, 0xc5a9, 0xb9da, 0xdaa3, 0xd4a9, 0xdaa4,
+ 0xd9fb, 0xb6ac, 0xb7eb, 0xb1f9, 0xd9fc, 0xb3e5, 0xbef6, 0xbff6,
+ 0xd2b1, 0xc0e4, 0xb6b3, 0xd9fe, 0xd9fd, 0xbebb, 0xc6e0, 0xd7bc,
+ 0xdaa1, 0xc1b9, 0xb5f2, 0xc1e8, 0xbcf5, 0xb4d5, 0xc1dd, 0xc4fd,
+ 0xbcb8, 0xb7b2, 0xb7ef, 0xd9ec, 0xc6be, 0xbfad, 0xbbcb, 0xb5ca,
+ 0xdbc9, 0xd0d7, 0xcdb9, 0xb0bc, 0xb3f6, 0xbbf7, 0xdbca, 0xbaaf,
+ 0xd4e4, 0xb5b6, 0xb5f3, 0xd8d6, 0xc8d0, 0xb7d6, 0xc7d0, 0xd8d7,
+ 0xbfaf, 0xdbbb, 0xd8d8, 0xd0cc, 0xbbae, 0xebbe, 0xc1d0, 0xc1f5,
+ 0xd4f2, 0xb8d5, 0xb4b4, 0xb3f5, 0xc9be, 0xc5d0, 0xc5d9, 0xc0fb,
+ 0xb1f0, 0xd8d9, 0xb9ce, 0xb5bd, 0xd8da, 0xd6c6, 0xcba2, 0xc8af,
+ 0xc9b2, 0xb4cc, 0xbfcc, 0xb9f4, 0xd8db, 0xd8dc, 0xb6e7, 0xbcc1,
+ 0xccea, 0xcff7, 0xd8dd, 0xc7b0, 0xb9d0, 0xbda3, 0xccde, 0xc6ca,
+ 0xd8e0, 0xd8de, 0xd8df, 0xb0fe, 0xbee7, 0xcaa3, 0xbcf4, 0xb8b1,
+ 0xb8ee, 0xd8e2, 0xbdcb, 0xd8e4, 0xd8e3, 0xc5fc, 0xd8e5, 0xd8e6,
+ 0xc1a6, 0xc8b0, 0xb0ec, 0xb9a6, 0xbcd3, 0xcef1, 0xdbbd, 0xc1d3,
+ 0xb6af, 0xd6fa, 0xc5ac, 0xbdd9, 0xdbbe, 0xdbbf, 0xc0f8, 0xbea2,
+ 0xc0cd, 0xdbc0, 0xcac6, 0xb2aa, 0xd3c2, 0xc3e3, 0xd1ab, 0xdbc2,
+ 0xc0d5, 0xdbc3, 0xbfb1, 0xc4bc, 0xc7da, 0xdbc4, 0xd9e8, 0xc9d7,
+ 0xb9b4, 0xcef0, 0xd4c8, 0xb0fc, 0xb4d2, 0xd0d9, 0xd9e9, 0xdecb,
+ 0xd9eb, 0xd8b0, 0xbbaf, 0xb1b1, 0xb3d7, 0xd8ce, 0xd4d1, 0xbdb3,
+ 0xbfef, 0xcfbb, 0xd8d0, 0xb7cb, 0xd8d1, 0xc6a5, 0xc7f8, 0xd2bd,
+ 0xd8d2, 0xc4e4, 0xcaae, 0xc7a7, 0xd8a6, 0xc9fd, 0xcee7, 0xbbdc,
+ 0xb0eb, 0xbbaa, 0xd0ad, 0xb1b0, 0xd7e4, 0xd7bf, 0xb5a5, 0xc2f4,
+ 0xc4cf, 0xb2a9, 0xb2b7, 0xb1e5, 0xdfb2, 0xd5bc, 0xbfa8, 0xc2ac,
+ 0xd8d5, 0xc2b1, 0xd8d4, 0xced4, 0xdae0, 0xcec0, 0xd8b4, 0xc3ae,
+ 0xd3a1, 0xcea3, 0xbcb4, 0xc8b4, 0xc2d1, 0xbeed, 0xd0b6, 0xdae1,
+ 0xc7e4, 0xb3a7, 0xb6f2, 0xccfc, 0xc0fa, 0xc0f7, 0xd1b9, 0xd1e1,
+ 0xd8c7, 0xb2de, 0xc0e5, 0xbaf1, 0xd8c8, 0xd4ad, 0xcfe1, 0xd8c9,
+ 0xd8ca, 0xcfc3, 0xb3f8, 0xbec7, 0xd8cb, 0xdbcc, 0xc8a5, 0xcfd8,
+ 0xc8fe, 0xb2ce, 0xd3d6, 0xb2e6, 0xbcb0, 0xd3d1, 0xcbab, 0xb7b4,
+ 0xb7a2, 0xcae5, 0xc8a1, 0xcadc, 0xb1e4, 0xd0f0, 0xc5d1, 0xdbc5,
+ 0xb5fe, 0xbfda, 0xb9c5, 0xbee4, 0xc1ed, 0xdfb6, 0xdfb5, 0xd6bb,
+ 0xbdd0, 0xd5d9, 0xb0c8, 0xb6a3, 0xbfc9, 0xcca8, 0xdfb3, 0xcab7,
+ 0xd3d2, 0xd8cf, 0xd2b6, 0xbac5, 0xcbbe, 0xccbe, 0xdfb7, 0xb5f0,
+ 0xdfb4, 0xd3f5, 0xb3d4, 0xb8f7, 0xdfba, 0xbacf, 0xbcaa, 0xb5f5,
+ 0xcdac, 0xc3fb, 0xbaf3, 0xc0f4, 0xcdc2, 0xcff2, 0xdfb8, 0xcfc5,
+ 0xc2c0, 0xdfb9, 0xc2f0, 0xbefd, 0xc1df, 0xcdcc, 0xd2f7, 0xb7cd,
+ 0xdfc1, 0xdfc4, 0xb7f1, 0xb0c9, 0xb6d6, 0xb7d4, 0xbaac, 0xccfd,
+ 0xbfd4, 0xcbb1, 0xc6f4, 0xd6a8, 0xdfc5, 0xcee2, 0xb3b3, 0xcefc,
+ 0xb4b5, 0xcec7, 0xbaf0, 0xcee1, 0xd1bd, 0xdfc0, 0xb4f4, 0xb3ca,
+ 0xb8e6, 0xdfbb, 0xc4c5, 0xdfbc, 0xdfbd, 0xdfbe, 0xc5bb, 0xdfbf,
+ 0xdfc2, 0xd4b1, 0xdfc3, 0xc7ba, 0xced8, 0xc4d8, 0xdfca, 0xdfcf,
+ 0xd6dc, 0xdfc9, 0xdfda, 0xceb6, 0xbac7, 0xdfce, 0xdfc8, 0xc5de,
+ 0xc9eb, 0xbaf4, 0xc3fc, 0xbed7, 0xdfc6, 0xdfcd, 0xc5d8, 0xd5a6,
+ 0xbacd, 0xbecc, 0xd3bd, 0xb8c0, 0xd6e4, 0xdfc7, 0xb9be, 0xbfa7,
+ 0xc1fc, 0xdfcb, 0xdfcc, 0xdfd0, 0xdfdb, 0xdfe5, 0xdfd7, 0xdfd6,
+ 0xd7c9, 0xdfe3, 0xdfe4, 0xe5eb, 0xd2a7, 0xdfd2, 0xbfa9, 0xd4db,
+ 0xbfc8, 0xdfd4, 0xcfcc, 0xdfdd, 0xd1ca, 0xdfde, 0xb0a7, 0xc6b7,
+ 0xdfd3, 0xbae5, 0xb6df, 0xcddb, 0xb9fe, 0xd4d5, 0xdfdf, 0xcfec,
+ 0xb0a5, 0xdfe7, 0xdfd1, 0xd1c6, 0xdfd5, 0xdfd8, 0xdfd9, 0xdfdc,
+ 0xbba9, 0xdfe0, 0xdfe1, 0xdfe2, 0xdfe6, 0xdfe8, 0xd3b4, 0xb8e7,
+ 0xc5b6, 0xdfea, 0xc9da, 0xc1a8, 0xc4c4, 0xbfde, 0xcff8, 0xd5dc,
+ 0xdfee, 0xb2b8, 0xbadf, 0xdfec, 0xdbc1, 0xd1e4, 0xcbf4, 0xb4bd,
+ 0xb0a6, 0xdff1, 0xccc6, 0xdff2, 0xdfed, 0xdfe9, 0xdfeb, 0xdfef,
+ 0xdff0, 0xbbbd, 0xdff3, 0xdff4, 0xbba3, 0xcadb, 0xcea8, 0xe0a7,
+ 0xb3aa, 0xe0a6, 0xe0a1, 0xdffe, 0xcdd9, 0xdffc, 0xdffa, 0xbfd0,
+ 0xd7c4, 0xc9cc, 0xdff8, 0xb0a1, 0xdffd, 0xdffb, 0xe0a2, 0xe0a8,
+ 0xb7c8, 0xc6a1, 0xc9b6, 0xc0b2, 0xdff5, 0xc5be, 0xd8c4, 0xdff9,
+ 0xc4f6, 0xe0a3, 0xe0a4, 0xe0a5, 0xd0a5, 0xe0b4, 0xcce4, 0xe0b1,
+ 0xbfa6, 0xe0af, 0xceb9, 0xe0ab, 0xc9c6, 0xc0ae, 0xe0ae, 0xbaed,
+ 0xbab0, 0xe0a9, 0xdff6, 0xe0b3, 0xe0b8, 0xb4ad, 0xe0b9, 0xcfb2,
+ 0xbac8, 0xe0b0, 0xd0fa, 0xe0ac, 0xd4fb, 0xdff7, 0xc5e7, 0xe0ad,
+ 0xd3f7, 0xe0b6, 0xe0b7, 0xe0c4, 0xd0e1, 0xe0bc, 0xe0c9, 0xe0ca,
+ 0xe0be, 0xe0aa, 0xc9a4, 0xe0c1, 0xe0b2, 0xcac8, 0xe0c3, 0xe0b5,
+ 0xcecb, 0xcbc3, 0xe0cd, 0xe0c6, 0xe0c2, 0xe0cb, 0xe0ba, 0xe0bf,
+ 0xe0c0, 0xe0c5, 0xe0c7, 0xe0c8, 0xe0cc, 0xe0bb, 0xcbd4, 0xe0d5,
+ 0xe0d6, 0xe0d2, 0xe0d0, 0xbcce, 0xe0d1, 0xb8c2, 0xd8c5, 0xd0ea,
+ 0xc2ef, 0xe0cf, 0xe0bd, 0xe0d4, 0xe0d3, 0xe0d7, 0xe0dc, 0xe0d8,
+ 0xd6f6, 0xb3b0, 0xd7ec, 0xcbbb, 0xe0da, 0xcefb, 0xbad9, 0xe0e1,
+ 0xe0dd, 0xd2ad, 0xe0e2, 0xe0db, 0xe0d9, 0xe0df, 0xe0e0, 0xe0de,
+ 0xe0e4, 0xc6f7, 0xd8ac, 0xd4eb, 0xe0e6, 0xcac9, 0xe0e5, 0xb8c1,
+ 0xe0e7, 0xe0e8, 0xe0e9, 0xe0e3, 0xbabf, 0xcce7, 0xe0ea, 0xcff9,
+ 0xe0eb, 0xc8c2, 0xbdc0, 0xc4d2, 0xe0ec, 0xe0ed, 0xc7f4, 0xcbc4,
+ 0xe0ee, 0xbbd8, 0xd8b6, 0xd2f2, 0xe0ef, 0xcdc5, 0xb6da, 0xe0f1,
+ 0xd4b0, 0xc0a7, 0xb4d1, 0xcea7, 0xe0f0, 0xe0f2, 0xb9cc, 0xb9fa,
+ 0xcdbc, 0xe0f3, 0xc6d4, 0xe0f4, 0xd4b2, 0xc8a6, 0xe0f6, 0xe0f5,
+ 0xe0f7, 0xcdc1, 0xcaa5, 0xd4da, 0xdbd7, 0xdbd9, 0xdbd8, 0xb9e7,
+ 0xdbdc, 0xdbdd, 0xb5d8, 0xdbda, 0xdbdb, 0xb3a1, 0xdbdf, 0xbbf8,
+ 0xd6b7, 0xdbe0, 0xbef9, 0xb7bb, 0xdbd0, 0xccae, 0xbfb2, 0xbbb5,
+ 0xd7f8, 0xbfd3, 0xbfe9, 0xbce1, 0xccb3, 0xdbde, 0xb0d3, 0xceeb,
+ 0xb7d8, 0xd7b9, 0xc6c2, 0xc0a4, 0xccb9, 0xdbe7, 0xdbe1, 0xc6ba,
+ 0xdbe3, 0xdbe8, 0xc5f7, 0xdbea, 0xdbe9, 0xbfc0, 0xdbe6, 0xdbe5,
+ 0xb4b9, 0xc0ac, 0xc2a2, 0xdbe2, 0xdbe4, 0xd0cd, 0xdbed, 0xc0dd,
+ 0xdbf2, 0xb6e2, 0xdbf3, 0xdbd2, 0xb9b8, 0xd4ab, 0xdbec, 0xbfd1,
+ 0xdbf0, 0xdbd1, 0xb5e6, 0xdbeb, 0xbfe5, 0xdbee, 0xdbf1, 0xdbf9,
+ 0xb9a1, 0xb0a3, 0xc2f1, 0xb3c7, 0xdbef, 0xdbf8, 0xc6d2, 0xdbf4,
+ 0xdbf5, 0xdbf7, 0xdbf6, 0xdbfe, 0xd3f2, 0xb2ba, 0xdbfd, 0xdca4,
+ 0xdbfb, 0xdbfa, 0xdbfc, 0xc5e0, 0xbbf9, 0xdca3, 0xdca5, 0xccc3,
+ 0xb6d1, 0xddc0, 0xdca1, 0xdca2, 0xc7b5, 0xb6e9, 0xdca7, 0xdca6,
+ 0xdca9, 0xb1a4, 0xb5cc, 0xbfb0, 0xd1df, 0xb6c2, 0xdca8, 0xcbfa,
+ 0xebf3, 0xcbdc, 0xcbfe, 0xccc1, 0xc8fb, 0xdcaa, 0xccee, 0xdcab,
+ 0xdbd3, 0xdcaf, 0xdcac, 0xbeb3, 0xcafb, 0xdcad, 0xc9ca, 0xc4b9,
+ 0xc7bd, 0xdcae, 0xd4f6, 0xd0e6, 0xc4ab, 0xb6d5, 0xdbd4, 0xb1da,
+ 0xdbd5, 0xdbd6, 0xbabe, 0xc8c0, 0xcabf, 0xc8c9, 0xd7b3, 0xc9f9,
+ 0xbfc7, 0xbaf8, 0xd2bc, 0xe2ba, 0xb4a6, 0xb1b8, 0xb8b4, 0xcfc4,
+ 0xd9e7, 0xcfa6, 0xcde2, 0xd9ed, 0xb6e0, 0xd2b9, 0xb9bb, 0xe2b9,
+ 0xe2b7, 0xb4f3, 0xccec, 0xccab, 0xb7f2, 0xd8b2, 0xd1eb, 0xbabb,
+ 0xcaa7, 0xcdb7, 0xd2c4, 0xbfe4, 0xbcd0, 0xb6e1, 0xdec5, 0xdec6,
+ 0xdbbc, 0xd1d9, 0xc6e6, 0xc4ce, 0xb7ee, 0xb7dc, 0xbffc, 0xd7e0,
+ 0xc6f5, 0xb1bc, 0xdec8, 0xbdb1, 0xccd7, 0xdeca, 0xdec9, 0xb5ec,
+ 0xc9dd, 0xb0c2, 0xc5ae, 0xc5ab, 0xc4cc, 0xbce9, 0xcbfd, 0xbac3,
+ 0xe5f9, 0xc8e7, 0xe5fa, 0xcdfd, 0xd7b1, 0xb8be, 0xc2e8, 0xc8d1,
+ 0xe5fb, 0xb6ca, 0xbccb, 0xd1fd, 0xe6a1, 0xc3ee, 0xe6a4, 0xe5fe,
+ 0xe6a5, 0xcdd7, 0xb7c1, 0xe5fc, 0xe5fd, 0xe6a3, 0xc4dd, 0xe6a8,
+ 0xe6a7, 0xc3c3, 0xc6de, 0xe6aa, 0xc4b7, 0xe6a2, 0xcabc, 0xbde3,
+ 0xb9c3, 0xe6a6, 0xd0d5, 0xceaf, 0xe6a9, 0xe6b0, 0xd2a6, 0xbdaa,
+ 0xe6ad, 0xe6af, 0xc0d1, 0xd2cc, 0xbca7, 0xe6b1, 0xd2f6, 0xd7cb,
+ 0xcdfe, 0xcdde, 0xc2a6, 0xe6ab, 0xe6ac, 0xbdbf, 0xe6ae, 0xe6b3,
+ 0xe6b2, 0xe6b6, 0xe6b8, 0xc4ef, 0xc4c8, 0xbeea, 0xc9ef, 0xe6b7,
+ 0xb6f0, 0xc3e4, 0xd3e9, 0xe6b4, 0xe6b5, 0xc8a2, 0xe6bd, 0xe6b9,
+ 0xc6c5, 0xcdf1, 0xe6bb, 0xe6bc, 0xbbe9, 0xe6be, 0xe6ba, 0xc0b7,
+ 0xd3a4, 0xe6bf, 0xc9f4, 0xe6c3, 0xe6c4, 0xd0f6, 0xc3bd, 0xc3c4,
+ 0xe6c2, 0xe6c1, 0xe6c7, 0xcfb1, 0xebf4, 0xe6ca, 0xe6c5, 0xbcde,
+ 0xc9a9, 0xbcb5, 0xcfd3, 0xe6c8, 0xe6c9, 0xe6ce, 0xe6d0, 0xe6d1,
+ 0xe6cb, 0xb5d5, 0xe6cc, 0xe6cf, 0xc4db, 0xe6c6, 0xe6cd, 0xe6d2,
+ 0xe6d4, 0xe6d3, 0xe6d5, 0xd9f8, 0xe6d6, 0xe6d7, 0xd7d3, 0xe6dd,
+ 0xe6de, 0xbfd7, 0xd4d0, 0xd7d6, 0xb4e6, 0xcbef, 0xe6da, 0xd8c3,
+ 0xd7ce, 0xd0a2, 0xc3cf, 0xe6df, 0xbcbe, 0xb9c2, 0xe6db, 0xd1a7,
+ 0xbaa2, 0xc2cf, 0xd8ab, 0xcaeb, 0xe5ee, 0xe6dc, 0xb7f5, 0xc8e6,
+ 0xc4f5, 0xe5b2, 0xc4fe, 0xcbfc, 0xe5b3, 0xd5ac, 0xd3ee, 0xcad8,
+ 0xb0b2, 0xcbce, 0xcdea, 0xbaea, 0xe5b5, 0xe5b4, 0xd7da, 0xb9d9,
+ 0xd6e6, 0xb6a8, 0xcdf0, 0xd2cb, 0xb1a6, 0xcab5, 0xb3e8, 0xc9f3,
+ 0xbfcd, 0xd0fb, 0xcad2, 0xe5b6, 0xbbc2, 0xcfdc, 0xb9ac, 0xd4d7,
+ 0xbaa6, 0xd1e7, 0xcffc, 0xbcd2, 0xe5b7, 0xc8dd, 0xbfed, 0xb1f6,
+ 0xcbde, 0xbcc5, 0xbcc4, 0xd2fa, 0xc3dc, 0xbfdc, 0xb8bb, 0xc3c2,
+ 0xbaae, 0xd4a2, 0xc7de, 0xc4af, 0xb2ec, 0xb9d1, 0xe5bb, 0xc1c8,
+ 0xd5af, 0xe5bc, 0xe5be, 0xb4e7, 0xb6d4, 0xcbc2, 0xd1b0, 0xb5bc,
+ 0xcad9, 0xb7e2, 0xc9e4, 0xbdab, 0xcebe, 0xd7f0, 0xd0a1, 0xc9d9,
+ 0xb6fb, 0xe6d8, 0xbce2, 0xb3be, 0xc9d0, 0xe6d9, 0xb3a2, 0xdecc,
+ 0xd3c8, 0xdecd, 0xd2a2, 0xdece, 0xbecd, 0xdecf, 0xcaac, 0xd2fc,
+ 0xb3df, 0xe5ea, 0xc4e1, 0xbea1, 0xceb2, 0xc4f2, 0xbed6, 0xc6a8,
+ 0xb2e3, 0xbed3, 0xc7fc, 0xcceb, 0xbdec, 0xcedd, 0xcaba, 0xc6c1,
+ 0xe5ec, 0xd0bc, 0xd5b9, 0xe5ed, 0xcaf4, 0xcdc0, 0xc2c5, 0xe5ef,
+ 0xc2c4, 0xe5f0, 0xe5f8, 0xcdcd, 0xc9bd, 0xd2d9, 0xe1a8, 0xd3ec,
+ 0xcbea, 0xc6f1, 0xe1ac, 0xe1a7, 0xe1a9, 0xe1aa, 0xe1af, 0xb2ed,
+ 0xe1ab, 0xb8da, 0xe1ad, 0xe1ae, 0xe1b0, 0xb5ba, 0xe1b1, 0xe1b3,
+ 0xe1b8, 0xd1d2, 0xe1b6, 0xe1b5, 0xc1eb, 0xe1b7, 0xd4c0, 0xe1b2,
+ 0xe1ba, 0xb0b6, 0xe1b4, 0xbff9, 0xe1b9, 0xe1bb, 0xe1be, 0xe1bc,
+ 0xd6c5, 0xcfbf, 0xe1bd, 0xe1bf, 0xc2cd, 0xb6eb, 0xd3f8, 0xc7cd,
+ 0xb7e5, 0xbefe, 0xe1c0, 0xe1c1, 0xe1c7, 0xb3e7, 0xc6e9, 0xb4de,
+ 0xd1c2, 0xe1c8, 0xe1c6, 0xe1c5, 0xe1c3, 0xe1c2, 0xb1c0, 0xd5b8,
+ 0xe1c4, 0xe1cb, 0xe1cc, 0xe1ca, 0xeffa, 0xe1d3, 0xe1d2, 0xc7b6,
+ 0xe1c9, 0xe1ce, 0xe1d0, 0xe1d4, 0xe1d1, 0xe1cd, 0xe1cf, 0xe1d5,
+ 0xe1d6, 0xe1d7, 0xe1d8, 0xe1da, 0xe1db, 0xcea1, 0xe7dd, 0xb4a8,
+ 0xd6dd, 0xd1b2, 0xb3b2, 0xb9a4, 0xd7f3, 0xc7c9, 0xbede, 0xb9ae,
+ 0xced7, 0xb2ee, 0xdbcf, 0xbcba, 0xd2d1, 0xcbc8, 0xb0cd, 0xcfef,
+ 0xd9e3, 0xbded, 0xb1d2, 0xcad0, 0xb2bc, 0xcba7, 0xb7ab, 0xcaa6,
+ 0xcfa3, 0xe0f8, 0xd5ca, 0xe0fb, 0xe0fa, 0xc5c1, 0xccfb, 0xc1b1,
+ 0xe0f9, 0xd6e3, 0xb2af, 0xd6c4, 0xb5db, 0xb4f8, 0xd6a1, 0xcfaf,
+ 0xb0ef, 0xe0fc, 0xe1a1, 0xb3a3, 0xe0fd, 0xe0fe, 0xc3b1, 0xc3dd,
+ 0xe1a2, 0xb7f9, 0xbbcf, 0xe1a3, 0xc4bb, 0xe1a4, 0xe1a5, 0xe1a6,
+ 0xb4b1, 0xb8c9, 0xc6bd, 0xc4ea, 0xb2a2, 0xd0d2, 0xe7db, 0xbbc3,
+ 0xd3d7, 0xd3c4, 0xb9e3, 0xe2cf, 0xd7af, 0xc7ec, 0xb1d3, 0xb4b2,
+ 0xe2d1, 0xd0f2, 0xc2ae, 0xe2d0, 0xbfe2, 0xd3a6, 0xb5d7, 0xe2d2,
+ 0xb5ea, 0xc3ed, 0xb8fd, 0xb8ae, 0xc5d3, 0xb7cf, 0xe2d4, 0xe2d3,
+ 0xb6c8, 0xd7f9, 0xcda5, 0xe2d8, 0xe2d6, 0xcafc, 0xbfb5, 0xd3b9,
+ 0xe2d5, 0xe2d7, 0xc1ae, 0xc0c8, 0xe2db, 0xe2da, 0xc0aa, 0xc1ce,
+ 0xe2dc, 0xe2dd, 0xe2de, 0xdbc8, 0xd1d3, 0xcda2, 0xbda8, 0xdec3,
+ 0xd8a5, 0xbfaa, 0xdbcd, 0xd2ec, 0xc6fa, 0xc5aa, 0xdec4, 0xb1d7,
+ 0xdfae, 0xcabd, 0xdfb1, 0xb9ad, 0xd2fd, 0xb8a5, 0xbaeb, 0xb3da,
+ 0xb5dc, 0xd5c5, 0xc3d6, 0xcfd2, 0xbba1, 0xe5f3, 0xe5f2, 0xe5f4,
+ 0xcde4, 0xc8f5, 0xb5af, 0xc7bf, 0xe5f6, 0xecb0, 0xe5e6, 0xb9e9,
+ 0xb5b1, 0xc2bc, 0xe5e8, 0xe5e7, 0xe5e9, 0xd2cd, 0xe1ea, 0xd0ce,
+ 0xcdae, 0xd1e5, 0xb2ca, 0xb1eb, 0xb1f2, 0xc5ed, 0xd5c3, 0xd3b0,
+ 0xe1dc, 0xe1dd, 0xd2db, 0xb3b9, 0xb1cb, 0xcdf9, 0xd5f7, 0xe1de,
+ 0xbeb6, 0xb4fd, 0xe1df, 0xbadc, 0xe1e0, 0xbbb2, 0xc2c9, 0xe1e1,
+ 0xd0ec, 0xcdbd, 0xe1e2, 0xb5c3, 0xc5c7, 0xe1e3, 0xe1e4, 0xd3f9,
+ 0xe1e5, 0xd1ad, 0xe1e6, 0xcea2, 0xe1e7, 0xb5c2, 0xe1e8, 0xbbd5,
+ 0xd0c4, 0xe2e0, 0xb1d8, 0xd2e4, 0xe2e1, 0xbcc9, 0xc8cc, 0xe2e3,
+ 0xecfe, 0xecfd, 0xdfaf, 0xe2e2, 0xd6be, 0xcdfc, 0xc3a6, 0xe3c3,
+ 0xd6d2, 0xe2e7, 0xe2e8, 0xd3c7, 0xe2ec, 0xbfec, 0xe2ed, 0xe2e5,
+ 0xb3c0, 0xc4ee, 0xe2ee, 0xd0c3, 0xbaf6, 0xe2e9, 0xb7de, 0xbbb3,
+ 0xccac, 0xcbcb, 0xe2e4, 0xe2e6, 0xe2ea, 0xe2eb, 0xe2f7, 0xe2f4,
+ 0xd4f5, 0xe2f3, 0xc5ad, 0xd5fa, 0xc5c2, 0xb2c0, 0xe2ef, 0xe2f2,
+ 0xc1af, 0xcbbc, 0xb5a1, 0xe2f9, 0xbcb1, 0xe2f1, 0xd0d4, 0xd4b9,
+ 0xe2f5, 0xb9d6, 0xe2f6, 0xc7d3, 0xe2f0, 0xd7dc, 0xeda1, 0xe2f8,
+ 0xeda5, 0xe2fe, 0xcad1, 0xc1b5, 0xbbd0, 0xbfd6, 0xbae3, 0xcba1,
+ 0xeda6, 0xeda3, 0xeda2, 0xbbd6, 0xeda7, 0xd0f4, 0xeda4, 0xbade,
+ 0xb6f7, 0xe3a1, 0xb6b2, 0xccf1, 0xb9a7, 0xcfa2, 0xc7a1, 0xbfd2,
+ 0xb6f1, 0xe2fa, 0xe2fb, 0xe2fd, 0xe2fc, 0xc4d5, 0xe3a2, 0xd3c1,
+ 0xe3a7, 0xc7c4, 0xcfa4, 0xe3a9, 0xbab7, 0xe3a8, 0xbbda, 0xe3a3,
+ 0xe3a4, 0xe3aa, 0xe3a6, 0xcef2, 0xd3c6, 0xbbbc, 0xd4c3, 0xc4fa,
+ 0xeda8, 0xd0fc, 0xe3a5, 0xc3f5, 0xe3ad, 0xb1af, 0xe3b2, 0xbcc2,
+ 0xe3ac, 0xb5bf, 0xc7e9, 0xe3b0, 0xbeaa, 0xcdef, 0xbbf3, 0xcce8,
+ 0xe3af, 0xe3b1, 0xcfa7, 0xe3ae, 0xcea9, 0xbbdd, 0xb5eb, 0xbee5,
+ 0xb2d2, 0xb3cd, 0xb1b9, 0xe3ab, 0xb2d1, 0xb5ac, 0xb9df, 0xb6e8,
+ 0xcfeb, 0xe3b7, 0xbbcc, 0xc8c7, 0xd0ca, 0xe3b8, 0xb3ee, 0xeda9,
+ 0xd3fa, 0xd3e4, 0xedaa, 0xe3b9, 0xd2e2, 0xe3b5, 0xd3de, 0xb8d0,
+ 0xe3b3, 0xe3b6, 0xb7df, 0xe3b4, 0xc0a2, 0xe3ba, 0xd4b8, 0xb4c8,
+ 0xe3bb, 0xbbc5, 0xc9f7, 0xc9e5, 0xc4bd, 0xedab, 0xc2fd, 0xbbdb,
+ 0xbfae, 0xcebf, 0xe3bc, 0xbfb6, 0xb1ef, 0xd4f7, 0xe3be, 0xedad,
+ 0xe3bf, 0xbaa9, 0xedac, 0xe3bd, 0xe3c0, 0xbab6, 0xb6ae, 0xd0b8,
+ 0xb0c3, 0xedae, 0xedaf, 0xc0c1, 0xe3c1, 0xc5b3, 0xe3c2, 0xdcb2,
+ 0xedb0, 0xb8ea, 0xceec, 0xeaa7, 0xd0e7, 0xcaf9, 0xc8d6, 0xcfb7,
+ 0xb3c9, 0xced2, 0xbde4, 0xe3de, 0xbbf2, 0xeaa8, 0xd5bd, 0xc6dd,
+ 0xeaa9, 0xeaaa, 0xeaac, 0xeaab, 0xeaae, 0xeaad, 0xbdd8, 0xeaaf,
+ 0xc2be, 0xb4c1, 0xb4f7, 0xbba7, 0xece6, 0xece5, 0xb7bf, 0xcbf9,
+ 0xb1e2, 0xece7, 0xc9c8, 0xece8, 0xece9, 0xcad6, 0xded0, 0xb2c5,
+ 0xd4fa, 0xc6cb, 0xb0c7, 0xb4f2, 0xc8d3, 0xcdd0, 0xbfb8, 0xbfdb,
+ 0xc7a4, 0xd6b4, 0xc0a9, 0xded1, 0xc9a8, 0xd1ef, 0xc5a4, 0xb0e7,
+ 0xb3b6, 0xc8c5, 0xb0e2, 0xb7f6, 0xc5fa, 0xb6f3, 0xd5d2, 0xb3d0,
+ 0xbcbc, 0xb3ad, 0xbef1, 0xb0d1, 0xd2d6, 0xcae3, 0xd7a5, 0xcdb6,
+ 0xb6b6, 0xbfb9, 0xd5db, 0xb8a7, 0xc5d7, 0xded2, 0xbfd9, 0xc2d5,
+ 0xc7c0, 0xbba4, 0xb1a8, 0xc5ea, 0xc5fb, 0xcca7, 0xb1a7, 0xb5d6,
+ 0xc4a8, 0xded3, 0xd1ba, 0xb3e9, 0xc3f2, 0xb7f7, 0xd6f4, 0xb5a3,
+ 0xb2f0, 0xc4b4, 0xc4e9, 0xc0ad, 0xded4, 0xb0e8, 0xc5c4, 0xc1e0,
+ 0xb9d5, 0xbedc, 0xcdd8, 0xb0ce, 0xcdcf, 0xded6, 0xbed0, 0xd7be,
+ 0xded5, 0xd5d0, 0xb0dd, 0xc4e2, 0xc2a3, 0xbcf0, 0xd3b5, 0xc0b9,
+ 0xc5a1, 0xb2a6, 0xd4f1, 0xc0a8, 0xcac3, 0xded7, 0xd5fc, 0xb9b0,
+ 0xc8ad, 0xcba9, 0xded9, 0xbfbd, 0xc6b4, 0xd7a7, 0xcab0, 0xc4c3,
+ 0xb3d6, 0xb9d2, 0xd6b8, 0xeafc, 0xb0b4, 0xbfe6, 0xccf4, 0xcdda,
+ 0xd6bf, 0xc2ce, 0xcece, 0xcca2, 0xd0ae, 0xc4d3, 0xb5b2, 0xded8,
+ 0xd5f5, 0xbcb7, 0xbbd3, 0xb0a4, 0xc5b2, 0xb4ec, 0xd5f1, 0xeafd,
+ 0xdeda, 0xcda6, 0xcdec, 0xcee6, 0xdedc, 0xcdb1, 0xc0a6, 0xd7bd,
+ 0xdedb, 0xb0c6, 0xbab4, 0xc9d3, 0xc4f3, 0xbee8, 0xb2b6, 0xc0cc,
+ 0xcbf0, 0xbcf1, 0xbbbb, 0xb5b7, 0xc5f5, 0xdee6, 0xdee3, 0xbedd,
+ 0xdedf, 0xb4b7, 0xbddd, 0xdee0, 0xc4ed, 0xcfc6, 0xb5e0, 0xb6de,
+ 0xcada, 0xb5f4, 0xdee5, 0xd5c6, 0xdee1, 0xcccd, 0xc6fe, 0xc5c5,
+ 0xd2b4, 0xbef2, 0xc2d3, 0xccbd, 0xb3b8, 0xbdd3, 0xbfd8, 0xcdc6,
+ 0xd1da, 0xb4eb, 0xdee4, 0xdedd, 0xdee7, 0xeafe, 0xc2b0, 0xdee2,
+ 0xd6c0, 0xb5a7, 0xb2f4, 0xdee8, 0xdef2, 0xdeed, 0xdef1, 0xc8e0,
+ 0xd7e1, 0xdeef, 0xc3e8, 0xcce1, 0xb2e5, 0xd2be, 0xdeee, 0xdeeb,
+ 0xced5, 0xb4a7, 0xbfab, 0xbebe, 0xbdd2, 0xdee9, 0xd4ae, 0xdede,
+ 0xdeea, 0xc0bf, 0xdeec, 0xb2f3, 0xb8e9, 0xc2a7, 0xbdc1, 0xdef5,
+ 0xdef8, 0xb2ab, 0xb4a4, 0xb4ea, 0xc9a6, 0xdef6, 0xcbd1, 0xb8e3,
+ 0xdef7, 0xdefa, 0xdef9, 0xccc2, 0xb0e1, 0xb4ee, 0xe5ba, 0xd0af,
+ 0xb2eb, 0xeba1, 0xdef4, 0xc9e3, 0xdef3, 0xb0da, 0xd2a1, 0xb1f7,
+ 0xccaf, 0xdef0, 0xcba4, 0xd5aa, 0xdefb, 0xb4dd, 0xc4a6, 0xdefd,
+ 0xc3fe, 0xc4a1, 0xdfa1, 0xc1cc, 0xdefc, 0xbeef, 0xc6b2, 0xb3c5,
+ 0xc8f6, 0xcbba, 0xdefe, 0xdfa4, 0xd7b2, 0xb3b7, 0xc1c3, 0xc7cb,
+ 0xb2a5, 0xb4e9, 0xd7ab, 0xc4ec, 0xdfa2, 0xdfa3, 0xdfa5, 0xbab3,
+ 0xdfa6, 0xc0de, 0xc9c3, 0xb2d9, 0xc7e6, 0xdfa7, 0xc7dc, 0xdfa8,
+ 0xeba2, 0xcbd3, 0xdfaa, 0xdfa9, 0xb2c1, 0xc5ca, 0xdfab, 0xd4dc,
+ 0xc8c1, 0xdfac, 0xbef0, 0xdfad, 0xd6a7, 0xeab7, 0xebb6, 0xcad5,
+ 0xd8fc, 0xb8c4, 0xb9a5, 0xb7c5, 0xd5fe, 0xb9ca, 0xd0a7, 0xf4cd,
+ 0xb5d0, 0xc3f4, 0xbec8, 0xebb7, 0xb0bd, 0xbdcc, 0xc1b2, 0xb1d6,
+ 0xb3a8, 0xb8d2, 0xc9a2, 0xb6d8, 0xebb8, 0xbeb4, 0xcafd, 0xc7c3,
+ 0xd5fb, 0xb7f3, 0xcec4, 0xd5ab, 0xb1f3, 0xecb3, 0xb0df, 0xecb5,
+ 0xb6b7, 0xc1cf, 0xf5fa, 0xd0b1, 0xd5e5, 0xced3, 0xbdef, 0xb3e2,
+ 0xb8ab, 0xd5b6, 0xedbd, 0xb6cf, 0xcbb9, 0xd0c2, 0xb7bd, 0xecb6,
+ 0xcaa9, 0xc5d4, 0xecb9, 0xecb8, 0xc2c3, 0xecb7, 0xd0fd, 0xecba,
+ 0xecbb, 0xd7e5, 0xecbc, 0xecbd, 0xc6ec, 0xcede, 0xbcc8, 0xc8d5,
+ 0xb5a9, 0xbec9, 0xd6bc, 0xd4e7, 0xd1ae, 0xd0f1, 0xeab8, 0xeab9,
+ 0xeaba, 0xbab5, 0xcab1, 0xbff5, 0xcdfa, 0xeac0, 0xb0ba, 0xeabe,
+ 0xc0a5, 0xeabb, 0xb2fd, 0xc3f7, 0xbbe8, 0xd2d7, 0xcef4, 0xeabf,
+ 0xeabc, 0xeac3, 0xd0c7, 0xd3b3, 0xb4ba, 0xc3c1, 0xd7f2, 0xd5d1,
+ 0xcac7, 0xeac5, 0xeac4, 0xeac7, 0xeac6, 0xd6e7, 0xcfd4, 0xeacb,
+ 0xbbce, 0xbdfa, 0xc9ce, 0xeacc, 0xc9b9, 0xcffe, 0xeaca, 0xd4ce,
+ 0xeacd, 0xeacf, 0xcded, 0xeac9, 0xeace, 0xceee, 0xbbde, 0xb3bf,
+ 0xc6d5, 0xbeb0, 0xcefa, 0xc7e7, 0xbea7, 0xead0, 0xd6c7, 0xc1c0,
+ 0xd4dd, 0xead1, 0xcfbe, 0xead2, 0xcaee, 0xc5af, 0xb0b5, 0xead4,
+ 0xead3, 0xf4df, 0xc4ba, 0xb1a9, 0xe5df, 0xead5, 0xcaef, 0xead6,
+ 0xead7, 0xc6d8, 0xead8, 0xead9, 0xd4bb, 0xc7fa, 0xd2b7, 0xb8fc,
+ 0xeac2, 0xb2dc, 0xc2fc, 0xd4f8, 0xcce6, 0xd7ee, 0xd4c2, 0xd3d0,
+ 0xebc3, 0xc5f3, 0xb7fe, 0xebd4, 0xcbb7, 0xebde, 0xc0ca, 0xcdfb,
+ 0xb3af, 0xc6da, 0xebfc, 0xc4be, 0xceb4, 0xc4a9, 0xb1be, 0xd4fd,
+ 0xcaf5, 0xd6ec, 0xc6d3, 0xb6e4, 0xbbfa, 0xd0e0, 0xc9b1, 0xd4d3,
+ 0xc8a8, 0xb8cb, 0xe8be, 0xc9bc, 0xe8bb, 0xc0ee, 0xd0d3, 0xb2c4,
+ 0xb4e5, 0xe8bc, 0xd5c8, 0xb6c5, 0xe8bd, 0xcaf8, 0xb8dc, 0xccf5,
+ 0xc0b4, 0xd1ee, 0xe8bf, 0xe8c2, 0xbabc, 0xb1ad, 0xbddc, 0xeabd,
+ 0xe8c3, 0xe8c6, 0xe8cb, 0xe8cc, 0xcbc9, 0xb0e5, 0xbcab, 0xb9b9,
+ 0xe8c1, 0xcdf7, 0xe8ca, 0xcef6, 0xd5ed, 0xc1d6, 0xe8c4, 0xc3b6,
+ 0xb9fb, 0xd6a6, 0xe8c8, 0xcae0, 0xd4e6, 0xe8c0, 0xe8c5, 0xe8c7,
+ 0xc7b9, 0xb7e3, 0xe8c9, 0xbfdd, 0xe8d2, 0xe8d7, 0xe8d5, 0xbcdc,
+ 0xbccf, 0xe8db, 0xe8de, 0xe8da, 0xb1fa, 0xb0d8, 0xc4b3, 0xb8cc,
+ 0xc6e2, 0xc8be, 0xc8e1, 0xe8cf, 0xe8d4, 0xe8d6, 0xb9f1, 0xe8d8,
+ 0xd7f5, 0xc4fb, 0xe8dc, 0xb2e9, 0xe8d1, 0xbced, 0xbfc2, 0xe8cd,
+ 0xd6f9, 0xc1f8, 0xb2f1, 0xe8df, 0xcac1, 0xe8d9, 0xd5a4, 0xb1ea,
+ 0xd5bb, 0xe8ce, 0xe8d0, 0xb6b0, 0xe8d3, 0xe8dd, 0xc0b8, 0xcaf7,
+ 0xcba8, 0xc6dc, 0xc0f5, 0xe8e9, 0xd0a3, 0xe8f2, 0xd6ea, 0xe8e0,
+ 0xe8e1, 0xd1f9, 0xbacb, 0xb8f9, 0xb8f1, 0xd4d4, 0xe8ef, 0xe8ee,
+ 0xe8ec, 0xb9f0, 0xccd2, 0xe8e6, 0xcea6, 0xbff2, 0xb0b8, 0xe8f1,
+ 0xe8f0, 0xd7c0, 0xe8e4, 0xcda9, 0xc9a3, 0xbbb8, 0xbddb, 0xe8ea,
+ 0xe8e2, 0xe8e3, 0xe8e5, 0xb5b5, 0xe8e7, 0xc7c5, 0xe8eb, 0xe8ed,
+ 0xbdb0, 0xd7ae, 0xe8f8, 0xe8f5, 0xcdb0, 0xe8f6, 0xc1ba, 0xe8e8,
+ 0xc3b7, 0xb0f0, 0xe8f4, 0xe8f7, 0xb9a3, 0xc9d2, 0xc3ce, 0xcee0,
+ 0xc0e6, 0xcbf3, 0xccdd, 0xd0b5, 0xcae1, 0xe8f3, 0xbcec, 0xe8f9,
+ 0xc3de, 0xc6e5, 0xb9f7, 0xb0f4, 0xd7d8, 0xbcac, 0xc5ef, 0xccc4,
+ 0xe9a6, 0xc9ad, 0xe9a2, 0xc0e2, 0xbfc3, 0xe8fe, 0xb9d7, 0xe8fb,
+ 0xe9a4, 0xd2ce, 0xe9a3, 0xd6b2, 0xd7b5, 0xe9a7, 0xbdb7, 0xe8fc,
+ 0xe8fd, 0xe9a1, 0xcdd6, 0xd2ac, 0xe9b2, 0xe9a9, 0xb4aa, 0xb4bb,
+ 0xe9ab, 0xd0a8, 0xe9a5, 0xb3fe, 0xe9ac, 0xc0e3, 0xe9aa, 0xe9b9,
+ 0xe9b8, 0xe9ae, 0xe8fa, 0xe9a8, 0xbfac, 0xe9b1, 0xe9ba, 0xc2a5,
+ 0xe9af, 0xb8c5, 0xe9ad, 0xd3dc, 0xe9b4, 0xe9b5, 0xe9b7, 0xe9c7,
+ 0xc0c6, 0xe9c5, 0xe9b0, 0xe9bb, 0xb0f1, 0xe9bc, 0xd5a5, 0xe9be,
+ 0xe9bf, 0xe9c1, 0xc1f1, 0xc8b6, 0xe9bd, 0xe9c2, 0xe9c3, 0xe9b3,
+ 0xe9b6, 0xbbb1, 0xe9c0, 0xbcf7, 0xe9c4, 0xe9c6, 0xe9ca, 0xe9ce,
+ 0xb2db, 0xe9c8, 0xb7ae, 0xe9cb, 0xe9cc, 0xd5c1, 0xc4a3, 0xe9d8,
+ 0xbae1, 0xe9c9, 0xd3a3, 0xe9d4, 0xe9d7, 0xe9d0, 0xe9cf, 0xc7c1,
+ 0xe9d2, 0xe9d9, 0xb3c8, 0xe9d3, 0xcff0, 0xe9cd, 0xb3f7, 0xe9d6,
+ 0xe9da, 0xccb4, 0xcfad, 0xe9d5, 0xe9dc, 0xe9db, 0xe9de, 0xe9d1,
+ 0xe9dd, 0xe9df, 0xc3ca, 0xc7b7, 0xb4ce, 0xbbb6, 0xd0c0, 0xeca3,
+ 0xc5b7, 0xd3fb, 0xeca4, 0xeca5, 0xc6db, 0xbfee, 0xeca6, 0xeca7,
+ 0xd0aa, 0xc7b8, 0xb8e8, 0xeca8, 0xd6b9, 0xd5fd, 0xb4cb, 0xb2bd,
+ 0xcee4, 0xc6e7, 0xcde1, 0xb4f5, 0xcbc0, 0xbcdf, 0xe9e2, 0xe9e3,
+ 0xd1ea, 0xe9e5, 0xb4f9, 0xe9e4, 0xd1b3, 0xcae2, 0xb2d0, 0xe9e8,
+ 0xe9e6, 0xe9e7, 0xd6b3, 0xe9e9, 0xe9ea, 0xe9eb, 0xe9ec, 0xecaf,
+ 0xc5b9, 0xb6ce, 0xd2f3, 0xb5ee, 0xbbd9, 0xecb1, 0xd2e3, 0xcee3,
+ 0xc4b8, 0xc3bf, 0xb6be, 0xd8b9, 0xb1c8, 0xb1cf, 0xb1d1, 0xc5fe,
+ 0xb1d0, 0xc3ab, 0xd5b1, 0xeba4, 0xbac1, 0xccba, 0xeba5, 0xeba7,
+ 0xeba8, 0xeba6, 0xeba9, 0xebab, 0xebaa, 0xebac, 0xcacf, 0xd8b5,
+ 0xc3f1, 0xc3a5, 0xc6f8, 0xebad, 0xc4ca, 0xebae, 0xebaf, 0xebb0,
+ 0xb7d5, 0xb7fa, 0xebb1, 0xc7e2, 0xebb3, 0xbaa4, 0xd1f5, 0xb0b1,
+ 0xebb2, 0xebb4, 0xb5aa, 0xc2c8, 0xc7e8, 0xebb5, 0xcbae, 0xe3df,
+ 0xd3c0, 0xd9db, 0xcda1, 0xd6ad, 0xc7f3, 0xd9e0, 0xbbe3, 0xbaba,
+ 0xe3e2, 0xcfab, 0xe3e0, 0xc9c7, 0xbab9, 0xd1b4, 0xe3e1, 0xc8ea,
+ 0xb9af, 0xbdad, 0xb3d8, 0xcedb, 0xccc0, 0xe3e8, 0xe3e9, 0xcdf4,
+ 0xccad, 0xbcb3, 0xe3ea, 0xe3eb, 0xd0da, 0xc6fb, 0xb7da, 0xc7df,
+ 0xd2ca, 0xced6, 0xe3e4, 0xe3ec, 0xc9f2, 0xb3c1, 0xe3e7, 0xc6e3,
+ 0xe3e5, 0xedb3, 0xe3e6, 0xc9b3, 0xc5e6, 0xb9b5, 0xc3bb, 0xe3e3,
+ 0xc5bd, 0xc1a4, 0xc2d9, 0xb2d7, 0xe3ed, 0xbba6, 0xc4ad, 0xe3f0,
+ 0xbeda, 0xe3fb, 0xe3f5, 0xbad3, 0xb7d0, 0xd3cd, 0xd6ce, 0xd5d3,
+ 0xb9c1, 0xd5b4, 0xd1d8, 0xd0b9, 0xc7f6, 0xc8aa, 0xb2b4, 0xc3da,
+ 0xe3ee, 0xe3fc, 0xe3ef, 0xb7a8, 0xe3f7, 0xe3f4, 0xb7ba, 0xc5a2,
+ 0xe3f6, 0xc5dd, 0xb2a8, 0xc6fc, 0xc4e0, 0xd7a2, 0xc0e1, 0xe3f9,
+ 0xe3fa, 0xe3fd, 0xcca9, 0xe3f3, 0xd3be, 0xb1c3, 0xedb4, 0xe3f1,
+ 0xe3f2, 0xe3f8, 0xd0ba, 0xc6c3, 0xd4f3, 0xe3fe, 0xbde0, 0xe4a7,
+ 0xe4a6, 0xd1f3, 0xe4a3, 0xe4a9, 0xc8f7, 0xcfb4, 0xe4a8, 0xe4ae,
+ 0xc2e5, 0xb6b4, 0xbdf2, 0xe4a2, 0xbae9, 0xe4aa, 0xe4ac, 0xb6fd,
+ 0xd6de, 0xe4b2, 0xe4ad, 0xe4a1, 0xbbee, 0xcddd, 0xc7a2, 0xc5c9,
+ 0xc1f7, 0xe4a4, 0xc7b3, 0xbdac, 0xbdbd, 0xe4a5, 0xd7c7, 0xb2e2,
+ 0xe4ab, 0xbcc3, 0xe4af, 0xbbeb, 0xe4b0, 0xc5a8, 0xe4b1, 0xd5e3,
+ 0xbfa3, 0xe4ba, 0xe4b7, 0xe4bb, 0xe4bd, 0xc6d6, 0xbac6, 0xc0cb,
+ 0xb8a1, 0xe4b4, 0xd4a1, 0xbaa3, 0xbdfe, 0xe4bc, 0xcdbf, 0xc4f9,
+ 0xcffb, 0xc9e6, 0xd3bf, 0xcfd1, 0xe4b3, 0xe4b8, 0xe4b9, 0xcce9,
+ 0xccce, 0xc0d4, 0xe4b5, 0xc1b0, 0xe4b6, 0xced0, 0xbbc1, 0xb5d3,
+ 0xc8f3, 0xbda7, 0xd5c7, 0xc9ac, 0xb8a2, 0xe4ca, 0xe4cc, 0xd1c4,
+ 0xd2ba, 0xbaad, 0xbad4, 0xe4c3, 0xb5ed, 0xd7cd, 0xe4c0, 0xcffd,
+ 0xe4bf, 0xc1dc, 0xccca, 0xcae7, 0xc4d7, 0xccd4, 0xe4c8, 0xe4c7,
+ 0xe4c1, 0xe4c4, 0xb5ad, 0xd3d9, 0xe4c6, 0xd2f9, 0xb4e3, 0xbbb4,
+ 0xc9ee, 0xb4be, 0xbbec, 0xd1cd, 0xcced, 0xedb5, 0xc7e5, 0xd4a8,
+ 0xe4cb, 0xd7d5, 0xe4c2, 0xbda5, 0xe4c5, 0xd3e6, 0xe4c9, 0xc9f8,
+ 0xe4be, 0xd3e5, 0xc7fe, 0xb6c9, 0xd4fc, 0xb2b3, 0xe4d7, 0xcec2,
+ 0xe4cd, 0xcebc, 0xb8db, 0xe4d6, 0xbfca, 0xd3ce, 0xc3ec, 0xc5c8,
+ 0xe4d8, 0xcdc4, 0xe4cf, 0xe4d4, 0xe4d5, 0xbafe, 0xcfe6, 0xd5bf,
+ 0xe4d2, 0xe4d0, 0xe4ce, 0xcde5, 0xcaaa, 0xc0a3, 0xbda6, 0xe4d3,
+ 0xb8c8, 0xe4e7, 0xd4b4, 0xe4db, 0xc1ef, 0xe4e9, 0xd2e7, 0xe4df,
+ 0xe4e0, 0xcfaa, 0xcbdd, 0xe4da, 0xe4d1, 0xe4e5, 0xc8dc, 0xe4e3,
+ 0xc4e7, 0xe4e2, 0xe4e1, 0xb3fc, 0xe4e8, 0xb5e1, 0xd7cc, 0xe4e6,
+ 0xbbac, 0xd7d2, 0xcccf, 0xebf8, 0xe4e4, 0xb9f6, 0xd6cd, 0xe4d9,
+ 0xe4dc, 0xc2fa, 0xe4de, 0xc2cb, 0xc0c4, 0xc2d0, 0xb1f5, 0xccb2,
+ 0xb5ce, 0xe4ef, 0xc6af, 0xc6e1, 0xe4f5, 0xc2a9, 0xc0ec, 0xd1dd,
+ 0xe4ee, 0xc4ae, 0xe4ed, 0xe4f6, 0xe4f4, 0xc2fe, 0xe4dd, 0xe4f0,
+ 0xcafe, 0xd5c4, 0xe4f1, 0xd1fa, 0xe4eb, 0xe4ec, 0xe4f2, 0xceab,
+ 0xc5cb, 0xc7b1, 0xc2ba, 0xe4ea, 0xc1ca, 0xccb6, 0xb3b1, 0xe4fb,
+ 0xe4f3, 0xe4fa, 0xe4fd, 0xe4fc, 0xb3ce, 0xb3ba, 0xe4f7, 0xe4f9,
+ 0xe4f8, 0xc5ec, 0xc0bd, 0xd4e8, 0xe5a2, 0xb0c4, 0xe5a4, 0xe5a3,
+ 0xbca4, 0xe5a5, 0xe5a1, 0xe4fe, 0xb1f4, 0xe5a8, 0xe5a9, 0xe5a6,
+ 0xe5a7, 0xe5aa, 0xc6d9, 0xe5ab, 0xe5ad, 0xe5ac, 0xe5af, 0xe5ae,
+ 0xb9e0, 0xe5b0, 0xe5b1, 0xbbf0, 0xece1, 0xc3f0, 0xb5c6, 0xbbd2,
+ 0xc1e9, 0xd4ee, 0xbec4, 0xd7c6, 0xd4d6, 0xb2d3, 0xecbe, 0xeac1,
+ 0xc2af, 0xb4b6, 0xd1d7, 0xb3b4, 0xc8b2, 0xbfbb, 0xecc0, 0xd6cb,
+ 0xecbf, 0xecc1, 0xecc5, 0xbee6, 0xccbf, 0xc5da, 0xbebc, 0xecc6,
+ 0xb1fe, 0xecc4, 0xd5a8, 0xb5e3, 0xecc2, 0xc1b6, 0xb3e3, 0xecc3,
+ 0xcbb8, 0xc0c3, 0xccfe, 0xc1d2, 0xecc8, 0xbae6, 0xc0d3, 0xd6f2,
+ 0xd1cc, 0xbfbe, 0xb7b3, 0xc9d5, 0xecc7, 0xbbe2, 0xcccc, 0xbdfd,
+ 0xc8c8, 0xcfa9, 0xcde9, 0xc5eb, 0xb7e9, 0xd1c9, 0xbab8, 0xecc9,
+ 0xecca, 0xbbc0, 0xeccb, 0xece2, 0xb1ba, 0xb7d9, 0xbdb9, 0xeccc,
+ 0xd1e6, 0xeccd, 0xc8bb, 0xecd1, 0xecd3, 0xbbcd, 0xbce5, 0xeccf,
+ 0xc9b7, 0xc3ba, 0xece3, 0xd5d5, 0xecd0, 0xd6f3, 0xecd2, 0xecce,
+ 0xecd4, 0xecd5, 0xc9bf, 0xcfa8, 0xd0dc, 0xd1ac, 0xc8db, 0xecd6,
+ 0xcef5, 0xcaec, 0xecda, 0xecd9, 0xb0be, 0xecd7, 0xecd8, 0xece4,
+ 0xc8bc, 0xc1c7, 0xecdc, 0xd1e0, 0xecdb, 0xd4ef, 0xecdd, 0xdbc6,
+ 0xecde, 0xb1ac, 0xecdf, 0xece0, 0xd7a6, 0xc5c0, 0xebbc, 0xb0ae,
+ 0xbef4, 0xb8b8, 0xd2af, 0xb0d6, 0xb5f9, 0xd8b3, 0xcbac, 0xe3dd,
+ 0xc6ac, 0xb0e6, 0xc5c6, 0xebb9, 0xebba, 0xebbb, 0xd1c0, 0xc5a3,
+ 0xeaf2, 0xc4b2, 0xc4b5, 0xc0ce, 0xeaf3, 0xc4c1, 0xceef, 0xeaf0,
+ 0xeaf4, 0xc9fc, 0xc7a3, 0xccd8, 0xcefe, 0xeaf5, 0xeaf6, 0xcfac,
+ 0xc0e7, 0xeaf7, 0xb6bf, 0xeaf8, 0xeaf9, 0xeafa, 0xeafb, 0xeaf1,
+ 0xc8ae, 0xe1eb, 0xb7b8, 0xe1ec, 0xe1ed, 0xd7b4, 0xe1ee, 0xe1ef,
+ 0xd3cc, 0xe1f1, 0xbff1, 0xe1f0, 0xb5d2, 0xb1b7, 0xe1f3, 0xe1f2,
+ 0xbafc, 0xe1f4, 0xb9b7, 0xbed1, 0xc4fc, 0xbadd, 0xbdc6, 0xe1f5,
+ 0xe1f7, 0xb6c0, 0xcfc1, 0xcaa8, 0xe1f6, 0xd5f8, 0xd3fc, 0xe1f8,
+ 0xe1fc, 0xe1f9, 0xe1fa, 0xc0ea, 0xe1fe, 0xe2a1, 0xc0c7, 0xe1fb,
+ 0xe1fd, 0xe2a5, 0xc1d4, 0xe2a3, 0xe2a8, 0xb2fe, 0xe2a2, 0xc3cd,
+ 0xb2c2, 0xe2a7, 0xe2a6, 0xe2a4, 0xe2a9, 0xe2ab, 0xd0c9, 0xd6ed,
+ 0xc3a8, 0xe2ac, 0xcfd7, 0xe2ae, 0xbaef, 0xe9e0, 0xe2ad, 0xe2aa,
+ 0xbbab, 0xd4b3, 0xe2b0, 0xe2af, 0xe9e1, 0xe2b1, 0xe2b2, 0xe2b3,
+ 0xcca1, 0xe2b4, 0xe2b5, 0xd0fe, 0xc2ca, 0xd3f1, 0xcdf5, 0xe7e0,
+ 0xe7e1, 0xbec1, 0xc2ea, 0xe7e4, 0xe7e3, 0xcde6, 0xc3b5, 0xe7e2,
+ 0xbbb7, 0xcfd6, 0xc1e1, 0xe7e9, 0xe7e8, 0xe7f4, 0xb2a3, 0xe7ea,
+ 0xe7e6, 0xe7ec, 0xe7eb, 0xc9ba, 0xd5e4, 0xe7e5, 0xb7a9, 0xe7e7,
+ 0xe7ee, 0xe7f3, 0xd6e9, 0xe7ed, 0xe7f2, 0xe7f1, 0xb0e0, 0xe7f5,
+ 0xc7f2, 0xc0c5, 0xc0ed, 0xc1f0, 0xe7f0, 0xe7f6, 0xcbf6, 0xe8a2,
+ 0xe8a1, 0xd7c1, 0xe7fa, 0xe7f9, 0xe7fb, 0xe7f7, 0xe7fe, 0xe7fd,
+ 0xe7fc, 0xc1d5, 0xc7d9, 0xc5fd, 0xc5c3, 0xc7ed, 0xe8a3, 0xe8a6,
+ 0xe8a5, 0xe8a7, 0xbaf7, 0xe7f8, 0xe8a4, 0xc8f0, 0xc9aa, 0xe8a9,
+ 0xb9e5, 0xd1fe, 0xe8a8, 0xe8aa, 0xe8ad, 0xe8ae, 0xc1a7, 0xe8af,
+ 0xe8b0, 0xe8ac, 0xe8b4, 0xe8ab, 0xe8b1, 0xe8b5, 0xe8b2, 0xe8b3,
+ 0xe8b7, 0xe8b6, 0xb9cf, 0xf0ac, 0xf0ad, 0xc6b0, 0xb0ea, 0xc8bf,
+ 0xcddf, 0xcecd, 0xeab1, 0xeab2, 0xc6bf, 0xb4c9, 0xeab3, 0xd5e7,
+ 0xddf9, 0xeab4, 0xeab5, 0xeab6, 0xb8ca, 0xdfb0, 0xc9f5, 0xccf0,
+ 0xc9fa, 0xc9fb, 0xd3c3, 0xcba6, 0xb8a6, 0xf0ae, 0xb1c2, 0xe5b8,
+ 0xccef, 0xd3c9, 0xbcd7, 0xc9ea, 0xb5e7, 0xc4d0, 0xb5e9, 0xeeae,
+ 0xbbad, 0xe7de, 0xeeaf, 0xb3a9, 0xeeb2, 0xeeb1, 0xbde7, 0xeeb0,
+ 0xceb7, 0xc5cf, 0xc1f4, 0xdbce, 0xeeb3, 0xd0f3, 0xc2d4, 0xc6e8,
+ 0xb7ac, 0xeeb4, 0xb3eb, 0xbbfb, 0xeeb5, 0xe7dc, 0xeeb6, 0xbdae,
+ 0xf1e2, 0xcae8, 0xd2c9, 0xf0da, 0xf0db, 0xf0dc, 0xc1c6, 0xb8ed,
+ 0xbece, 0xf0de, 0xc5b1, 0xf0dd, 0xd1f1, 0xf0e0, 0xb0cc, 0xbdea,
+ 0xd2df, 0xf0df, 0xb4af, 0xb7e8, 0xf0e6, 0xf0e5, 0xc6a3, 0xf0e1,
+ 0xf0e2, 0xb4c3, 0xf0e3, 0xd5ee, 0xccdb, 0xbed2, 0xbcb2, 0xf0e8,
+ 0xf0e7, 0xf0e4, 0xb2a1, 0xd6a2, 0xd3b8, 0xbeb7, 0xc8ac, 0xf0ea,
+ 0xd1f7, 0xd6cc, 0xbadb, 0xf0e9, 0xb6bb, 0xcdb4, 0xc6a6, 0xc1a1,
+ 0xf0eb, 0xf0ee, 0xf0ed, 0xf0f0, 0xf0ec, 0xbbbe, 0xf0ef, 0xccb5,
+ 0xf0f2, 0xb3d5, 0xb1d4, 0xf0f3, 0xf0f4, 0xf0f6, 0xb4e1, 0xf0f1,
+ 0xf0f7, 0xf0fa, 0xf0f8, 0xf0f5, 0xf0fd, 0xf0f9, 0xf0fc, 0xf0fe,
+ 0xf1a1, 0xcec1, 0xf1a4, 0xf1a3, 0xc1f6, 0xf0fb, 0xcadd, 0xb4f1,
+ 0xb1f1, 0xccb1, 0xf1a6, 0xf1a7, 0xf1ac, 0xd5ce, 0xf1a9, 0xc8b3,
+ 0xf1a2, 0xf1ab, 0xf1a8, 0xf1a5, 0xf1aa, 0xb0a9, 0xf1ad, 0xf1af,
+ 0xf1b1, 0xf1b0, 0xf1ae, 0xd1a2, 0xf1b2, 0xf1b3, 0xb9ef, 0xb5c7,
+ 0xb0d7, 0xb0d9, 0xd4ed, 0xb5c4, 0xbdd4, 0xbbca, 0xf0a7, 0xb8de,
+ 0xf0a8, 0xb0a8, 0xf0a9, 0xcdee, 0xf0aa, 0xf0ab, 0xc6a4, 0xd6e5,
+ 0xf1e4, 0xf1e5, 0xc3f3, 0xd3db, 0xd6d1, 0xc5e8, 0xd3af, 0xd2e6,
+ 0xeec1, 0xb0bb, 0xd5b5, 0xd1ce, 0xbce0, 0xbad0, 0xbff8, 0xb8c7,
+ 0xb5c1, 0xc5cc, 0xcaa2, 0xc3cb, 0xeec2, 0xc4bf, 0xb6a2, 0xedec,
+ 0xc3a4, 0xd6b1, 0xcfe0, 0xedef, 0xc5ce, 0xb6dc, 0xcaa1, 0xeded,
+ 0xedf0, 0xedf1, 0xc3bc, 0xbfb4, 0xedee, 0xedf4, 0xedf2, 0xd5e6,
+ 0xc3df, 0xedf3, 0xedf6, 0xd5a3, 0xd1a3, 0xedf5, 0xc3d0, 0xedf7,
+ 0xbff4, 0xbeec, 0xedf8, 0xccf7, 0xd1db, 0xd7c5, 0xd5f6, 0xedfc,
+ 0xedfb, 0xedf9, 0xedfa, 0xedfd, 0xbea6, 0xcbaf, 0xeea1, 0xb6bd,
+ 0xeea2, 0xc4c0, 0xedfe, 0xbdde, 0xb2c7, 0xb6c3, 0xeea5, 0xd8ba,
+ 0xeea3, 0xeea6, 0xc3e9, 0xb3f2, 0xeea7, 0xeea4, 0xcfb9, 0xeea8,
+ 0xc2f7, 0xeea9, 0xeeaa, 0xdeab, 0xc6b3, 0xc7c6, 0xd6f5, 0xb5c9,
+ 0xcbb2, 0xeeab, 0xcdab, 0xeeac, 0xd5b0, 0xeead, 0xf6c4, 0xdbc7,
+ 0xb4a3, 0xc3ac, 0xf1e6, 0xcab8, 0xd2d3, 0xd6aa, 0xeff2, 0xbed8,
+ 0xbdc3, 0xeff3, 0xb6cc, 0xb0ab, 0xcaaf, 0xedb6, 0xedb7, 0xcef9,
+ 0xb7af, 0xbff3, 0xedb8, 0xc2eb, 0xc9b0, 0xedb9, 0xc6f6, 0xbfb3,
+ 0xedbc, 0xc5f8, 0xd1d0, 0xd7a9, 0xedba, 0xedbb, 0xd1e2, 0xedbf,
+ 0xedc0, 0xedc4, 0xedc8, 0xedc6, 0xedce, 0xd5e8, 0xedc9, 0xedc7,
+ 0xedbe, 0xc5e9, 0xc6c6, 0xc9e9, 0xd4d2, 0xedc1, 0xedc2, 0xedc3,
+ 0xedc5, 0xc0f9, 0xb4a1, 0xb9e8, 0xedd0, 0xedd1, 0xedca, 0xedcf,
+ 0xcef8, 0xcbb6, 0xedcc, 0xedcd, 0xcff5, 0xedd2, 0xc1f2, 0xd3b2,
+ 0xedcb, 0xc8b7, 0xbcef, 0xc5f0, 0xedd6, 0xb5ef, 0xc2b5, 0xb0ad,
+ 0xcbe9, 0xb1ae, 0xedd4, 0xcdeb, 0xb5e2, 0xedd5, 0xedd3, 0xedd7,
+ 0xb5fa, 0xedd8, 0xedd9, 0xeddc, 0xb1cc, 0xc5f6, 0xbcee, 0xedda,
+ 0xccbc, 0xb2ea, 0xeddb, 0xc4eb, 0xb4c5, 0xb0f5, 0xeddf, 0xc0da,
+ 0xb4e8, 0xc5cd, 0xeddd, 0xbfc4, 0xedde, 0xc4a5, 0xede0, 0xede1,
+ 0xede3, 0xc1d7, 0xbbc7, 0xbdb8, 0xede2, 0xede4, 0xede6, 0xede5,
+ 0xede7, 0xcabe, 0xecea, 0xc0f1, 0xc9e7, 0xeceb, 0xc6ee, 0xecec,
+ 0xc6ed, 0xeced, 0xecf0, 0xd7e6, 0xecf3, 0xecf1, 0xecee, 0xecef,
+ 0xd7a3, 0xc9f1, 0xcbee, 0xecf4, 0xecf2, 0xcfe9, 0xecf6, 0xc6b1,
+ 0xbcc0, 0xecf5, 0xb5bb, 0xbbf6, 0xecf7, 0xd9f7, 0xbdfb, 0xc2bb,
+ 0xecf8, 0xecf9, 0xb8a3, 0xecfa, 0xecfb, 0xecfc, 0xd3ed, 0xd8ae,
+ 0xc0eb, 0xc7dd, 0xbacc, 0xd0e3, 0xcbbd, 0xcdba, 0xb8d1, 0xb1fc,
+ 0xc7ef, 0xd6d6, 0xbfc6, 0xc3eb, 0xeff5, 0xc3d8, 0xd7e2, 0xeff7,
+ 0xb3d3, 0xc7d8, 0xd1ed, 0xd6c8, 0xeff8, 0xeff6, 0xbbfd, 0xb3c6,
+ 0xbdd5, 0xd2c6, 0xbbe0, 0xcfa1, 0xeffc, 0xeffb, 0xeff9, 0xb3cc,
+ 0xc9d4, 0xcbb0, 0xeffe, 0xb0de, 0xd6c9, 0xeffd, 0xb3ed, 0xf6d5,
+ 0xcec8, 0xf0a2, 0xf0a1, 0xb5be, 0xbcda, 0xbbfc, 0xb8e5, 0xc4c2,
+ 0xf0a3, 0xcbeb, 0xf0a6, 0xd1a8, 0xbebf, 0xc7ee, 0xf1b6, 0xf1b7,
+ 0xbfd5, 0xb4a9, 0xf1b8, 0xcdbb, 0xc7d4, 0xd5ad, 0xf1b9, 0xf1ba,
+ 0xc7cf, 0xd2a4, 0xd6cf, 0xf1bb, 0xbdd1, 0xb4b0, 0xbebd, 0xb4dc,
+ 0xced1, 0xbfdf, 0xf1bd, 0xbffa, 0xf1bc, 0xf1bf, 0xf1be, 0xf1c0,
+ 0xf1c1, 0xc1fe, 0xc1a2, 0xcafa, 0xd5be, 0xbeba, 0xbeb9, 0xd5c2,
+ 0xbfa2, 0xcdaf, 0xf1b5, 0xbddf, 0xb6cb, 0xd6f1, 0xf3c3, 0xf3c4,
+ 0xb8cd, 0xf3c6, 0xf3c7, 0xb0ca, 0xf3c5, 0xf3c9, 0xcbf1, 0xf3cb,
+ 0xd0a6, 0xb1ca, 0xf3c8, 0xf3cf, 0xb5d1, 0xf3d7, 0xf3d2, 0xf3d4,
+ 0xf3d3, 0xb7fb, 0xb1bf, 0xf3ce, 0xf3ca, 0xb5da, 0xf3d0, 0xf3d1,
+ 0xf3d5, 0xf3cd, 0xbce3, 0xc1fd, 0xf3d6, 0xf3da, 0xf3cc, 0xb5c8,
+ 0xbdee, 0xf3dc, 0xb7a4, 0xbff0, 0xd6fe, 0xcdb2, 0xb4f0, 0xb2df,
+ 0xf3d8, 0xf3d9, 0xc9b8, 0xf3dd, 0xf3de, 0xf3e1, 0xf3df, 0xf3e3,
+ 0xf3e2, 0xf3db, 0xbfea, 0xb3ef, 0xf3e0, 0xc7a9, 0xbcf2, 0xf3eb,
+ 0xb9bf, 0xf3e4, 0xb2ad, 0xbbfe, 0xcbe3, 0xf3ed, 0xf3e9, 0xb9dc,
+ 0xf3ee, 0xf3e5, 0xf3e6, 0xf3ea, 0xc2e1, 0xf3ec, 0xf3ef, 0xf3e8,
+ 0xbcfd, 0xcfe4, 0xf3f0, 0xf3e7, 0xf3f2, 0xd7ad, 0xc6aa, 0xf3f3,
+ 0xf3f1, 0xc2a8, 0xb8dd, 0xf3f5, 0xf3f4, 0xb4db, 0xf3f6, 0xf3f7,
+ 0xf3f8, 0xc0ba, 0xc0e9, 0xc5f1, 0xf3fb, 0xf3fa, 0xb4d8, 0xf3fe,
+ 0xf3f9, 0xf3fc, 0xf3fd, 0xf4a1, 0xf4a3, 0xbbc9, 0xf4a2, 0xf4a4,
+ 0xb2be, 0xf4a6, 0xf4a5, 0xbcae, 0xc3d7, 0xd9e1, 0xc0e0, 0xf4cc,
+ 0xd7d1, 0xb7db, 0xf4ce, 0xc1a3, 0xc6c9, 0xb4d6, 0xd5b3, 0xf4d0,
+ 0xf4cf, 0xf4d1, 0xcbda, 0xf4d2, 0xd4c1, 0xd6e0, 0xb7e0, 0xc1b8,
+ 0xc1bb, 0xf4d3, 0xbeac, 0xb4e2, 0xf4d4, 0xf4d5, 0xbeab, 0xf4d6,
+ 0xf4db, 0xf4d7, 0xf4da, 0xbafd, 0xf4d8, 0xf4d9, 0xb8e2, 0xccc7,
+ 0xf4dc, 0xb2da, 0xc3d3, 0xd4e3, 0xbfb7, 0xf4dd, 0xc5b4, 0xf4e9,
+ 0xcfb5, 0xcec9, 0xcbd8, 0xcbf7, 0xbdf4, 0xd7cf, 0xc0db, 0xd0f5,
+ 0xf4ea, 0xf4eb, 0xf4ec, 0xf7e3, 0xb7b1, 0xf4ed, 0xd7eb, 0xf4ee,
+ 0xe6f9, 0xbec0, 0xe6fa, 0xbaec, 0xe6fb, 0xcfcb, 0xe6fc, 0xd4bc,
+ 0xbcb6, 0xe6fd, 0xe6fe, 0xbccd, 0xc8d2, 0xceb3, 0xe7a1, 0xb4bf,
+ 0xe7a2, 0xc9b4, 0xb8d9, 0xc4c9, 0xd7dd, 0xc2da, 0xb7d7, 0xd6bd,
+ 0xcec6, 0xb7c4, 0xc5a6, 0xe7a3, 0xcfdf, 0xe7a4, 0xe7a5, 0xe7a6,
+ 0xc1b7, 0xd7e9, 0xc9f0, 0xcfb8, 0xd6af, 0xd6d5, 0xe7a7, 0xb0ed,
+ 0xe7a8, 0xe7a9, 0xc9dc, 0xd2ef, 0xbead, 0xe7aa, 0xb0f3, 0xc8de,
+ 0xbde1, 0xe7ab, 0xc8c6, 0xe7ac, 0xbbe6, 0xb8f8, 0xd1a4, 0xe7ad,
+ 0xc2e7, 0xbef8, 0xbdca, 0xcdb3, 0xe7ae, 0xe7af, 0xbeee, 0xd0e5,
+ 0xcbe7, 0xccd0, 0xbccc, 0xe7b0, 0xbca8, 0xd0f7, 0xe7b1, 0xd0f8,
+ 0xe7b2, 0xe7b3, 0xb4c2, 0xe7b4, 0xe7b5, 0xc9fe, 0xceac, 0xc3e0,
+ 0xe7b7, 0xb1c1, 0xb3f1, 0xe7b8, 0xe7b9, 0xd7db, 0xd5c0, 0xe7ba,
+ 0xc2cc, 0xd7ba, 0xe7bb, 0xe7bc, 0xe7bd, 0xbcea, 0xc3e5, 0xc0c2,
+ 0xe7be, 0xe7bf, 0xbca9, 0xe7c0, 0xe7c1, 0xe7b6, 0xb6d0, 0xe7c2,
+ 0xe7c3, 0xe7c4, 0xbbba, 0xb5de, 0xc2c6, 0xb1e0, 0xe7c5, 0xd4b5,
+ 0xe7c6, 0xb8bf, 0xe7c8, 0xe7c7, 0xb7ec, 0xe7c9, 0xb2f8, 0xe7ca,
+ 0xe7cb, 0xe7cc, 0xe7cd, 0xe7ce, 0xe7cf, 0xe7d0, 0xd3a7, 0xcbf5,
+ 0xe7d1, 0xe7d2, 0xe7d3, 0xe7d4, 0xc9c9, 0xe7d5, 0xe7d6, 0xe7d7,
+ 0xe7d8, 0xe7d9, 0xbdc9, 0xe7da, 0xf3be, 0xb8d7, 0xc8b1, 0xf3bf,
+ 0xf3c0, 0xf3c1, 0xb9de, 0xcdf8, 0xd8e8, 0xbab1, 0xc2de, 0xeeb7,
+ 0xb7a3, 0xeeb9, 0xeeb8, 0xb0d5, 0xeebb, 0xd5d6, 0xd7ef, 0xd6c3,
+ 0xeebd, 0xcaf0, 0xeebc, 0xeebe, 0xeec0, 0xeebf, 0xd1f2, 0xc7bc,
+ 0xc3c0, 0xb8e1, 0xc1e7, 0xf4c6, 0xd0df, 0xf4c7, 0xcfdb, 0xc8ba,
+ 0xf4c8, 0xf4c9, 0xf4ca, 0xf4cb, 0xd9fa, 0xb8fe, 0xe5f1, 0xd3f0,
+ 0xf4e0, 0xcecc, 0xb3e1, 0xf1b4, 0xd2ee, 0xf4e1, 0xcfe8, 0xf4e2,
+ 0xc7cc, 0xb5d4, 0xb4e4, 0xf4e4, 0xf4e3, 0xf4e5, 0xf4e6, 0xf4e7,
+ 0xbab2, 0xb0bf, 0xf4e8, 0xb7ad, 0xd2ed, 0xd2ab, 0xc0cf, 0xbfbc,
+ 0xeba3, 0xd5df, 0xeac8, 0xf1f3, 0xb6f8, 0xcba3, 0xc4cd, 0xf1e7,
+ 0xf1e8, 0xb8fb, 0xf1e9, 0xbac4, 0xd4c5, 0xb0d2, 0xf1ea, 0xf1eb,
+ 0xf1ec, 0xf1ed, 0xf1ee, 0xf1ef, 0xf1f1, 0xf1f0, 0xc5d5, 0xf1f2,
+ 0xb6fa, 0xf1f4, 0xd2ae, 0xdec7, 0xcbca, 0xb3dc, 0xb5a2, 0xb9a2,
+ 0xc4f4, 0xf1f5, 0xf1f6, 0xc1c4, 0xc1fb, 0xd6b0, 0xf1f7, 0xf1f8,
+ 0xc1aa, 0xc6b8, 0xbedb, 0xf1f9, 0xb4cf, 0xf1fa, 0xedb2, 0xedb1,
+ 0xcbe0, 0xd2de, 0xcbc1, 0xd5d8, 0xc8e2, 0xc0df, 0xbca1, 0xebc1,
+ 0xd0a4, 0xd6e2, 0xb6c7, 0xb8d8, 0xebc0, 0xb8ce, 0xebbf, 0xb3a6,
+ 0xb9c9, 0xd6ab, 0xb7f4, 0xb7ca, 0xbce7, 0xb7be, 0xebc6, 0xebc7,
+ 0xb0b9, 0xbfcf, 0xebc5, 0xd3fd, 0xebc8, 0xebc9, 0xb7ce, 0xebc2,
+ 0xebc4, 0xc9f6, 0xd6d7, 0xd5cd, 0xd0b2, 0xebcf, 0xceb8, 0xebd0,
+ 0xb5a8, 0xb1b3, 0xebd2, 0xcca5, 0xc5d6, 0xebd3, 0xebd1, 0xc5df,
+ 0xebce, 0xcaa4, 0xebd5, 0xb0fb, 0xbafa, 0xd8b7, 0xf1e3, 0xebca,
+ 0xebcb, 0xebcc, 0xebcd, 0xebd6, 0xe6c0, 0xebd9, 0xbfe8, 0xd2c8,
+ 0xebd7, 0xebdc, 0xb8ec, 0xebd8, 0xbdba, 0xd0d8, 0xb0b7, 0xebdd,
+ 0xc4dc, 0xd6ac, 0xb4e0, 0xc2f6, 0xbcb9, 0xebda, 0xebdb, 0xd4e0,
+ 0xc6ea, 0xc4d4, 0xebdf, 0xc5a7, 0xd9f5, 0xb2b1, 0xebe4, 0xbdc5,
+ 0xebe2, 0xebe3, 0xb8ac, 0xcdd1, 0xebe5, 0xebe1, 0xc1b3, 0xc6a2,
+ 0xccf3, 0xebe6, 0xc0b0, 0xd2b8, 0xebe7, 0xb8af, 0xb8ad, 0xebe8,
+ 0xc7bb, 0xcdf3, 0xebea, 0xebeb, 0xebed, 0xd0c8, 0xebf2, 0xebee,
+ 0xebf1, 0xc8f9, 0xd1fc, 0xebec, 0xebe9, 0xb8b9, 0xcfd9, 0xc4e5,
+ 0xebef, 0xebf0, 0xccda, 0xcdc8, 0xb0f2, 0xebf6, 0xebf5, 0xb2b2,
+ 0xb8e0, 0xebf7, 0xb1ec, 0xccc5, 0xc4a4, 0xcfa5, 0xebf9, 0xeca2,
+ 0xc5f2, 0xebfa, 0xc9c5, 0xe2df, 0xebfe, 0xcdce, 0xeca1, 0xb1db,
+ 0xd3b7, 0xd2dc, 0xebfd, 0xebfb, 0xb3bc, 0xeab0, 0xd7d4, 0xf4ab,
+ 0xb3f4, 0xd6c1, 0xd6c2, 0xd5e9, 0xbeca, 0xf4a7, 0xd2a8, 0xf4a8,
+ 0xf4a9, 0xf4aa, 0xbecb, 0xd3df, 0xc9e0, 0xc9e1, 0xf3c2, 0xcae6,
+ 0xccf2, 0xe2b6, 0xcbb4, 0xcee8, 0xd6db, 0xf4ad, 0xf4ae, 0xf4af,
+ 0xf4b2, 0xbabd, 0xf4b3, 0xb0e3, 0xf4b0, 0xf4b1, 0xbda2, 0xb2d5,
+ 0xf4b6, 0xf4b7, 0xb6e6, 0xb2b0, 0xcfcf, 0xf4b4, 0xb4ac, 0xf4b5,
+ 0xf4b8, 0xf4b9, 0xcda7, 0xf4ba, 0xf4bb, 0xf4bc, 0xcbd2, 0xf4bd,
+ 0xf4be, 0xf4bf, 0xf4de, 0xc1bc, 0xbce8, 0xc9ab, 0xd1de, 0xe5f5,
+ 0xdcb3, 0xd2d5, 0xdcb4, 0xb0ac, 0xdcb5, 0xbdda, 0xdcb9, 0xd8c2,
+ 0xdcb7, 0xd3f3, 0xc9d6, 0xdcba, 0xdcb6, 0xdcbb, 0xc3a2, 0xdcbc,
+ 0xdcc5, 0xdcbd, 0xcedf, 0xd6a5, 0xdccf, 0xdccd, 0xdcd2, 0xbde6,
+ 0xc2ab, 0xdcb8, 0xdccb, 0xdcce, 0xdcbe, 0xb7d2, 0xb0c5, 0xdcc7,
+ 0xd0be, 0xdcc1, 0xbba8, 0xb7bc, 0xdccc, 0xdcc6, 0xdcbf, 0xc7db,
+ 0xd1bf, 0xdcc0, 0xdcca, 0xdcd0, 0xcead, 0xdcc2, 0xdcc3, 0xdcc8,
+ 0xdcc9, 0xb2d4, 0xdcd1, 0xcbd5, 0xd4b7, 0xdcdb, 0xdcdf, 0xcca6,
+ 0xdce6, 0xc3e7, 0xdcdc, 0xbfc1, 0xdcd9, 0xb0fa, 0xb9b6, 0xdce5,
+ 0xdcd3, 0xdcc4, 0xdcd6, 0xc8f4, 0xbfe0, 0xc9bb, 0xb1bd, 0xd3a2,
+ 0xdcda, 0xdcd5, 0xc6bb, 0xdcde, 0xd7c2, 0xc3af, 0xb7b6, 0xc7d1,
+ 0xc3a9, 0xdce2, 0xdcd8, 0xdceb, 0xdcd4, 0xdcdd, 0xbea5, 0xdcd7,
+ 0xdce0, 0xdce3, 0xdce4, 0xdcf8, 0xdce1, 0xdda2, 0xdce7, 0xbceb,
+ 0xb4c4, 0xc3a3, 0xb2e7, 0xdcfa, 0xdcf2, 0xdcef, 0xdcfc, 0xdcee,
+ 0xd2f0, 0xb2e8, 0xc8d7, 0xc8e3, 0xdcfb, 0xdced, 0xdcf7, 0xdcf5,
+ 0xbea3, 0xdcf4, 0xb2dd, 0xdcf3, 0xbcf6, 0xdce8, 0xbbc4, 0xc0f3,
+ 0xbcd4, 0xdce9, 0xdcea, 0xdcf1, 0xdcf6, 0xdcf9, 0xb5b4, 0xc8d9,
+ 0xbbe7, 0xdcfe, 0xdcfd, 0xd3ab, 0xdda1, 0xdda3, 0xdda5, 0xd2f1,
+ 0xdda4, 0xdda6, 0xdda7, 0xd2a9, 0xbac9, 0xdda9, 0xddb6, 0xddb1,
+ 0xddb4, 0xddb0, 0xc6ce, 0xc0f2, 0xc9af, 0xdcec, 0xddae, 0xddb7,
+ 0xdcf0, 0xddaf, 0xddb8, 0xddac, 0xddb9, 0xddb3, 0xddad, 0xc4aa,
+ 0xdda8, 0xc0b3, 0xc1ab, 0xddaa, 0xddab, 0xddb2, 0xbbf1, 0xddb5,
+ 0xd3a8, 0xddba, 0xddbb, 0xc3a7, 0xddd2, 0xddbc, 0xddd1, 0xb9bd,
+ 0xbed5, 0xbefa, 0xbaca, 0xddca, 0xddc5, 0xddbf, 0xb2cb, 0xddc3,
+ 0xddcb, 0xb2a4, 0xddd5, 0xddbe, 0xc6d0, 0xddd0, 0xddd4, 0xc1e2,
+ 0xb7c6, 0xddce, 0xddcf, 0xddc4, 0xddbd, 0xddcd, 0xccd1, 0xddc9,
+ 0xddc2, 0xc3c8, 0xc6bc, 0xceae, 0xddcc, 0xddc8, 0xddc1, 0xddc6,
+ 0xc2dc, 0xd3a9, 0xd3aa, 0xddd3, 0xcff4, 0xc8f8, 0xdde6, 0xddc7,
+ 0xdde0, 0xc2e4, 0xdde1, 0xddd7, 0xd6f8, 0xddd9, 0xddd8, 0xb8f0,
+ 0xddd6, 0xc6cf, 0xb6ad, 0xdde2, 0xbaf9, 0xd4e1, 0xdde7, 0xb4d0,
+ 0xddda, 0xbffb, 0xdde3, 0xdddf, 0xdddd, 0xb5d9, 0xdddb, 0xdddc,
+ 0xddde, 0xbdaf, 0xdde4, 0xdde5, 0xddf5, 0xc3c9, 0xcbe2, 0xddf2,
+ 0xd8e1, 0xc6d1, 0xddf4, 0xd5f4, 0xddf3, 0xddf0, 0xddec, 0xddef,
+ 0xdde8, 0xd0ee, 0xc8d8, 0xddee, 0xdde9, 0xddea, 0xcbf2, 0xdded,
+ 0xb1cd, 0xc0b6, 0xbcbb, 0xddf1, 0xddf7, 0xddf6, 0xddeb, 0xc5ee,
+ 0xddfb, 0xdea4, 0xdea3, 0xddf8, 0xc3ef, 0xc2fb, 0xd5e1, 0xceb5,
+ 0xddfd, 0xb2cc, 0xc4e8, 0xcadf, 0xc7be, 0xddfa, 0xddfc, 0xddfe,
+ 0xdea2, 0xb0aa, 0xb1ce, 0xdeac, 0xdea6, 0xbdb6, 0xc8ef, 0xdea1,
+ 0xdea5, 0xdea9, 0xdea8, 0xdea7, 0xdead, 0xd4cc, 0xdeb3, 0xdeaa,
+ 0xdeae, 0xc0d9, 0xb1a1, 0xdeb6, 0xdeb1, 0xdeb2, 0xd1a6, 0xdeb5,
+ 0xdeaf, 0xdeb0, 0xd0bd, 0xdeb4, 0xcaed, 0xdeb9, 0xdeb8, 0xdeb7,
+ 0xdebb, 0xbde5, 0xb2d8, 0xc3ea, 0xdeba, 0xc5ba, 0xdebc, 0xccd9,
+ 0xb7aa, 0xd4e5, 0xdebd, 0xdebf, 0xc4a2, 0xdec1, 0xdebe, 0xdec0,
+ 0xd5ba, 0xdec2, 0xf2ae, 0xbba2, 0xc2b2, 0xc5b0, 0xc2c7, 0xf2af,
+ 0xd0e9, 0xd3dd, 0xebbd, 0xb3e6, 0xf2b0, 0xf2b1, 0xcaad, 0xbae7,
+ 0xf2b3, 0xf2b5, 0xf2b4, 0xcbe4, 0xcfba, 0xf2b2, 0xcab4, 0xd2cf,
+ 0xc2ec, 0xcec3, 0xf2b8, 0xb0f6, 0xf2b7, 0xf2be, 0xb2cf, 0xd1c1,
+ 0xf2ba, 0xf2bc, 0xd4e9, 0xf2bb, 0xf2b6, 0xf2bf, 0xf2bd, 0xf2b9,
+ 0xf2c7, 0xf2c4, 0xf2c6, 0xf2ca, 0xf2c2, 0xf2c0, 0xf2c5, 0xd6fb,
+ 0xf2c1, 0xc7f9, 0xc9df, 0xf2c8, 0xb9c6, 0xb5b0, 0xf2c3, 0xf2c9,
+ 0xf2d0, 0xf2d6, 0xbbd7, 0xf2d5, 0xcddc, 0xd6eb, 0xf2d2, 0xf2d4,
+ 0xb8f2, 0xf2cb, 0xf2ce, 0xc2f9, 0xd5dd, 0xf2cc, 0xf2cd, 0xf2cf,
+ 0xf2d3, 0xf2d9, 0xd3bc, 0xb6ea, 0xcaf1, 0xb7e4, 0xf2d7, 0xf2d8,
+ 0xf2da, 0xf2dd, 0xf2db, 0xf2dc, 0xd1d1, 0xf2d1, 0xcdc9, 0xcecf,
+ 0xd6a9, 0xf2e3, 0xc3db, 0xf2e0, 0xc0af, 0xf2ec, 0xf2de, 0xf2e1,
+ 0xf2e8, 0xf2e2, 0xf2e7, 0xf2e6, 0xf2e9, 0xf2df, 0xf2e4, 0xf2ea,
+ 0xd3ac, 0xf2e5, 0xb2f5, 0xf2f2, 0xd0ab, 0xf2f5, 0xbbc8, 0xf2f9,
+ 0xf2f0, 0xf2f6, 0xf2f8, 0xf2fa, 0xf2f3, 0xf2f1, 0xbafb, 0xb5fb,
+ 0xf2ef, 0xf2f7, 0xf2ed, 0xf2ee, 0xf2eb, 0xf3a6, 0xf3a3, 0xf3a2,
+ 0xf2f4, 0xc8da, 0xf2fb, 0xf3a5, 0xc3f8, 0xf2fd, 0xf3a7, 0xf3a9,
+ 0xf3a4, 0xf2fc, 0xf3ab, 0xf3aa, 0xc2dd, 0xf3ae, 0xf3b0, 0xf3a1,
+ 0xf3b1, 0xf3ac, 0xf3af, 0xf2fe, 0xf3ad, 0xf3b2, 0xf3b4, 0xf3a8,
+ 0xf3b3, 0xf3b5, 0xd0b7, 0xf3b8, 0xd9f9, 0xf3b9, 0xf3b7, 0xc8e4,
+ 0xf3b6, 0xf3ba, 0xf3bb, 0xb4c0, 0xeec3, 0xf3bc, 0xf3bd, 0xd1aa,
+ 0xf4ac, 0xd0c6, 0xd0d0, 0xd1dc, 0xcfce, 0xbdd6, 0xd1c3, 0xbae2,
+ 0xe1e9, 0xd2c2, 0xf1c2, 0xb2b9, 0xb1ed, 0xf1c3, 0xc9c0, 0xb3c4,
+ 0xd9f2, 0xcba5, 0xf1c4, 0xd6d4, 0xf1c5, 0xf4c0, 0xf1c6, 0xd4ac,
+ 0xf1c7, 0xb0c0, 0xf4c1, 0xf4c2, 0xb4fc, 0xc5db, 0xccbb, 0xd0e4,
+ 0xcde0, 0xf1c8, 0xd9f3, 0xb1bb, 0xcfae, 0xb8a4, 0xf1ca, 0xf1cb,
+ 0xb2c3, 0xc1d1, 0xd7b0, 0xf1c9, 0xf1cc, 0xf1ce, 0xd9f6, 0xd2e1,
+ 0xd4a3, 0xf4c3, 0xc8b9, 0xf4c4, 0xf1cd, 0xf1cf, 0xbfe3, 0xf1d0,
+ 0xf1d4, 0xf1d6, 0xf1d1, 0xc9d1, 0xc5e1, 0xc2e3, 0xb9fc, 0xf1d3,
+ 0xf1d5, 0xb9d3, 0xf1db, 0xbad6, 0xb0fd, 0xf1d9, 0xf1d8, 0xf1d2,
+ 0xf1da, 0xf1d7, 0xc8ec, 0xcdca, 0xf1dd, 0xe5bd, 0xf1dc, 0xf1de,
+ 0xf1df, 0xcfe5, 0xf4c5, 0xbdf3, 0xf1e0, 0xf1e1, 0xcef7, 0xd2aa,
+ 0xf1fb, 0xb8b2, 0xbcfb, 0xb9db, 0xb9e6, 0xc3d9, 0xcad3, 0xeae8,
+ 0xc0c0, 0xbef5, 0xeae9, 0xeaea, 0xeaeb, 0xeaec, 0xeaed, 0xeaee,
+ 0xeaef, 0xbdc7, 0xf5fb, 0xf5fd, 0xf5fe, 0xf5fc, 0xbde2, 0xf6a1,
+ 0xb4a5, 0xf6a2, 0xf6a3, 0xecb2, 0xd1d4, 0xd9ea, 0xf6a4, 0xeeba,
+ 0xd5b2, 0xd3fe, 0xccdc, 0xcac4, 0xe5c0, 0xf6a5, 0xbeaf, 0xc6a9,
+ 0xdaa5, 0xbcc6, 0xb6a9, 0xb8bc, 0xc8cf, 0xbca5, 0xdaa6, 0xdaa7,
+ 0xccd6, 0xc8c3, 0xdaa8, 0xc6fd, 0xd1b5, 0xd2e9, 0xd1b6, 0xbcc7,
+ 0xbdb2, 0xbbe4, 0xdaa9, 0xdaaa, 0xd1c8, 0xdaab, 0xd0ed, 0xb6ef,
+ 0xc2db, 0xcbcf, 0xb7ed, 0xc9e8, 0xb7c3, 0xbef7, 0xd6a4, 0xdaac,
+ 0xdaad, 0xc6c0, 0xd7e7, 0xcab6, 0xd5a9, 0xcbdf, 0xd5ef, 0xdaae,
+ 0xd6df, 0xb4ca, 0xdab0, 0xdaaf, 0xd2eb, 0xdab1, 0xdab2, 0xdab3,
+ 0xcad4, 0xdab4, 0xcaab, 0xdab5, 0xdab6, 0xb3cf, 0xd6ef, 0xdab7,
+ 0xbbb0, 0xb5ae, 0xdab8, 0xdab9, 0xb9ee, 0xd1af, 0xd2e8, 0xdaba,
+ 0xb8c3, 0xcfea, 0xb2ef, 0xdabb, 0xdabc, 0xbdeb, 0xcedc, 0xd3ef,
+ 0xdabd, 0xcef3, 0xdabe, 0xd3d5, 0xbbe5, 0xdabf, 0xcbb5, 0xcbd0,
+ 0xdac0, 0xc7eb, 0xd6ee, 0xdac1, 0xc5b5, 0xb6c1, 0xdac2, 0xb7cc,
+ 0xbfce, 0xdac3, 0xdac4, 0xcbad, 0xdac5, 0xb5f7, 0xdac6, 0xc1c2,
+ 0xd7bb, 0xdac7, 0xccb8, 0xd2ea, 0xc4b1, 0xdac8, 0xb5fd, 0xbbd1,
+ 0xdac9, 0xd0b3, 0xdaca, 0xdacb, 0xcebd, 0xdacc, 0xdacd, 0xdace,
+ 0xb2f7, 0xdad1, 0xdacf, 0xd1e8, 0xdad0, 0xc3d5, 0xdad2, 0xdad3,
+ 0xdad4, 0xdad5, 0xd0bb, 0xd2a5, 0xb0f9, 0xdad6, 0xc7ab, 0xdad7,
+ 0xbdf7, 0xc3a1, 0xdad8, 0xdad9, 0xc3fd, 0xccb7, 0xdada, 0xdadb,
+ 0xc0be, 0xc6d7, 0xdadc, 0xdadd, 0xc7b4, 0xdade, 0xdadf, 0xb9c8,
+ 0xbbed, 0xb6b9, 0xf4f8, 0xf4f9, 0xcde3, 0xf5b9, 0xebe0, 0xcff3,
+ 0xbbbf, 0xbac0, 0xd4a5, 0xe1d9, 0xf5f4, 0xb1aa, 0xb2f2, 0xf5f5,
+ 0xf5f7, 0xbad1, 0xf5f6, 0xc3b2, 0xf5f9, 0xf5f8, 0xb1b4, 0xd5ea,
+ 0xb8ba, 0xb9b1, 0xb2c6, 0xd4f0, 0xcfcd, 0xb0dc, 0xd5cb, 0xbbf5,
+ 0xd6ca, 0xb7b7, 0xccb0, 0xc6b6, 0xb1e1, 0xb9ba, 0xd6fc, 0xb9e1,
+ 0xb7a1, 0xbcfa, 0xeada, 0xeadb, 0xccf9, 0xb9f3, 0xeadc, 0xb4fb,
+ 0xc3b3, 0xb7d1, 0xbad8, 0xeadd, 0xd4f4, 0xeade, 0xbcd6, 0xbbdf,
+ 0xeadf, 0xc1de, 0xc2b8, 0xd4df, 0xd7ca, 0xeae0, 0xeae1, 0xeae4,
+ 0xeae2, 0xeae3, 0xc9de, 0xb8b3, 0xb6c4, 0xeae5, 0xcaea, 0xc9cd,
+ 0xb4cd, 0xe2d9, 0xc5e2, 0xeae6, 0xc0b5, 0xd7b8, 0xeae7, 0xd7ac,
+ 0xc8fc, 0xd8d3, 0xd8cd, 0xd4de, 0xd4f9, 0xc9c4, 0xd3ae, 0xb8d3,
+ 0xb3e0, 0xc9e2, 0xf4f6, 0xbad5, 0xf4f7, 0xd7df, 0xf4f1, 0xb8b0,
+ 0xd5d4, 0xb8cf, 0xc6f0, 0xb3c3, 0xf4f2, 0xb3ac, 0xd4bd, 0xc7f7,
+ 0xf4f4, 0xf4f3, 0xcccb, 0xc8a4, 0xf4f5, 0xd7e3, 0xc5bf, 0xf5c0,
+ 0xf5bb, 0xf5c3, 0xf5c2, 0xd6ba, 0xf5c1, 0xd4be, 0xf5c4, 0xf5cc,
+ 0xb0cf, 0xb5f8, 0xf5c9, 0xf5ca, 0xc5dc, 0xf5c5, 0xf5c6, 0xf5c7,
+ 0xf5cb, 0xbee0, 0xf5c8, 0xb8fa, 0xf5d0, 0xf5d3, 0xbfe7, 0xb9f2,
+ 0xf5bc, 0xf5cd, 0xc2b7, 0xccf8, 0xbcf9, 0xf5ce, 0xf5cf, 0xf5d1,
+ 0xb6e5, 0xf5d2, 0xf5d5, 0xf5bd, 0xf5d4, 0xd3bb, 0xb3ec, 0xcca4,
+ 0xf5d6, 0xf5d7, 0xbee1, 0xf5d8, 0xccdf, 0xf5db, 0xb2c8, 0xd7d9,
+ 0xf5d9, 0xf5da, 0xf5dc, 0xf5e2, 0xf5e0, 0xf5df, 0xf5dd, 0xf5e1,
+ 0xf5de, 0xf5e4, 0xf5e5, 0xcce3, 0xe5bf, 0xb5b8, 0xf5e3, 0xf5e8,
+ 0xcca3, 0xf5e6, 0xf5e7, 0xf5be, 0xb1c4, 0xf5bf, 0xb5c5, 0xb2e4,
+ 0xf5ec, 0xf5e9, 0xb6d7, 0xf5ed, 0xf5ea, 0xf5eb, 0xb4da, 0xd4ea,
+ 0xf5ee, 0xb3f9, 0xf5ef, 0xf5f1, 0xf5f0, 0xf5f2, 0xf5f3, 0xc9ed,
+ 0xb9aa, 0xc7fb, 0xb6e3, 0xccc9, 0xeaa6, 0xb3b5, 0xd4fe, 0xb9ec,
+ 0xd0f9, 0xe9ed, 0xd7aa, 0xe9ee, 0xc2d6, 0xc8ed, 0xbae4, 0xe9ef,
+ 0xe9f0, 0xe9f1, 0xd6e1, 0xe9f2, 0xe9f3, 0xe9f5, 0xe9f4, 0xe9f6,
+ 0xe9f7, 0xc7e1, 0xe9f8, 0xd4d8, 0xe9f9, 0xbdce, 0xe9fa, 0xe9fb,
+ 0xbdcf, 0xe9fc, 0xb8a8, 0xc1be, 0xe9fd, 0xb1b2, 0xbbd4, 0xb9f5,
+ 0xe9fe, 0xeaa1, 0xeaa2, 0xeaa3, 0xb7f8, 0xbcad, 0xcae4, 0xe0ce,
+ 0xd4af, 0xcfbd, 0xd5b7, 0xeaa4, 0xd5de, 0xeaa5, 0xd0c1, 0xb9bc,
+ 0xb4c7, 0xb1d9, 0xc0b1, 0xb1e6, 0xb1e7, 0xb1e8, 0xb3bd, 0xc8e8,
+ 0xe5c1, 0xb1df, 0xc1c9, 0xb4ef, 0xc7a8, 0xd3d8, 0xc6f9, 0xd1b8,
+ 0xb9fd, 0xc2f5, 0xd3ad, 0xd4cb, 0xbdfc, 0xe5c2, 0xb7b5, 0xe5c3,
+ 0xbbb9, 0xd5e2, 0xbdf8, 0xd4b6, 0xcea5, 0xc1ac, 0xb3d9, 0xccf6,
+ 0xe5c6, 0xe5c4, 0xe5c8, 0xe5ca, 0xe5c7, 0xb5cf, 0xc6c8, 0xb5fc,
+ 0xe5c5, 0xcaf6, 0xe5c9, 0xc3d4, 0xb1c5, 0xbca3, 0xd7b7, 0xcdcb,
+ 0xcbcd, 0xcaca, 0xccd3, 0xe5cc, 0xe5cb, 0xc4e6, 0xd1a1, 0xd1b7,
+ 0xe5cd, 0xe5d0, 0xcdb8, 0xd6f0, 0xe5cf, 0xb5dd, 0xcdbe, 0xe5d1,
+ 0xb6ba, 0xcda8, 0xb9e4, 0xcac5, 0xb3d1, 0xcbd9, 0xd4ec, 0xe5d2,
+ 0xb7ea, 0xe5ce, 0xe5d5, 0xb4fe, 0xe5d6, 0xe5d3, 0xe5d4, 0xd2dd,
+ 0xc2df, 0xb1c6, 0xd3e2, 0xb6dd, 0xcbec, 0xe5d7, 0xd3f6, 0xb1e9,
+ 0xb6f4, 0xe5da, 0xe5d8, 0xe5d9, 0xb5c0, 0xd2c5, 0xe5dc, 0xe5de,
+ 0xe5dd, 0xc7b2, 0xd2a3, 0xe5db, 0xd4e2, 0xd5da, 0xe5e0, 0xd7f1,
+ 0xe5e1, 0xb1dc, 0xd1fb, 0xe5e2, 0xe5e4, 0xe5e3, 0xe5e5, 0xd2d8,
+ 0xb5cb, 0xe7df, 0xdaf5, 0xdaf8, 0xdaf6, 0xdaf7, 0xdafa, 0xd0cf,
+ 0xc4c7, 0xb0ee, 0xd0b0, 0xdaf9, 0xd3ca, 0xbaaa, 0xdba2, 0xc7f1,
+ 0xdafc, 0xdafb, 0xc9db, 0xdafd, 0xdba1, 0xd7de, 0xdafe, 0xc1da,
+ 0xdba5, 0xd3f4, 0xdba7, 0xdba4, 0xdba8, 0xbdbc, 0xc0c9, 0xdba3,
+ 0xdba6, 0xd6a3, 0xdba9, 0xdbad, 0xdbae, 0xdbac, 0xbac2, 0xbfa4,
+ 0xdbab, 0xdbaa, 0xd4c7, 0xb2bf, 0xdbaf, 0xb9f9, 0xdbb0, 0xb3bb,
+ 0xb5a6, 0xb6bc, 0xdbb1, 0xb6f5, 0xdbb2, 0xb1c9, 0xdbb4, 0xdbb3,
+ 0xdbb5, 0xdbb7, 0xdbb6, 0xdbb8, 0xdbb9, 0xdbba, 0xd3cf, 0xf4fa,
+ 0xc7f5, 0xd7c3, 0xc5e4, 0xf4fc, 0xf4fd, 0xf4fb, 0xbec6, 0xd0ef,
+ 0xb7d3, 0xd4cd, 0xccaa, 0xf5a2, 0xf5a1, 0xbaa8, 0xf4fe, 0xcbd6,
+ 0xf5a4, 0xc0d2, 0xb3ea, 0xcdaa, 0xf5a5, 0xf5a3, 0xbdb4, 0xf5a8,
+ 0xf5a9, 0xbdcd, 0xc3b8, 0xbfe1, 0xcbe1, 0xf5aa, 0xf5a6, 0xf5a7,
+ 0xc4f0, 0xf5ac, 0xb4bc, 0xd7ed, 0xb4d7, 0xf5ab, 0xf5ae, 0xf5ad,
+ 0xf5af, 0xd0d1, 0xc3d1, 0xc8a9, 0xf5b0, 0xf5b1, 0xf5b2, 0xf5b3,
+ 0xf5b4, 0xf5b5, 0xf5b7, 0xf5b6, 0xf5b8, 0xb2c9, 0xd3d4, 0xcacd,
+ 0xc0ef, 0xd6d8, 0xd2b0, 0xc1bf, 0xbdf0, 0xb8aa, 0xbcf8, 0xf6c6,
+ 0xf6c7, 0xf6c8, 0xf6c9, 0xf6ca, 0xf6cc, 0xf6cb, 0xf7e9, 0xf6cd,
+ 0xf6ce, 0xeec4, 0xeec5, 0xeec6, 0xd5eb, 0xb6a4, 0xeec8, 0xeec7,
+ 0xeec9, 0xeeca, 0xc7a5, 0xeecb, 0xeecc, 0xb7b0, 0xb5f6, 0xeecd,
+ 0xeecf, 0xeece, 0xb8c6, 0xeed0, 0xeed1, 0xeed2, 0xb6db, 0xb3ae,
+ 0xd6d3, 0xc4c6, 0xb1b5, 0xb8d6, 0xeed3, 0xeed4, 0xd4bf, 0xc7d5,
+ 0xbefb, 0xced9, 0xb9b3, 0xeed6, 0xeed5, 0xeed8, 0xeed7, 0xc5a5,
+ 0xeed9, 0xeeda, 0xc7ae, 0xeedb, 0xc7af, 0xeedc, 0xb2a7, 0xeedd,
+ 0xeede, 0xeedf, 0xeee0, 0xeee1, 0xd7ea, 0xeee2, 0xeee3, 0xbcd8,
+ 0xeee4, 0xd3cb, 0xccfa, 0xb2ac, 0xc1e5, 0xeee5, 0xc7a6, 0xc3ad,
+ 0xeee6, 0xeee7, 0xeee8, 0xeee9, 0xeeea, 0xeeeb, 0xeeec, 0xeeed,
+ 0xeeee, 0xeeef, 0xeef0, 0xeef1, 0xeef2, 0xeef4, 0xeef3, 0xeef5,
+ 0xcdad, 0xc2c1, 0xeef6, 0xeef7, 0xeef8, 0xd5a1, 0xeef9, 0xcfb3,
+ 0xeefa, 0xeefb, 0xeefc, 0xeefd, 0xefa1, 0xeefe, 0xefa2, 0xb8f5,
+ 0xc3fa, 0xefa3, 0xefa4, 0xbdc2, 0xd2bf, 0xb2f9, 0xefa5, 0xefa6,
+ 0xefa7, 0xd2f8, 0xefa8, 0xd6fd, 0xefa9, 0xc6cc, 0xefaa, 0xefab,
+ 0xc1b4, 0xefac, 0xcffa, 0xcbf8, 0xefae, 0xefad, 0xb3fa, 0xb9f8,
+ 0xefaf, 0xefb0, 0xd0e2, 0xefb1, 0xefb2, 0xb7e6, 0xd0bf, 0xefb3,
+ 0xefb4, 0xefb5, 0xc8f1, 0xcce0, 0xefb6, 0xefb7, 0xefb8, 0xefb9,
+ 0xefba, 0xd5e0, 0xefbb, 0xb4ed, 0xc3aa, 0xefbc, 0xefbd, 0xefbe,
+ 0xefbf, 0xcefd, 0xefc0, 0xc2e0, 0xb4b8, 0xd7b6, 0xbdf5, 0xcfc7,
+ 0xefc3, 0xefc1, 0xefc2, 0xefc4, 0xb6a7, 0xbcfc, 0xbee2, 0xc3cc,
+ 0xefc5, 0xefc6, 0xefc7, 0xefcf, 0xefc8, 0xefc9, 0xefca, 0xc7c2,
+ 0xeff1, 0xb6cd, 0xefcb, 0xefcc, 0xefcd, 0xb6c6, 0xc3be, 0xefce,
+ 0xefd0, 0xefd1, 0xefd2, 0xd5f2, 0xefd3, 0xc4f7, 0xefd4, 0xc4f8,
+ 0xefd5, 0xefd6, 0xb8e4, 0xb0f7, 0xefd7, 0xefd8, 0xefd9, 0xefda,
+ 0xefdb, 0xefdc, 0xefdd, 0xefde, 0xbeb5, 0xefe1, 0xefdf, 0xefe0,
+ 0xefe2, 0xefe3, 0xc1cd, 0xefe4, 0xefe5, 0xefe6, 0xefe7, 0xefe8,
+ 0xefe9, 0xefea, 0xefeb, 0xefec, 0xc0d8, 0xefed, 0xc1ad, 0xefee,
+ 0xefef, 0xeff0, 0xcfe2, 0xb3a4, 0xc3c5, 0xe3c5, 0xc9c1, 0xe3c6,
+ 0xb1d5, 0xceca, 0xb4b3, 0xc8f2, 0xe3c7, 0xcfd0, 0xe3c8, 0xbce4,
+ 0xe3c9, 0xe3ca, 0xc3c6, 0xd5a2, 0xc4d6, 0xb9eb, 0xcec5, 0xe3cb,
+ 0xc3f6, 0xe3cc, 0xb7a7, 0xb8f3, 0xbad2, 0xe3cd, 0xe3ce, 0xd4c4,
+ 0xe3cf, 0xe3d0, 0xd1cb, 0xe3d1, 0xe3d2, 0xe3d3, 0xe3d4, 0xd1d6,
+ 0xe3d5, 0xb2fb, 0xc0bb, 0xe3d6, 0xc0ab, 0xe3d7, 0xe3d8, 0xe3d9,
+ 0xe3da, 0xe3db, 0xb8b7, 0xdae2, 0xb6d3, 0xdae4, 0xdae3, 0xdae6,
+ 0xc8ee, 0xdae5, 0xb7c0, 0xd1f4, 0xd2f5, 0xd5f3, 0xbdd7, 0xd7e8,
+ 0xdae8, 0xdae7, 0xb0a2, 0xcdd3, 0xdae9, 0xb8bd, 0xbcca, 0xc2bd,
+ 0xc2a4, 0xb3c2, 0xdaea, 0xc2aa, 0xc4b0, 0xbdb5, 0xcfde, 0xdaeb,
+ 0xc9c2, 0xb1dd, 0xdaec, 0xb6b8, 0xd4ba, 0xb3fd, 0xdaed, 0xd4c9,
+ 0xcfd5, 0xc5e3, 0xdaee, 0xdaef, 0xdaf0, 0xc1ea, 0xccd5, 0xcfdd,
+ 0xd3e7, 0xc2a1, 0xdaf1, 0xcbe5, 0xdaf2, 0xcbe6, 0xd2fe, 0xb8f4,
+ 0xdaf3, 0xb0af, 0xcfb6, 0xd5cf, 0xcbed, 0xdaf4, 0xe3c4, 0xc1a5,
+ 0xf6bf, 0xf6c0, 0xf6c1, 0xc4d1, 0xc8b8, 0xd1e3, 0xd0db, 0xd1c5,
+ 0xbcaf, 0xb9cd, 0xeff4, 0xb4c6, 0xd3ba, 0xf6c2, 0xb3fb, 0xf6c3,
+ 0xb5f1, 0xf6c5, 0xd3ea, 0xf6a7, 0xd1a9, 0xf6a9, 0xf6a8, 0xc1e3,
+ 0xc0d7, 0xb1a2, 0xceed, 0xd0e8, 0xf6ab, 0xcff6, 0xf6aa, 0xd5f0,
+ 0xf6ac, 0xc3b9, 0xbbf4, 0xf6ae, 0xf6ad, 0xc4de, 0xc1d8, 0xcbaa,
+ 0xcfbc, 0xf6af, 0xf6b0, 0xf6b1, 0xc2b6, 0xb0d4, 0xc5f9, 0xf6b2,
+ 0xc7e0, 0xf6a6, 0xbeb8, 0xbeb2, 0xb5e5, 0xb7c7, 0xbfbf, 0xc3d2,
+ 0xc3e6, 0xd8cc, 0xb8ef, 0xbdf9, 0xd1a5, 0xb0d0, 0xf7b0, 0xf7b1,
+ 0xd0ac, 0xb0b0, 0xf7b2, 0xf7b3, 0xf7b4, 0xc7ca, 0xbecf, 0xf7b7,
+ 0xf7b6, 0xb1de, 0xf7b5, 0xf7b8, 0xf7b9, 0xcea4, 0xc8cd, 0xbaab,
+ 0xe8b8, 0xe8b9, 0xe8ba, 0xbec2, 0xd2f4, 0xd4cf, 0xc9d8, 0xd2b3,
+ 0xb6a5, 0xc7ea, 0xf1fc, 0xcfee, 0xcbb3, 0xd0eb, 0xe7ef, 0xcde7,
+ 0xb9cb, 0xb6d9, 0xf1fd, 0xb0e4, 0xcbcc, 0xf1fe, 0xd4a4, 0xc2ad,
+ 0xc1ec, 0xc6c4, 0xbeb1, 0xf2a1, 0xbcd5, 0xf2a2, 0xf2a3, 0xf2a4,
+ 0xd2c3, 0xc6b5, 0xcdc7, 0xf2a5, 0xd3b1, 0xbfc5, 0xcce2, 0xf2a6,
+ 0xf2a7, 0xd1d5, 0xb6ee, 0xf2a8, 0xf2a9, 0xb5df, 0xf2aa, 0xf2ab,
+ 0xb2fc, 0xf2ac, 0xf2ad, 0xc8a7, 0xb7e7, 0xeca9, 0xecaa, 0xecab,
+ 0xecac, 0xc6ae, 0xecad, 0xecae, 0xb7c9, 0xcab3, 0xe2b8, 0xf7cf,
+ 0xf7d0, 0xb2cd, 0xf7d1, 0xf7d3, 0xf7d2, 0xe2bb, 0xbca2, 0xe2bc,
+ 0xe2bd, 0xe2be, 0xe2bf, 0xe2c0, 0xe2c1, 0xb7b9, 0xd2fb, 0xbda4,
+ 0xcace, 0xb1a5, 0xcbc7, 0xe2c2, 0xb6fc, 0xc8c4, 0xe2c3, 0xbdc8,
+ 0xb1fd, 0xe2c4, 0xb6f6, 0xe2c5, 0xc4d9, 0xe2c6, 0xcfda, 0xb9dd,
+ 0xe2c7, 0xc0a1, 0xe2c8, 0xb2f6, 0xe2c9, 0xc1f3, 0xe2ca, 0xe2cb,
+ 0xc2f8, 0xe2cc, 0xe2cd, 0xe2ce, 0xcad7, 0xd8b8, 0xd9e5, 0xcfe3,
+ 0xf0a5, 0xdcb0, 0xc2ed, 0xd4a6, 0xcdd4, 0xd1b1, 0xb3db, 0xc7fd,
+ 0xb2b5, 0xc2bf, 0xe6e0, 0xcabb, 0xe6e1, 0xe6e2, 0xbed4, 0xe6e3,
+ 0xd7a4, 0xcdd5, 0xe6e5, 0xbcdd, 0xe6e4, 0xe6e6, 0xe6e7, 0xc2ee,
+ 0xbdbe, 0xe6e8, 0xc2e6, 0xbaa7, 0xe6e9, 0xe6ea, 0xb3d2, 0xd1e9,
+ 0xbfa5, 0xe6eb, 0xc6ef, 0xe6ec, 0xe6ed, 0xe6ee, 0xc6ad, 0xe6ef,
+ 0xc9a7, 0xe6f0, 0xe6f1, 0xe6f2, 0xe5b9, 0xe6f3, 0xe6f4, 0xc2e2,
+ 0xe6f5, 0xe6f6, 0xd6e8, 0xe6f7, 0xe6f8, 0xb9c7, 0xf7bb, 0xf7ba,
+ 0xf7be, 0xf7bc, 0xbaa1, 0xf7bf, 0xf7c0, 0xf7c2, 0xf7c1, 0xf7c4,
+ 0xf7c3, 0xf7c5, 0xf7c6, 0xf7c7, 0xcbe8, 0xb8df, 0xf7d4, 0xf7d5,
+ 0xf7d6, 0xf7d8, 0xf7da, 0xf7d7, 0xf7db, 0xf7d9, 0xd7d7, 0xf7dc,
+ 0xf7dd, 0xf7de, 0xf7df, 0xf7e0, 0xdbcb, 0xd8aa, 0xe5f7, 0xb9ed,
+ 0xbffd, 0xbbea, 0xf7c9, 0xc6c7, 0xf7c8, 0xf7ca, 0xf7cc, 0xf7cb,
+ 0xf7cd, 0xceba, 0xf7ce, 0xc4a7, 0xd3e3, 0xf6cf, 0xc2b3, 0xf6d0,
+ 0xf6d1, 0xf6d2, 0xf6d3, 0xf6d4, 0xf6d6, 0xb1ab, 0xf6d7, 0xf6d8,
+ 0xf6d9, 0xf6da, 0xf6db, 0xf6dc, 0xf6dd, 0xf6de, 0xcfca, 0xf6df,
+ 0xf6e0, 0xf6e1, 0xf6e2, 0xf6e3, 0xf6e4, 0xc0f0, 0xf6e5, 0xf6e6,
+ 0xf6e7, 0xf6e8, 0xf6e9, 0xf6ea, 0xf6eb, 0xf6ec, 0xf6ed, 0xf6ee,
+ 0xf6ef, 0xf6f0, 0xf6f1, 0xf6f2, 0xf6f3, 0xf6f4, 0xbea8, 0xf6f5,
+ 0xf6f6, 0xf6f7, 0xf6f8, 0xc8fa, 0xf6f9, 0xf6fa, 0xf6fb, 0xf6fc,
+ 0xf6fd, 0xf6fe, 0xf7a1, 0xf7a2, 0xf7a3, 0xf7a4, 0xf7a5, 0xf7a6,
+ 0xf7a7, 0xf7a8, 0xb1ee, 0xf7a9, 0xf7aa, 0xf7ab, 0xf7ac, 0xf7ad,
+ 0xc1db, 0xf7ae, 0xf7af, 0xc4f1, 0xf0af, 0xbca6, 0xf0b0, 0xc3f9,
+ 0xc5b8, 0xd1bb, 0xf0b1, 0xf0b2, 0xf0b3, 0xf0b4, 0xf0b5, 0xd1bc,
+ 0xd1ec, 0xf0b7, 0xf0b6, 0xd4a7, 0xcdd2, 0xf0b8, 0xf0ba, 0xf0b9,
+ 0xf0bb, 0xf0bc, 0xb8eb, 0xf0bd, 0xbae8, 0xf0be, 0xf0bf, 0xbee9,
+ 0xf0c0, 0xb6ec, 0xf0c1, 0xf0c2, 0xf0c3, 0xf0c4, 0xc8b5, 0xf0c5,
+ 0xf0c6, 0xf0c7, 0xc5f4, 0xf0c8, 0xf0c9, 0xf0ca, 0xf7bd, 0xf0cb,
+ 0xf0cc, 0xf0cd, 0xf0ce, 0xf0cf, 0xbad7, 0xf0d0, 0xf0d1, 0xf0d2,
+ 0xf0d3, 0xf0d4, 0xf0d5, 0xf0d6, 0xf0d8, 0xd3a5, 0xf0d7, 0xf0d9,
+ 0xf5ba, 0xc2b9, 0xf7e4, 0xf7e5, 0xf7e6, 0xf7e7, 0xf7e8, 0xc2b4,
+ 0xf7ea, 0xf7eb, 0xc2f3, 0xf4f0, 0xf4ef, 0xc2e9, 0xf7e1, 0xf7e2,
+ 0xbbc6, 0xd9e4, 0xcaf2, 0xc0e8, 0xf0a4, 0xbada, 0xc7ad, 0xc4ac,
+ 0xf7ec, 0xf7ed, 0xf7ee, 0xf7f0, 0xf7ef, 0xf7f1, 0xf7f4, 0xf7f3,
+ 0xf7f2, 0xf7f5, 0xf7f6, 0xede9, 0xedea, 0xedeb, 0xf6bc, 0xf6bd,
+ 0xf6be, 0xb6a6, 0xd8be, 0xb9c4, 0xd8bb, 0xdcb1, 0xcaf3, 0xf7f7,
+ 0xf7f8, 0xf7f9, 0xf7fb, 0xf7fa, 0xb1c7, 0xf7fc, 0xf7fd, 0xf7fe,
+ 0xc6eb, 0xecb4, 0xb3dd, 0xf6b3, 0xf6b4, 0xc1e4, 0xf6b5, 0xf6b6,
+ 0xf6b7, 0xf6b8, 0xf6b9, 0xf6ba, 0xc8a3, 0xf6bb, 0xc1fa, 0xb9a8,
+ 0xede8, 0xb9ea, 0xd9df, 0xa3a1, 0xa3a2, 0xa3a3, 0xa1e7, 0xa3a5,
+ 0xa3a6, 0xa3a7, 0xa3a8, 0xa3a9, 0xa3aa, 0xa3ab, 0xa3ac, 0xa3ad,
+ 0xa3ae, 0xa3af, 0xa3b0, 0xa3b1, 0xa3b2, 0xa3b3, 0xa3b4, 0xa3b5,
+ 0xa3b6, 0xa3b7, 0xa3b8, 0xa3b9, 0xa3ba, 0xa3bb, 0xa3bc, 0xa3bd,
+ 0xa3be, 0xa3bf, 0xa3c0, 0xa3c1, 0xa3c2, 0xa3c3, 0xa3c4, 0xa3c5,
+ 0xa3c6, 0xa3c7, 0xa3c8, 0xa3c9, 0xa3ca, 0xa3cb, 0xa3cc, 0xa3cd,
+ 0xa3ce, 0xa3cf, 0xa3d0, 0xa3d1, 0xa3d2, 0xa3d3, 0xa3d4, 0xa3d5,
+ 0xa3d6, 0xa3d7, 0xa3d8, 0xa3d9, 0xa3da, 0xa3db, 0xa3dc, 0xa3dd,
+ 0xa3de, 0xa3df, 0xa3e0, 0xa3e1, 0xa3e2, 0xa3e3, 0xa3e4, 0xa3e5,
+ 0xa3e6, 0xa3e7, 0xa3e8, 0xa3e9, 0xa3ea, 0xa3eb, 0xa3ec, 0xa3ed,
+ 0xa3ee, 0xa3ef, 0xa3f0, 0xa3f1, 0xa3f2, 0xa3f3, 0xa3f4, 0xa3f5,
+ 0xa3f6, 0xa3f7, 0xa3f8, 0xa3f9, 0xa3fa, 0xa3fb, 0xa3fc, 0xa3fd,
+ 0xa1ab, 0xa1e9, 0xa1ea, 0xa3fe, 0xa3a4,
+};
+
+typedef struct {
+ unsigned short indx; /* index into big table */
+ unsigned short used; /* bitmask of used entries */
+} Summary16;
+
+static const Summary16 gb2312_uni2indx_page00[70] = {
+ /* 0x0000 */
+ { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 },
+ { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 },
+ { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0190 }, { 3, 0x0003 },
+ { 5, 0x0000 }, { 5, 0x0080 }, { 6, 0x3703 }, { 13, 0x168c },
+ /* 0x0100 */
+ { 19, 0x0002 }, { 20, 0x0808 }, { 22, 0x0800 }, { 23, 0x0000 },
+ { 23, 0x2000 }, { 24, 0x0000 }, { 24, 0x0800 }, { 25, 0x0000 },
+ { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 },
+ { 25, 0x4000 }, { 26, 0x1555 }, { 33, 0x0000 }, { 33, 0x0000 },
+ /* 0x0200 */
+ { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 },
+ { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 },
+ { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 },
+ { 33, 0x0280 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 },
+ /* 0x0300 */
+ { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 },
+ { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 },
+ { 35, 0x0000 }, { 35, 0xfffe }, { 50, 0x03fb }, { 59, 0xfffe },
+ { 74, 0x03fb }, { 83, 0x0000 }, { 83, 0x0000 }, { 83, 0x0000 },
+ /* 0x0400 */
+ { 83, 0x0002 }, { 84, 0xffff }, { 100, 0xffff }, { 116, 0xffff },
+ { 132, 0xffff }, { 148, 0x0002 },
+};
+static const Summary16 gb2312_uni2indx_page20[101] = {
+ /* 0x2000 */
+ { 149, 0x0000 }, { 149, 0x3360 }, { 155, 0x0040 }, { 156, 0x080d },
+ { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 },
+ { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 },
+ { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 },
+ /* 0x2100 */
+ { 160, 0x0008 }, { 161, 0x0040 }, { 162, 0x0000 }, { 162, 0x0000 },
+ { 162, 0x0000 }, { 162, 0x0000 }, { 162, 0x0fff }, { 174, 0x0000 },
+ { 174, 0x0000 }, { 174, 0x000f }, { 178, 0x0000 }, { 178, 0x0000 },
+ { 178, 0x0000 }, { 178, 0x0000 }, { 178, 0x0000 }, { 178, 0x0000 },
+ /* 0x2200 */
+ { 178, 0x8100 }, { 180, 0x6402 }, { 184, 0x4fa1 }, { 192, 0x20f0 },
+ { 197, 0x1100 }, { 199, 0x0000 }, { 199, 0xc033 }, { 205, 0x0000 },
+ { 205, 0x0000 }, { 205, 0x0200 }, { 206, 0x0020 }, { 207, 0x0000 },
+ { 207, 0x0000 }, { 207, 0x0000 }, { 207, 0x0000 }, { 207, 0x0000 },
+ /* 0x2300 */
+ { 207, 0x0000 }, { 207, 0x0004 }, { 208, 0x0000 }, { 208, 0x0000 },
+ { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 },
+ { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 },
+ { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 },
+ /* 0x2400 */
+ { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 },
+ { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x03ff }, { 218, 0xfff0 },
+ { 230, 0xffff }, { 246, 0x0fff }, { 258, 0x0000 }, { 258, 0x0000 },
+ { 258, 0x0000 }, { 258, 0x0000 }, { 258, 0x0000 }, { 258, 0x0000 },
+ /* 0x2500 */
+ { 258, 0xffff }, { 274, 0xffff }, { 290, 0xffff }, { 306, 0xffff },
+ { 322, 0x0fff }, { 334, 0x0000 }, { 334, 0x0000 }, { 334, 0x0000 },
+ { 334, 0x0000 }, { 334, 0x0000 }, { 334, 0x0003 }, { 336, 0x000c },
+ { 338, 0xc8c0 }, { 343, 0x0000 }, { 343, 0x0000 }, { 343, 0x0000 },
+ /* 0x2600 */
+ { 343, 0x0060 }, { 345, 0x0000 }, { 345, 0x0000 }, { 345, 0x0000 },
+ { 345, 0x0005 },
+};
+static const Summary16 gb2312_uni2indx_page30[35] = {
+ /* 0x3000 */
+ { 347, 0xff2f }, { 360, 0x00fb }, { 367, 0x0000 }, { 367, 0x0000 },
+ { 367, 0xfffe }, { 382, 0xffff }, { 398, 0xffff }, { 414, 0xffff },
+ { 430, 0xffff }, { 446, 0x000f }, { 450, 0xfffe }, { 465, 0xffff },
+ { 481, 0xffff }, { 497, 0xffff }, { 513, 0xffff }, { 529, 0x087f },
+ /* 0x3100 */
+ { 537, 0xffe0 }, { 548, 0xffff }, { 564, 0x03ff }, { 574, 0x0000 },
+ { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 },
+ { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 },
+ { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 },
+ /* 0x3200 */
+ { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x03ff },
+};
+static const Summary16 gb2312_uni2indx_page4e[1263] = {
+ /* 0x4e00 */
+ { 584, 0x7f8b }, { 595, 0x7f7b }, { 608, 0x3db4 }, { 617, 0xef55 },
+ { 628, 0xfba8 }, { 638, 0xf35d }, { 649, 0x0243 }, { 653, 0x400b },
+ { 657, 0xfb40 }, { 665, 0x8d3e }, { 674, 0x7bf7 }, { 687, 0x8c2c },
+ { 693, 0x6eff }, { 706, 0xe3fa }, { 717, 0x1d3a }, { 725, 0xa8ed },
+ /* 0x4f00 */
+ { 734, 0xe602 }, { 740, 0xcf83 }, { 749, 0x8cf5 }, { 758, 0x3555 },
+ { 766, 0xe048 }, { 771, 0xffab }, { 784, 0x92b9 }, { 792, 0xd859 },
+ { 800, 0xab18 }, { 807, 0x2892 }, { 812, 0xd7e9 }, { 823, 0x8020 },
+ { 825, 0xc438 }, { 831, 0xf583 }, { 840, 0xe74a }, { 849, 0x450a },
+ /* 0x5000 */
+ { 854, 0xb000 }, { 857, 0x9714 }, { 864, 0x7762 }, { 873, 0x5400 },
+ { 876, 0xd188 }, { 882, 0x1420 }, { 885, 0x1020 }, { 887, 0xc8c0 },
+ { 892, 0x2121 }, { 896, 0x0000 }, { 896, 0x13a8 }, { 902, 0x0c04 },
+ { 905, 0x8000 }, { 906, 0x0440 }, { 908, 0x70c0 }, { 913, 0x0828 },
+ /* 0x5100 */
+ { 916, 0x08c0 }, { 919, 0x0004 }, { 920, 0x0002 }, { 921, 0x8000 },
+ { 922, 0x2b7b }, { 932, 0x1472 }, { 938, 0x7924 }, { 945, 0x3bfb },
+ { 957, 0x3327 }, { 965, 0x1ae4 }, { 972, 0x9835 }, { 979, 0x38ef },
+ { 989, 0x9ad1 }, { 997, 0x2802 }, { 1000, 0xa813 }, { 1006, 0xbf69 },
+ /* 0x5200 */
+ { 1017, 0x65cf }, { 1027, 0x2fc6 }, { 1036, 0x6b11 }, { 1043, 0xafc9 },
+ { 1053, 0x340f }, { 1060, 0x5053 }, { 1066, 0x86a2 }, { 1072, 0xa004 },
+ { 1075, 0x0106 }, { 1078, 0xe809 }, { 1084, 0x3f0f }, { 1094, 0xc00e },
+ { 1099, 0x0a88 }, { 1103, 0x8145 }, { 1108, 0x0010 }, { 1109, 0xc601 },
+ /* 0x5300 */
+ { 1114, 0xa161 }, { 1120, 0x26e1 }, { 1127, 0x444b }, { 1133, 0xce00 },
+ { 1138, 0xc7aa }, { 1147, 0xd4ee }, { 1157, 0xcadf }, { 1168, 0x85bb },
+ { 1177, 0x3a74 }, { 1185, 0xa520 }, { 1190, 0x436c }, { 1197, 0x8840 },
+ { 1200, 0x3f06 }, { 1208, 0x8bd2 }, { 1216, 0xff79 }, { 1229, 0x3bef },
+ /* 0x5400 */
+ { 1241, 0xf75a }, { 1252, 0xe8ef }, { 1263, 0xfbcb }, { 1275, 0x5b36 },
+ { 1284, 0x0d49 }, { 1290, 0x1bfd }, { 1301, 0x0154 }, { 1305, 0x39ee },
+ { 1315, 0xd855 }, { 1323, 0x2e75 }, { 1332, 0xbfd8 }, { 1343, 0xa91a },
+ { 1350, 0xf3d7 }, { 1362, 0xf6bf }, { 1375, 0x67e0 }, { 1383, 0xb40c },
+ /* 0x5500 */
+ { 1389, 0x82c2 }, { 1394, 0x0813 }, { 1398, 0xd49d }, { 1407, 0xd08b },
+ { 1414, 0x065a }, { 1420, 0x1061 }, { 1424, 0x74f2 }, { 1433, 0x59e0 },
+ { 1440, 0x8f9f }, { 1451, 0xb312 }, { 1458, 0x0080 }, { 1459, 0x6aaa },
+ { 1467, 0x3230 }, { 1472, 0xb05e }, { 1480, 0x9d7a }, { 1490, 0x60ac },
+ /* 0x5600 */
+ { 1496, 0xd303 }, { 1503, 0xc900 }, { 1507, 0x3098 }, { 1512, 0x8a56 },
+ { 1519, 0x7000 }, { 1522, 0x1390 }, { 1527, 0x1f14 }, { 1534, 0x1842 },
+ { 1538, 0xc060 }, { 1542, 0x0008 }, { 1543, 0x8008 }, { 1545, 0x1080 },
+ { 1547, 0x0400 }, { 1548, 0xec90 }, { 1555, 0x2817 }, { 1561, 0xe633 },
+ /* 0x5700 */
+ { 1570, 0x0758 }, { 1576, 0x9000 }, { 1578, 0xf708 }, { 1586, 0x4e09 },
+ { 1592, 0xf485 }, { 1600, 0xfc83 }, { 1609, 0xaf53 }, { 1619, 0x18c8 },
+ { 1624, 0x187c }, { 1631, 0x080c }, { 1634, 0x6adf }, { 1645, 0x0114 },
+ { 1648, 0xc80c }, { 1653, 0xa734 }, { 1661, 0xa011 }, { 1665, 0x2710 },
+ /* 0x5800 */
+ { 1670, 0x28c5 }, { 1676, 0x4222 }, { 1680, 0x0413 }, { 1684, 0x0021 },
+ { 1686, 0x3010 }, { 1689, 0x4112 }, { 1693, 0x1820 }, { 1696, 0x4000 },
+ { 1697, 0x022b }, { 1702, 0xc60c }, { 1708, 0x0300 }, { 1710, 0x1000 },
+ { 1711, 0x0022 }, { 1713, 0x0022 }, { 1715, 0x5810 }, { 1719, 0x0249 },
+ /* 0x5900 */
+ { 1723, 0xa094 }, { 1728, 0x9670 }, { 1735, 0xeeb0 }, { 1744, 0x1792 },
+ { 1751, 0xcb96 }, { 1760, 0x05f2 }, { 1767, 0x0025 }, { 1770, 0x2358 },
+ { 1776, 0x25de }, { 1785, 0x42cc }, { 1791, 0xcf38 }, { 1800, 0x4a04 },
+ { 1804, 0x0c40 }, { 1807, 0x359f }, { 1817, 0x1128 }, { 1821, 0x8a00 },
+ /* 0x5a00 */
+ { 1824, 0x13fa }, { 1833, 0x910a }, { 1838, 0x0229 }, { 1842, 0x1056 },
+ { 1847, 0x0641 }, { 1851, 0x0420 }, { 1853, 0x0484 }, { 1856, 0x84f0 },
+ { 1862, 0x0000 }, { 1862, 0x0c04 }, { 1865, 0x0400 }, { 1866, 0x412c },
+ { 1871, 0x1206 }, { 1875, 0x1154 }, { 1880, 0x0a4b }, { 1886, 0x0002 },
+ /* 0x5b00 */
+ { 1887, 0x0200 }, { 1888, 0x00c0 }, { 1890, 0x0000 }, { 1890, 0x0094 },
+ { 1893, 0x0001 }, { 1894, 0xbfbb }, { 1907, 0x167c }, { 1915, 0x242b },
+ { 1921, 0x9bbb }, { 1932, 0x7fa8 }, { 1942, 0x0c7f }, { 1951, 0xe379 },
+ { 1961, 0x10f4 }, { 1967, 0xe00d }, { 1973, 0x4132 }, { 1978, 0x9f01 },
+ /* 0x5c00 */
+ { 1985, 0x8652 }, { 1991, 0x3572 }, { 1999, 0x10b4 }, { 2004, 0xff12 },
+ { 2014, 0xcf27 }, { 2024, 0x4223 }, { 2029, 0xc06b }, { 2036, 0x8602 },
+ { 2040, 0x3106 }, { 2045, 0x1fd3 }, { 2055, 0x3a0c }, { 2061, 0xa1aa },
+ { 2068, 0x0812 }, { 2071, 0x0204 }, { 2073, 0x2572 }, { 2080, 0x0801 },
+ /* 0x5d00 */
+ { 2082, 0x40cc }, { 2087, 0x4850 }, { 2091, 0x62d0 }, { 2097, 0x6010 },
+ { 2100, 0x1c80 }, { 2104, 0x2900 }, { 2107, 0x9a00 }, { 2111, 0x0010 },
+ { 2112, 0x0004 }, { 2113, 0x2200 }, { 2115, 0x0000 }, { 2115, 0x0080 },
+ { 2116, 0x2020 }, { 2118, 0x6800 }, { 2121, 0xcbe6 }, { 2131, 0x609e },
+ /* 0x5e00 */
+ { 2138, 0x916e }, { 2146, 0x3f73 }, { 2157, 0x60c0 }, { 2161, 0x3982 },
+ { 2167, 0x1034 }, { 2171, 0x4830 }, { 2175, 0x0006 }, { 2177, 0xbd5c },
+ { 2187, 0x8cd1 }, { 2194, 0xd6fb }, { 2206, 0x20e1 }, { 2211, 0x43e8 },
+ { 2218, 0x0600 }, { 2220, 0x084e }, { 2225, 0x0500 }, { 2227, 0xc4d0 },
+ /* 0x5f00 */
+ { 2233, 0x8d1f }, { 2242, 0x89aa }, { 2249, 0xa6e1 }, { 2257, 0x1602 },
+ { 2261, 0x0001 }, { 2262, 0x21ed }, { 2270, 0x3656 }, { 2278, 0x1a8b },
+ { 2285, 0x1fb7 }, { 2296, 0x13a5 }, { 2303, 0x6502 }, { 2308, 0x30a0 },
+ { 2312, 0xb278 }, { 2320, 0x23c7 }, { 2328, 0x6c93 }, { 2336, 0xe922 },
+ /* 0x6000 */
+ { 2343, 0xe47f }, { 2354, 0x3a74 }, { 2362, 0x8fe3 }, { 2372, 0x9820 },
+ { 2376, 0x280e }, { 2381, 0x2625 }, { 2387, 0xbf9c }, { 2398, 0xbf49 },
+ { 2408, 0x3218 }, { 2413, 0xac54 }, { 2420, 0xb949 }, { 2428, 0x1916 },
+ { 2434, 0x0c60 }, { 2438, 0xb522 }, { 2445, 0xfbc1 }, { 2455, 0x0659 },
+ /* 0x6100 */
+ { 2461, 0xe343 }, { 2469, 0x8420 }, { 2472, 0x08d9 }, { 2478, 0x8000 },
+ { 2479, 0x5500 }, { 2483, 0x2022 }, { 2486, 0x0184 }, { 2489, 0x00a1 },
+ { 2492, 0x4800 }, { 2494, 0x2010 }, { 2496, 0x1380 }, { 2500, 0x4080 },
+ { 2502, 0x0d04 }, { 2506, 0x0016 }, { 2509, 0x0040 }, { 2510, 0x8020 },
+ /* 0x6200 */
+ { 2512, 0xfd40 }, { 2520, 0x8de7 }, { 2530, 0x5436 }, { 2537, 0xe098 },
+ { 2543, 0x7b8b }, { 2553, 0x091e }, { 2559, 0xfec8 }, { 2569, 0xd249 },
+ { 2576, 0x0611 }, { 2580, 0x8dee }, { 2590, 0x1937 }, { 2598, 0xba22 },
+ { 2605, 0x77f4 }, { 2616, 0x9fdd }, { 2628, 0xf3ec }, { 2639, 0xf0da },
+ /* 0x6300 */
+ { 2648, 0x4386 }, { 2654, 0xec42 }, { 2661, 0x8d3f }, { 2671, 0x2604 },
+ { 2675, 0xfa6c }, { 2685, 0xc021 }, { 2689, 0x628e }, { 2696, 0x0cc2 },
+ { 2701, 0xd785 }, { 2710, 0x0145 }, { 2714, 0x77ad }, { 2725, 0x5599 },
+ { 2733, 0xe250 }, { 2739, 0x4045 }, { 2743, 0x260b }, { 2749, 0xa154 },
+ /* 0x6400 */
+ { 2755, 0x9827 }, { 2762, 0x5819 }, { 2768, 0x3443 }, { 2774, 0xa410 },
+ { 2778, 0x05f2 }, { 2785, 0x4114 }, { 2789, 0x2280 }, { 2792, 0x0700 },
+ { 2795, 0x00b4 }, { 2799, 0x4266 }, { 2805, 0x7210 }, { 2810, 0x15a1 },
+ { 2816, 0x6025 }, { 2821, 0x4185 }, { 2826, 0x0054 }, { 2829, 0x0000 },
+ /* 0x6500 */
+ { 2829, 0x0201 }, { 2831, 0x0104 }, { 2833, 0xc820 }, { 2837, 0xcb70 },
+ { 2845, 0x9320 }, { 2850, 0x6a62 }, { 2857, 0x184c }, { 2862, 0x0095 },
+ { 2866, 0x1880 }, { 2869, 0x9a8b }, { 2877, 0xaab2 }, { 2885, 0x3201 },
+ { 2889, 0xd87a }, { 2898, 0x00c4 }, { 2901, 0xf3e5 }, { 2912, 0x04c3 },
+ /* 0x6600 */
+ { 2917, 0xd44d }, { 2925, 0xa238 }, { 2931, 0xa1a1 }, { 2937, 0x5072 },
+ { 2943, 0x980a }, { 2948, 0x84fc }, { 2956, 0xc152 }, { 2962, 0x44d1 },
+ { 2968, 0x1094 }, { 2972, 0x20c2 }, { 2976, 0x4180 }, { 2979, 0x4210 },
+ { 2982, 0x0000 }, { 2982, 0x3a00 }, { 2986, 0x0240 }, { 2988, 0xd29d },
+ /* 0x6700 */
+ { 2997, 0x2f01 }, { 3003, 0xa8b1 }, { 3010, 0xbd40 }, { 3017, 0x2432 },
+ { 3022, 0xd34d }, { 3031, 0xd04b }, { 3038, 0xa723 }, { 3046, 0xd0ad },
+ { 3054, 0x0a92 }, { 3059, 0x75a1 }, { 3067, 0xadac }, { 3076, 0x01e9 },
+ { 3082, 0x801a }, { 3086, 0x771f }, { 3097, 0x9225 }, { 3103, 0xa01b },
+ /* 0x6800 */
+ { 3109, 0xdfa1 }, { 3119, 0x20ca }, { 3124, 0x0602 }, { 3127, 0x738c },
+ { 3135, 0x577f }, { 3147, 0x003b }, { 3152, 0x0bff }, { 3163, 0x00d0 },
+ { 3166, 0x806a }, { 3171, 0x0088 }, { 3173, 0xa1c4 }, { 3179, 0x0029 },
+ { 3182, 0x2a05 }, { 3187, 0x0524 }, { 3191, 0x4009 }, { 3194, 0x1623 },
+ /* 0x6900 */
+ { 3200, 0x6822 }, { 3205, 0x8005 }, { 3208, 0x2011 }, { 3211, 0xa211 },
+ { 3216, 0x0004 }, { 3217, 0x6490 }, { 3222, 0x4849 }, { 3227, 0x1382 },
+ { 3232, 0x23d5 }, { 3240, 0x1930 }, { 3245, 0x2980 }, { 3249, 0x0892 },
+ { 3253, 0x5402 }, { 3257, 0x8811 }, { 3261, 0x2001 }, { 3263, 0xa004 },
+ /* 0x6a00 */
+ { 3266, 0x0400 }, { 3267, 0x8180 }, { 3270, 0x8502 }, { 3274, 0x6022 },
+ { 3278, 0x0090 }, { 3280, 0x0b01 }, { 3284, 0x0022 }, { 3286, 0x1202 },
+ { 3289, 0x4011 }, { 3292, 0x0083 }, { 3295, 0x1a01 }, { 3299, 0x0000 },
+ { 3299, 0x0000 }, { 3299, 0x0000 }, { 3299, 0x0000 }, { 3299, 0x0000 },
+ /* 0x6b00 */
+ { 3299, 0x0000 }, { 3299, 0x0000 }, { 3299, 0x009f }, { 3305, 0x4684 },
+ { 3310, 0x12c8 }, { 3315, 0x0200 }, { 3316, 0x04fc }, { 3323, 0x1a00 },
+ { 3326, 0x2ede }, { 3336, 0x0c4c }, { 3341, 0x0402 }, { 3343, 0x80b8 },
+ { 3348, 0xa826 }, { 3354, 0x0afc }, { 3362, 0x8c02 }, { 3366, 0x2228 },
+ /* 0x6c00 */
+ { 3370, 0xa0e0 }, { 3375, 0x8f7b }, { 3386, 0xc7d6 }, { 3396, 0x2135 },
+ { 3402, 0x06c7 }, { 3409, 0xf8b1 }, { 3418, 0x0713 }, { 3424, 0x6255 },
+ { 3431, 0x936e }, { 3440, 0x8a19 }, { 3446, 0x6efa }, { 3457, 0xfb0e },
+ { 3467, 0x1630 }, { 3472, 0x48f9 }, { 3480, 0xcd2f }, { 3490, 0x7deb },
+ /* 0x6d00 */
+ { 3502, 0x5892 }, { 3508, 0x4e84 }, { 3514, 0x4ca0 }, { 3519, 0x7a2e },
+ { 3528, 0xedea }, { 3539, 0x561e }, { 3547, 0xc649 }, { 3554, 0x1190 },
+ { 3558, 0x5324 }, { 3564, 0xe83a }, { 3572, 0xcfdb }, { 3584, 0x8124 },
+ { 3588, 0x18f1 }, { 3595, 0x6342 }, { 3601, 0x5853 }, { 3608, 0x1a8a },
+ /* 0x6e00 */
+ { 3614, 0x7420 }, { 3619, 0x24d3 }, { 3626, 0xaa3b }, { 3635, 0x0514 },
+ { 3639, 0x6018 }, { 3643, 0x8958 }, { 3649, 0x4800 }, { 3651, 0xc000 },
+ { 3653, 0x8268 }, { 3658, 0x9101 }, { 3662, 0x84a4 }, { 3667, 0x2cd6 },
+ { 3675, 0x8886 }, { 3680, 0xc4ba }, { 3688, 0x0377 }, { 3696, 0x0210 },
+ /* 0x6f00 */
+ { 3698, 0x8244 }, { 3702, 0x0038 }, { 3705, 0xae11 }, { 3712, 0x404a },
+ { 3716, 0x28c0 }, { 3720, 0x5100 }, { 3723, 0x6044 }, { 3727, 0x1514 },
+ { 3732, 0x7310 }, { 3738, 0x1000 }, { 3739, 0x0082 }, { 3741, 0x0248 },
+ { 3744, 0x0205 }, { 3747, 0x4006 }, { 3750, 0xc003 }, { 3754, 0x0000 },
+ /* 0x7000 */
+ { 3754, 0x0000 }, { 3754, 0x0c02 }, { 3757, 0x0008 }, { 3758, 0x0220 },
+ { 3760, 0x9000 }, { 3762, 0x4000 }, { 3763, 0xb800 }, { 3767, 0xd161 },
+ { 3774, 0x4621 }, { 3779, 0x3274 }, { 3786, 0xf800 }, { 3791, 0x3b8a },
+ { 3799, 0x050f }, { 3805, 0x8b00 }, { 3809, 0xbbd0 }, { 3818, 0x2280 },
+ /* 0x7100 */
+ { 3821, 0x0600 }, { 3823, 0x0769 }, { 3830, 0x8040 }, { 3832, 0x0043 },
+ { 3835, 0x5420 }, { 3839, 0x5000 }, { 3841, 0x41d0 }, { 3846, 0x250c },
+ { 3851, 0x8410 }, { 3854, 0x8310 }, { 3858, 0x1101 }, { 3861, 0x0228 },
+ { 3864, 0x4008 }, { 3866, 0x0030 }, { 3868, 0x40a1 }, { 3872, 0x0200 },
+ /* 0x7200 */
+ { 3873, 0x0040 }, { 3874, 0x2000 }, { 3875, 0x1500 }, { 3878, 0xabe3 },
+ { 3888, 0x3180 }, { 3892, 0xaa44 }, { 3898, 0xc2c6 }, { 3905, 0xc624 },
+ { 3911, 0xac13 }, { 3918, 0x8004 }, { 3920, 0xb000 }, { 3923, 0x03d1 },
+ { 3929, 0x611e }, { 3936, 0x4285 }, { 3941, 0xf303 }, { 3949, 0x1d9f },
+ /* 0x7300 */
+ { 3959, 0x440a }, { 3963, 0x78e8 }, { 3971, 0x5e26 }, { 3979, 0xc392 },
+ { 3986, 0x2000 }, { 3987, 0x0085 }, { 3990, 0xb001 }, { 3994, 0x4000 },
+ { 3995, 0x4a90 }, { 4000, 0x8842 }, { 4004, 0xca04 }, { 4009, 0x0c8d },
+ { 4015, 0xa705 }, { 4022, 0x4203 }, { 4026, 0x22a1 }, { 4031, 0x0004 },
+ /* 0x7400 */
+ { 4032, 0x8668 }, { 4038, 0x0c01 }, { 4041, 0x5564 }, { 4048, 0x1079 },
+ { 4054, 0x0002 }, { 4055, 0xdea0 }, { 4063, 0x2000 }, { 4064, 0x40c1 },
+ { 4068, 0x488b }, { 4074, 0x5001 }, { 4077, 0x0380 }, { 4080, 0x0400 },
+ { 4081, 0x0000 }, { 4081, 0x5004 }, { 4084, 0xc05d }, { 4091, 0x80d0 },
+ /* 0x7500 */
+ { 4095, 0xa010 }, { 4098, 0x970a }, { 4105, 0xbb20 }, { 4112, 0x4daf },
+ { 4122, 0xd921 }, { 4129, 0x1e10 }, { 4134, 0x0460 }, { 4137, 0x8314 },
+ { 4142, 0x8848 }, { 4146, 0xa6d6 }, { 4155, 0xd83b }, { 4164, 0x733f },
+ { 4175, 0x27bc }, { 4184, 0x4974 }, { 4191, 0x0ddc }, { 4199, 0x9213 },
+ /* 0x7600 */
+ { 4205, 0x142b }, { 4211, 0x8ba1 }, { 4218, 0x2e75 }, { 4227, 0xd139 },
+ { 4235, 0x3009 }, { 4239, 0x5050 }, { 4243, 0x8808 }, { 4246, 0x6900 },
+ { 4250, 0x49d4 }, { 4257, 0x024a }, { 4261, 0x4010 }, { 4263, 0x8016 },
+ { 4267, 0xe564 }, { 4275, 0x89d7 }, { 4284, 0xc020 }, { 4287, 0x5316 },
+ /* 0x7700 */
+ { 4294, 0x2b92 }, { 4301, 0x8600 }, { 4304, 0xa345 }, { 4311, 0x15e0 },
+ { 4317, 0x008b }, { 4321, 0x0c03 }, { 4325, 0x196e }, { 4333, 0xe200 },
+ { 4337, 0x7031 }, { 4343, 0x8006 }, { 4346, 0x16a5 }, { 4353, 0xa829 },
+ { 4359, 0x2000 }, { 4360, 0x1880 }, { 4363, 0x7aac }, { 4372, 0xe148 },
+ /* 0x7800 */
+ { 4378, 0x3207 }, { 4384, 0xb5d6 }, { 4394, 0x32e8 }, { 4401, 0x5f91 },
+ { 4410, 0x50a1 }, { 4415, 0x20e5 }, { 4421, 0x7c00 }, { 4426, 0x1080 },
+ { 4428, 0x7280 }, { 4433, 0x9d8a }, { 4441, 0x00aa }, { 4445, 0x421f },
+ { 4452, 0x0e22 }, { 4457, 0x0231 }, { 4461, 0x1100 }, { 4463, 0x0494 },
+ /* 0x7900 */
+ { 4467, 0x0022 }, { 4469, 0x4008 }, { 4471, 0x0010 }, { 4472, 0x5c10 },
+ { 4477, 0x0343 }, { 4482, 0xfcc8 }, { 4491, 0xa1a5 }, { 4498, 0x0580 },
+ { 4501, 0x8433 }, { 4507, 0x0400 }, { 4508, 0x0080 }, { 4509, 0x6e08 },
+ { 4515, 0x2a4b }, { 4522, 0x8126 }, { 4527, 0xaad8 }, { 4535, 0x2901 },
+ /* 0x7a00 */
+ { 4539, 0x684d }, { 4546, 0x4490 }, { 4550, 0x0009 }, { 4552, 0xba88 },
+ { 4559, 0x0040 }, { 4560, 0x0082 }, { 4562, 0x0000 }, { 4562, 0x87d1 },
+ { 4570, 0x215b }, { 4577, 0xb1e6 }, { 4586, 0x3161 }, { 4592, 0x8008 },
+ { 4594, 0x0800 }, { 4595, 0xc240 }, { 4599, 0xa069 }, { 4605, 0xa600 },
+ /* 0x7b00 */
+ { 4609, 0x8d58 }, { 4616, 0x4a32 }, { 4622, 0x5d71 }, { 4631, 0x550a },
+ { 4637, 0x9aa0 }, { 4643, 0x2d57 }, { 4652, 0x4005 }, { 4655, 0x4aa6 },
+ { 4662, 0x2021 }, { 4665, 0x30b1 }, { 4671, 0x3fc6 }, { 4681, 0x0112 },
+ { 4684, 0x10c2 }, { 4688, 0x260a }, { 4693, 0x4462 }, { 4698, 0x5082 },
+ /* 0x7c00 */
+ { 4702, 0x9880 }, { 4706, 0x8040 }, { 4708, 0x04c0 }, { 4711, 0x8100 },
+ { 4713, 0x2003 }, { 4716, 0x0000 }, { 4716, 0x0000 }, { 4716, 0x3818 },
+ { 4721, 0x0200 }, { 4722, 0xf1a6 }, { 4731, 0x4434 }, { 4736, 0x720e },
+ { 4743, 0x35a2 }, { 4750, 0x92e0 }, { 4756, 0x8101 }, { 4759, 0x0900 },
+ /* 0x7d00 */
+ { 4761, 0x0400 }, { 4762, 0x0000 }, { 4762, 0x8885 }, { 4767, 0x0000 },
+ { 4767, 0x0000 }, { 4767, 0x0000 }, { 4767, 0x4000 }, { 4768, 0x0080 },
+ { 4769, 0x0000 }, { 4769, 0x0000 }, { 4769, 0x4040 }, { 4771, 0x0000 },
+ { 4771, 0x0000 }, { 4771, 0x0000 }, { 4771, 0x0000 }, { 4771, 0x0000 },
+ /* 0x7e00 */
+ { 4771, 0x0000 }, { 4771, 0x0000 }, { 4771, 0x0000 }, { 4771, 0x0800 },
+ { 4772, 0x0082 }, { 4774, 0x0000 }, { 4774, 0x0000 }, { 4774, 0x0000 },
+ { 4774, 0x0004 }, { 4775, 0x8800 }, { 4777, 0xbfff }, { 4792, 0xe7ef },
+ { 4805, 0xffff }, { 4821, 0xffbf }, { 4836, 0xefef }, { 4850, 0xfdff },
+ /* 0x7f00 */
+ { 4865, 0xfbff }, { 4880, 0xbffe }, { 4894, 0xffff }, { 4910, 0x057f },
+ { 4919, 0x0034 }, { 4922, 0x85b3 }, { 4930, 0x4706 }, { 4936, 0x4216 },
+ { 4941, 0x5402 }, { 4945, 0xe410 }, { 4950, 0x8092 }, { 4954, 0xb305 },
+ { 4961, 0x5422 }, { 4966, 0x8130 }, { 4970, 0x4263 }, { 4976, 0x180b },
+ /* 0x8000 */
+ { 4981, 0x387b }, { 4990, 0x13f5 }, { 4999, 0x07e5 }, { 5007, 0xa9ea },
+ { 5016, 0x3c4c }, { 5023, 0x0514 }, { 5027, 0x0600 }, { 5029, 0x8002 },
+ { 5031, 0x1ad9 }, { 5039, 0xbd48 }, { 5047, 0xee37 }, { 5058, 0xf496 },
+ { 5067, 0x705f }, { 5076, 0x7ec0 }, { 5084, 0xbfb2 }, { 5095, 0x355f },
+ /* 0x8100 */
+ { 5105, 0xe644 }, { 5112, 0x455f }, { 5121, 0x9000 }, { 5123, 0x4146 },
+ { 5128, 0x1d40 }, { 5133, 0x063b }, { 5140, 0x62a1 }, { 5146, 0xfe13 },
+ { 5156, 0x8505 }, { 5161, 0x3902 }, { 5166, 0x0548 }, { 5170, 0x0c08 },
+ { 5173, 0x144f }, { 5180, 0x0000 }, { 5180, 0x3488 }, { 5185, 0x5818 },
+ /* 0x8200 */
+ { 5190, 0x3077 }, { 5198, 0xd815 }, { 5205, 0xbd0e }, { 5214, 0x4bfb },
+ { 5225, 0x8a90 }, { 5230, 0x8500 }, { 5233, 0xc100 }, { 5236, 0xe61d },
+ { 5245, 0xed14 }, { 5253, 0xb386 }, { 5261, 0xff72 }, { 5273, 0x639b },
+ { 5282, 0xfd92 }, { 5292, 0xd9be }, { 5303, 0x887b }, { 5311, 0x0a92 },
+ /* 0x8300 */
+ { 5316, 0xd3fe }, { 5328, 0x1cb2 }, { 5335, 0xb980 }, { 5341, 0x177a },
+ { 5350, 0x82c9 }, { 5356, 0xdc17 }, { 5365, 0xfffb }, { 5380, 0x3980 },
+ { 5385, 0x4260 }, { 5389, 0x590c }, { 5395, 0x0f01 }, { 5400, 0x37df },
+ { 5412, 0x94a3 }, { 5419, 0xb150 }, { 5425, 0x0623 }, { 5430, 0x2307 },
+ /* 0x8400 */
+ { 5436, 0xf85a }, { 5445, 0x3102 }, { 5449, 0x01f0 }, { 5454, 0x3102 },
+ { 5458, 0x0040 }, { 5459, 0x1e82 }, { 5465, 0x3a0a }, { 5471, 0x056a },
+ { 5477, 0x5b84 }, { 5484, 0x1280 }, { 5487, 0x8002 }, { 5489, 0xa714 },
+ { 5496, 0x2612 }, { 5501, 0xa04b }, { 5507, 0x1069 }, { 5512, 0x9001 },
+ /* 0x8500 */
+ { 5515, 0x1000 }, { 5516, 0x848a }, { 5521, 0x1802 }, { 5524, 0x3f80 },
+ { 5531, 0x0708 }, { 5535, 0x4240 }, { 5538, 0x0110 }, { 5540, 0x4e14 },
+ { 5546, 0x80b0 }, { 5550, 0x1800 }, { 5552, 0xc510 }, { 5557, 0x0281 },
+ { 5560, 0x8202 }, { 5563, 0x1029 }, { 5567, 0x0210 }, { 5569, 0x8800 },
+ /* 0x8600 */
+ { 5571, 0x0020 }, { 5572, 0x0042 }, { 5574, 0x0280 }, { 5576, 0x1100 },
+ { 5578, 0xe000 }, { 5581, 0x4413 }, { 5586, 0x5804 }, { 5590, 0xfe02 },
+ { 5598, 0x3c07 }, { 5605, 0x3028 }, { 5609, 0x9798 }, { 5617, 0x0473 },
+ { 5623, 0xced1 }, { 5632, 0xcb13 }, { 5640, 0x6210 }, { 5644, 0x431f },
+ /* 0x8700 */
+ { 5652, 0x278d }, { 5660, 0x55ac }, { 5668, 0x422e }, { 5674, 0xc892 },
+ { 5680, 0x5380 }, { 5685, 0x0288 }, { 5688, 0x4039 }, { 5693, 0x7851 },
+ { 5700, 0x292c }, { 5706, 0x8088 }, { 5709, 0xb900 }, { 5714, 0x2428 },
+ { 5718, 0x0c41 }, { 5722, 0x080e }, { 5726, 0x4421 }, { 5730, 0x4200 },
+ /* 0x8800 */
+ { 5732, 0x0408 }, { 5734, 0x0868 }, { 5738, 0x0006 }, { 5740, 0x1204 },
+ { 5743, 0x3031 }, { 5748, 0x0290 }, { 5751, 0x5b3e }, { 5761, 0xe085 },
+ { 5767, 0x2936 }, { 5774, 0x1044 }, { 5777, 0x2814 }, { 5781, 0x1082 },
+ { 5784, 0x4266 }, { 5790, 0x8334 }, { 5796, 0x013c }, { 5801, 0x531b },
+ /* 0x8900 */
+ { 5809, 0x0404 }, { 5811, 0x0e0d }, { 5817, 0x0c22 }, { 5821, 0x0051 },
+ { 5824, 0x0012 }, { 5826, 0xc000 }, { 5828, 0x0040 }, { 5829, 0x8800 },
+ { 5831, 0x004a }, { 5834, 0x0000 }, { 5834, 0x0000 }, { 5834, 0x0000 },
+ { 5834, 0xdff6 }, { 5847, 0x5447 }, { 5854, 0x8868 }, { 5859, 0x0008 },
+ /* 0x8a00 */
+ { 5860, 0x0081 }, { 5862, 0x0000 }, { 5862, 0x0000 }, { 5862, 0x4000 },
+ { 5863, 0x0100 }, { 5864, 0x0000 }, { 5864, 0x0000 }, { 5864, 0x0200 },
+ { 5865, 0x0600 }, { 5867, 0x0008 }, { 5868, 0x0000 }, { 5868, 0x0000 },
+ { 5868, 0x0000 }, { 5868, 0x0000 }, { 5868, 0x0000 }, { 5868, 0x0000 },
+ /* 0x8b00 */
+ { 5868, 0x0080 }, { 5869, 0x0000 }, { 5869, 0x0040 }, { 5870, 0x0000 },
+ { 5870, 0x0000 }, { 5870, 0x0000 }, { 5870, 0x1040 }, { 5872, 0x0000 },
+ { 5872, 0x0000 }, { 5872, 0x0000 }, { 5872, 0xefff }, { 5887, 0xf7fd },
+ { 5901, 0xff7f }, { 5916, 0xfffe }, { 5931, 0xfbff }, { 5946, 0xffff },
+ /* 0x8c00 */
+ { 5962, 0xfdff }, { 5977, 0xbfff }, { 5992, 0xffff }, { 6008, 0x00ff },
+ { 6016, 0x12c2 }, { 6021, 0x0420 }, { 6023, 0x0c06 }, { 6027, 0x0708 },
+ { 6031, 0x1624 }, { 6036, 0x0110 }, { 6038, 0x0000 }, { 6038, 0x0000 },
+ { 6038, 0x0000 }, { 6038, 0x0000 }, { 6038, 0x0000 }, { 6038, 0x0000 },
+ /* 0x8d00 */
+ { 6038, 0x0000 }, { 6038, 0xe000 }, { 6041, 0xfffe }, { 6056, 0xffff },
+ { 6072, 0xffff }, { 6088, 0x7f79 }, { 6100, 0x28df }, { 6109, 0x00f9 },
+ { 6115, 0x0c32 }, { 6120, 0x8012 }, { 6123, 0x0008 }, { 6124, 0xd53a },
+ { 6133, 0xd858 }, { 6140, 0xecc2 }, { 6148, 0x9d18 }, { 6155, 0x2fa8 },
+ /* 0x8e00 */
+ { 6163, 0x9620 }, { 6168, 0xe010 }, { 6172, 0xd60c }, { 6179, 0x2622 },
+ { 6184, 0x0f97 }, { 6193, 0x0206 }, { 6196, 0xb240 }, { 6201, 0x9055 },
+ { 6207, 0x80a2 }, { 6211, 0x5011 }, { 6215, 0x9800 }, { 6218, 0x0404 },
+ { 6220, 0x4000 }, { 6221, 0x0000 }, { 6221, 0x0000 }, { 6221, 0x0000 },
+ /* 0x8f00 */
+ { 6221, 0x0000 }, { 6221, 0x0000 }, { 6221, 0x0000 }, { 6221, 0x0000 },
+ { 6221, 0x0000 }, { 6221, 0x0000 }, { 6221, 0xfbc0 }, { 6230, 0xffff },
+ { 6246, 0xeffe }, { 6260, 0xdffb }, { 6274, 0x0b08 }, { 6278, 0x6243 },
+ { 6284, 0x41b6 }, { 6291, 0xfb3b }, { 6303, 0x6f74 }, { 6313, 0x2389 },
+ /* 0x9000 */
+ { 6319, 0xae7f }, { 6331, 0xecd7 }, { 6342, 0xe047 }, { 6349, 0x5960 },
+ { 6355, 0xa096 }, { 6361, 0x098f }, { 6368, 0x612c }, { 6374, 0xa030 },
+ { 6378, 0x090d }, { 6383, 0x2aaa }, { 6390, 0xd44e }, { 6398, 0x4f7b },
+ { 6409, 0xc4b2 }, { 6416, 0x388b }, { 6423, 0xa9c6 }, { 6431, 0x6110 },
+ /* 0x9100 */
+ { 6435, 0x0014 }, { 6437, 0x4200 }, { 6439, 0x800c }, { 6442, 0x0202 },
+ { 6444, 0xfe48 }, { 6453, 0x6485 }, { 6459, 0xd63e }, { 6469, 0xe3f7 },
+ { 6481, 0x3aa0 }, { 6487, 0x0c07 }, { 6492, 0xe40c }, { 6498, 0x0430 },
+ { 6501, 0xf680 }, { 6508, 0x1002 }, { 6510, 0x0000 }, { 6510, 0x0000 },
+ /* 0x9200 */
+ { 6510, 0x0000 }, { 6510, 0x0000 }, { 6510, 0x0000 }, { 6510, 0x0000 },
+ { 6510, 0x0000 }, { 6510, 0x0000 }, { 6510, 0x0000 }, { 6510, 0x0010 },
+ { 6511, 0x4000 }, { 6512, 0x0000 }, { 6512, 0x4000 }, { 6513, 0x0000 },
+ { 6513, 0x0100 }, { 6514, 0x0000 }, { 6514, 0x0000 }, { 6514, 0x0000 },
+ /* 0x9300 */
+ { 6514, 0x0000 }, { 6514, 0x0000 }, { 6514, 0x0000 }, { 6514, 0x4000 },
+ { 6515, 0x0000 }, { 6515, 0x0000 }, { 6515, 0x0400 }, { 6516, 0x0000 },
+ { 6516, 0x8000 }, { 6517, 0x0000 }, { 6517, 0x0000 }, { 6517, 0x0000 },
+ { 6517, 0x0400 }, { 6518, 0x0040 }, { 6519, 0x0000 }, { 6519, 0x0000 },
+ /* 0x9400 */
+ { 6519, 0x0000 }, { 6519, 0x0000 }, { 6519, 0x0000 }, { 6519, 0x4000 },
+ { 6520, 0x0000 }, { 6520, 0x0000 }, { 6520, 0x0800 }, { 6521, 0x0000 },
+ { 6521, 0xffe0 }, { 6532, 0xfebd }, { 6545, 0xffff }, { 6561, 0xffff },
+ { 6577, 0x7f7f }, { 6591, 0xfbe7 }, { 6604, 0xffbf }, { 6619, 0xf7ff },
+ /* 0x9500 */
+ { 6634, 0xffff }, { 6650, 0xefff }, { 6665, 0xff7e }, { 6679, 0xdff7 },
+ { 6693, 0xf6f7 }, { 6706, 0xfbdf }, { 6720, 0xbffe }, { 6734, 0x804f },
+ { 6740, 0x0000 }, { 6740, 0x0000 }, { 6740, 0x0000 }, { 6740, 0x0000 },
+ { 6740, 0x0000 }, { 6740, 0x0000 }, { 6740, 0xef00 }, { 6747, 0x7fff },
+ /* 0x9600 */
+ { 6762, 0xff7f }, { 6777, 0xb6f7 }, { 6789, 0x4406 }, { 6793, 0xb87e },
+ { 6803, 0x3bf5 }, { 6814, 0x8831 }, { 6819, 0x1796 }, { 6827, 0x00f4 },
+ { 6832, 0xa960 }, { 6838, 0x1391 }, { 6844, 0x0080 }, { 6845, 0x7249 },
+ { 6852, 0xf2f3 }, { 6863, 0x0024 }, { 6865, 0x8701 }, { 6870, 0x42c8 },
+ /* 0x9700 */
+ { 6875, 0xe3d3 }, { 6885, 0x5048 }, { 6889, 0x2400 }, { 6891, 0x4305 },
+ { 6896, 0x0000 }, { 6896, 0x4a4c }, { 6902, 0x0227 }, { 6907, 0x1058 },
+ { 6911, 0x2820 }, { 6914, 0x0116 }, { 6918, 0xa809 }, { 6923, 0x0014 },
+ { 6925, 0x0000 }, { 6925, 0x0000 }, { 6925, 0x3ec0 }, { 6932, 0x0068 },
+ /* 0x9800 */
+ { 6935, 0x0000 }, { 6935, 0x0000 }, { 6935, 0x0000 }, { 6935, 0x0000 },
+ { 6935, 0x0000 }, { 6935, 0x0000 }, { 6935, 0x0000 }, { 6935, 0xffe0 },
+ { 6946, 0xb7ff }, { 6960, 0xfddb }, { 6973, 0x00f7 }, { 6980, 0x0000 },
+ { 6980, 0x4000 }, { 6981, 0xc72e }, { 6990, 0x0180 }, { 6992, 0x0000 },
+ /* 0x9900 */
+ { 6992, 0x2000 }, { 6993, 0x0001 }, { 6994, 0x4000 }, { 6995, 0x0000 },
+ { 6995, 0x0000 }, { 6995, 0x0030 }, { 6997, 0xffa8 }, { 7008, 0xb4f7 },
+ { 7019, 0xadf3 }, { 7030, 0x03ff }, { 7040, 0x0120 }, { 7042, 0x0000 },
+ { 7042, 0x0000 }, { 7042, 0x0000 }, { 7042, 0x0000 }, { 7042, 0x0000 },
+ /* 0x9a00 */
+ { 7042, 0x0000 }, { 7042, 0x0000 }, { 7042, 0x0000 }, { 7042, 0x0000 },
+ { 7042, 0x0000 }, { 7042, 0x0000 }, { 7042, 0xf000 }, { 7046, 0xfffb },
+ { 7061, 0x9df7 }, { 7073, 0xfdcf }, { 7086, 0x01bf }, { 7094, 0x15c3 },
+ { 7101, 0x1827 }, { 7107, 0x810a }, { 7111, 0xa842 }, { 7116, 0x0a00 },
+ /* 0x9b00 */
+ { 7118, 0x8108 }, { 7121, 0x8008 }, { 7123, 0x8008 }, { 7125, 0x1804 },
+ { 7128, 0xa3be }, { 7138, 0x0012 }, { 7140, 0x0000 }, { 7140, 0x0000 },
+ { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 },
+ { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 },
+ /* 0x9c00 */
+ { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 },
+ { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x9000 },
+ { 7142, 0x69e6 }, { 7151, 0xdc37 }, { 7161, 0x6bff }, { 7174, 0x3dff },
+ { 7187, 0xfcf8 }, { 7198, 0xf3f9 }, { 7210, 0x0004 },
+};
+static const Summary16 gb2312_uni2indx_page9e[27] = {
+ /* 0x9e00 */
+ { 7211, 0x0000 }, { 7211, 0x8000 }, { 7212, 0xbf6f }, { 7225, 0xe7ee },
+ { 7237, 0xdffe }, { 7251, 0x5da2 }, { 7259, 0x3fd8 }, { 7269, 0xc00b },
+ { 7274, 0x0984 }, { 7278, 0xa00c }, { 7282, 0x0040 }, { 7283, 0x6910 },
+ { 7288, 0xe210 }, { 7293, 0xb912 }, { 7300, 0x86a5 }, { 7307, 0x5a00 },
+ /* 0x9f00 */
+ { 7311, 0x6800 }, { 7314, 0x0289 }, { 7318, 0x9005 }, { 7322, 0x6a80 },
+ { 7327, 0x0010 }, { 7328, 0x0003 }, { 7330, 0x0000 }, { 7330, 0x8000 },
+ { 7331, 0x1ff9 }, { 7342, 0x8e00 }, { 7346, 0x0001 },
+};
+static const Summary16 gb2312_uni2indx_pageff[15] = {
+ /* 0xff00 */
+ { 7347, 0xfffe }, { 7362, 0xffff }, { 7378, 0xffff }, { 7394, 0xffff },
+ { 7410, 0xffff }, { 7426, 0x7fff }, { 7441, 0x0000 }, { 7441, 0x0000 },
+ { 7441, 0x0000 }, { 7441, 0x0000 }, { 7441, 0x0000 }, { 7441, 0x0000 },
+ { 7441, 0x0000 }, { 7441, 0x0000 }, { 7441, 0x002b },
+};
+
+INTERNAL int gb2312_wctomb_zint(unsigned int* r, unsigned int wc) {
+ const Summary16 *summary = NULL;
+ if (wc < 0x0460) {
+ if (wc == 0x00b7) { /* ZINT: Patched to duplicate map to 0xA1A4 */
+ *r = 0xA1A4;
+ return 2;
+ }
+ summary = &gb2312_uni2indx_page00[(wc>>4)];
+ } else if (wc >= 0x2000 && wc < 0x2650) {
+ if (wc == 0x2014) { /* ZINT: Patched to duplicate map to 0xA1AA */
+ *r = 0xA1AA;
+ return 2;
+ }
+ summary = &gb2312_uni2indx_page20[(wc>>4)-0x200];
+ } else if (wc >= 0x3000 && wc < 0x3230) {
+ summary = &gb2312_uni2indx_page30[(wc>>4)-0x300];
+ } else if (wc >= 0x4e00 && wc < 0x9cf0) {
+ summary = &gb2312_uni2indx_page4e[(wc>>4)-0x4e0];
+ } else if (wc >= 0x9e00 && wc < 0x9fb0) {
+ summary = &gb2312_uni2indx_page9e[(wc>>4)-0x9e0];
+ } else if (wc >= 0xff00 && wc < 0xfff0) {
+ summary = &gb2312_uni2indx_pageff[(wc>>4)-0xff0];
+ }
+ if (summary) {
+ unsigned short used = summary->used;
+ unsigned int i = wc & 0x0f;
+ if (used & ((unsigned short) 1 << i)) {
+ /* Keep in 'used' only the bits 0..i-1. */
+ used &= ((unsigned short) 1 << i) - 1;
+ /* Add 'summary->indx' and the number of bits set in 'used'. */
+ used = (used & 0x5555) + ((used & 0xaaaa) >> 1);
+ used = (used & 0x3333) + ((used & 0xcccc) >> 2);
+ used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4);
+ used = (used & 0x00ff) + (used >> 8);
+ *r = gb2312_2charset[summary->indx + used];
+ return 2;
+ }
+ }
+ return 0;
+}
+
+/* Convert UTF-8 string to GB 2312 (EUC-CN) and place in array of ints */
+INTERNAL int gb2312_utf8tomb(struct zint_symbol *symbol, const unsigned char source[], size_t* p_length, unsigned int* gbdata) {
+ int error_number;
+ unsigned int i, length;
+#ifndef _MSC_VER
+ unsigned int utfdata[*p_length + 1];
+#else
+ unsigned int* utfdata = (unsigned int*) _alloca((*p_length + 1) * sizeof(unsigned int));
+#endif
+
+ error_number = utf8_to_unicode(symbol, source, utfdata, p_length, 1 /*disallow_4byte*/);
+ if (error_number != 0) {
+ return error_number;
+ }
+
+ for (i = 0, length = *p_length; i < length; i++) {
+ if (utfdata[i] < 0x80) {
+ gbdata[i] = utfdata[i];
+ } else {
+ if (!gb2312_wctomb_zint(gbdata + i, utfdata[i])) {
+ strcpy(symbol->errtxt, "810: Invalid character in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* Convert UTF-8 string to single byte ECI and place in array of ints */
+INTERNAL int gb2312_utf8tosb(int eci, const unsigned char source[], size_t* p_length, unsigned int* gbdata, int full_multibyte) {
+ int error_number;
+#ifndef _MSC_VER
+ unsigned char single_byte[*p_length + 1];
+#else
+ unsigned char* single_byte = (unsigned char*) _alloca(*p_length + 1);
+#endif
+
+ error_number = utf_to_eci(eci, source, single_byte, p_length);
+ if (error_number != 0) {
+ /* Note not setting `symbol->errtxt`, up to caller */
+ return error_number;
+ }
+
+ gb2312_cpy(single_byte, p_length, gbdata, full_multibyte);
+
+ return 0;
+}
+
+/* If `full_multibyte` set, copy byte input stream to array of ints, putting double-bytes that match GRIDMATRIX Chinese mode in a single entry.
+ * If `full_multibyte` not set, do a straight copy */
+INTERNAL void gb2312_cpy(const unsigned char source[], size_t* p_length, unsigned int* gbdata, int full_multibyte) {
+ unsigned int i, j, length;
+ unsigned char c1, c2;
+
+ if (full_multibyte) {
+ for (i = 0, j = 0, length = *p_length; i < length; i++, j++) {
+ if (length - i >= 2) {
+ c1 = source[i];
+ c2 = source[i + 1];
+ if (((c1 >= 0xA1 && c1 <= 0xA9) || (c1 >= 0xB0 && c1 <= 0xF7)) && c2 >= 0xA1 && c2 <= 0xFE) {
+ /* This may or may not be valid GB 2312 (EUC-CN), but don't care as long as it can be encoded in GRIDMATRIX Chinese mode */
+ gbdata[j] = (c1 << 8) | c2;
+ i++;
+ } else {
+ gbdata[j] = c1;
+ }
+ } else {
+ gbdata[j] = source[i];
+ }
+ }
+ *p_length = j;
+ } else {
+ /* Straight copy */
+ for (i = 0, length = *p_length; i < length; i++) {
+ gbdata[i] = source[i];
+ }
+ }
+}
diff --git a/backend/gb2312.h b/backend/gb2312.h
index 572ff3b..b3ca91b 100644
--- a/backend/gb2312.h
+++ b/backend/gb2312.h
@@ -1,7 +1,7 @@
-/* gb2312.h - Unicode to GB 2312-1980 lookup table
+/* gb2312.h - Unicode to GB 2312-1980 (EUC-CN)
libzint - the open source barcode library
- Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2009-2020 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -27,7452 +27,23 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
-static const 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
-};
+#ifndef GB2312_H
+#define GB2312_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+INTERNAL int gb2312_wctomb_zint(unsigned int* r, unsigned int wc);
+INTERNAL int gb2312_utf8tomb(struct zint_symbol *symbol, const unsigned char source[], size_t* p_length, unsigned int* gbdata);
+INTERNAL int gb2312_utf8tosb(int eci, const unsigned char source[], size_t* p_length, unsigned int* gbdata, int full_multibyte);
+INTERNAL void gb2312_cpy(const unsigned char source[], size_t* p_length, unsigned int* gbdata, int full_multibyte);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* GB2312_H */
diff --git a/backend/general_field.c b/backend/general_field.c
new file mode 100644
index 0000000..13c5ed0
--- /dev/null
+++ b/backend/general_field.c
@@ -0,0 +1,187 @@
+/* general_field.c - Handles general field compaction (GS1 DataBar and composites) */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <string.h>
+#include "common.h"
+#include "general_field.h"
+
+static char alphanum_puncs[] = "*,-./";
+static char isoiec_puncs[] = "!\"%&'()*+,-./:;<=>?_ ";
+
+/* Returns type of char at `i`. FNC1 counted as NUMERIC. Returns 0 if invalid char */
+static int general_field_type(char* general_field, int i) {
+ if (general_field[i] == '[' || (general_field[i] >= '0' && general_field[i] <= '9')) {
+ return NUMERIC;
+ }
+ if ((general_field[i] >= 'A' && general_field[i] <= 'Z') || strchr(alphanum_puncs, general_field[i])) {
+ return ALPHA;
+ }
+ if ((general_field[i] >= 'a' && general_field[i] <= 'z') || strchr(isoiec_puncs, general_field[i])) {
+ return ISOIEC;
+ }
+ return 0;
+}
+
+/* Returns true if next (including `i`) `num` chars of type `type`, or if given (non-zero), `type2` */
+static int general_field_next(char* general_field, int i, int general_field_len, int num, int type, int type2) {
+ if (i + num > general_field_len) {
+ return 0;
+ }
+ for (; i < general_field_len && num; i++, num--) {
+ int type_i = general_field_type(general_field, i);
+ if ((type_i != type && !type2) || (type_i != type && type_i != type2)) {
+ return 0;
+ }
+ }
+ return num == 0;
+}
+
+/* Returns true if next (including `i`) `num` up to `max_num` chars of type `type` and occur at end */
+static int general_field_next_terminate(char* general_field, int i, int general_field_len, int num, int max_num, int type) {
+ if (i + max_num < general_field_len) {
+ return 0;
+ }
+ for (; i < general_field_len; i++, num--) {
+ if (general_field_type(general_field, i) != type) {
+ return 0;
+ }
+ }
+ return i == general_field_len && num <= 0;
+}
+
+/* Returns true if none of the next (including `i`) `num` chars (or end occurs) of type `type` */
+static int general_field_next_none(char* general_field, int i, int general_field_len, int num, int type) {
+ for (; i < general_field_len && num; i++, num--) {
+ if (general_field_type(general_field, i) == type) {
+ return 0;
+ }
+ }
+ return num == 0 || i == general_field_len;
+}
+
+/* Attempts to apply encoding rules from sections 7.2.5.5.1 to 7.2.5.5.3
+ * of ISO/IEC 24724:2011 (same as sections 5.4.1 to 5.4.3 of ISO/IEC 24723:2010) */
+INTERNAL int general_field_encode(char* general_field, int* p_mode, int* p_last_digit, char binary_string[]) {
+ int i, d1, d2;
+ int mode = *p_mode;
+ int last_digit = 0; /* Set to odd remaining digit at end if any */
+ int general_field_len = strlen(general_field);
+
+ for (i = 0; i < general_field_len; ) {
+ int type = general_field_type(general_field, i);
+ if (!type) {
+ return 0;
+ }
+ switch (mode) {
+ case NUMERIC:
+ if (i < general_field_len - 1) { /* If at least 2 characters remain */
+ if (type != NUMERIC || general_field_type(general_field, i + 1) != NUMERIC) { /* 7.2.5.5.1/5.4.1 a) */
+ strcat(binary_string, "0000"); /* Alphanumeric latch */
+ mode = ALPHA;
+ } else {
+ d1 = general_field[i] == '[' ? 10 : ctoi(general_field[i]);
+ d2 = general_field[i + 1] == '[' ? 10 : ctoi(general_field[i + 1]);
+ bin_append((11 * d1) + d2 + 8, 7, binary_string);
+ i += 2;
+ }
+ } else { /* If 1 character remains */
+ if (type != NUMERIC) { /* 7.2.5.5.1/5.4.1 b) */
+ strcat(binary_string, "0000"); /* Alphanumeric latch */
+ mode = ALPHA;
+ } else {
+ last_digit = general_field[i]; /* Ending with single digit. 7.2.5.5.1 c) and 5.4.1 c) dealt with separately outside this procedure */
+ i++;
+ }
+ }
+ break;
+ case ALPHA:
+ if (general_field[i] == '[') { /* 7.2.5.5.2/5.4.2 a) */
+ strcat(binary_string, "01111");
+ mode = NUMERIC;
+ i++;
+ } else if (type == ISOIEC) { /* 7.2.5.5.2/5.4.2 b) */
+ strcat(binary_string, "00100"); /* ISO/IEC 646 latch */
+ mode = ISOIEC;
+ } else if (general_field_next(general_field, i, general_field_len, 6, NUMERIC, 0)) { /* 7.2.5.5.2/5.4.2 c) */
+ strcat(binary_string, "000"); /* Numeric latch */
+ mode = NUMERIC;
+ } else if (general_field_next_terminate(general_field, i, general_field_len, 4, 5 /*Can limit to 5 max due to above*/, NUMERIC)) { /* 7.2.5.5.2/5.4.2 d) */
+ strcat(binary_string, "000"); /* Numeric latch */
+ mode = NUMERIC;
+ } else if ((general_field[i] >= '0') && (general_field[i] <= '9')) {
+ bin_append(general_field[i] - 43, 5, binary_string);
+ i++;
+ } else if ((general_field[i] >= 'A') && (general_field[i] <= 'Z')) {
+ bin_append(general_field[i] - 33, 6, binary_string);
+ i++;
+ } else {
+ bin_append(posn(alphanum_puncs, general_field[i]) + 58, 6, binary_string);
+ i++;
+ }
+ break;
+ case ISOIEC:
+ if (general_field[i] == '[') { /* 7.2.5.5.3/5.4.3 a) */
+ strcat(binary_string, "01111");
+ mode = NUMERIC;
+ i++;
+ } else {
+ int next_10_not_isoiec = general_field_next_none(general_field, i, general_field_len, 10, ISOIEC);
+ if (next_10_not_isoiec && general_field_next(general_field, i, general_field_len, 4, NUMERIC, 0)) { /* 7.2.5.5.3/5.4.3 b) */
+ strcat(binary_string, "000"); /* Numeric latch */
+ mode = NUMERIC;
+ } else if (next_10_not_isoiec && general_field_next(general_field, i, general_field_len, 5, ALPHA, NUMERIC)) { /* 7.2.5.5.3/5.4.3 c) */
+ /* Note this rule can produce longer bitstreams if most of the alphanumerics are numeric */
+ strcat(binary_string, "00100"); /* Alphanumeric latch */
+ mode = ALPHA;
+ } else if ((general_field[i] >= '0') && (general_field[i] <= '9')) {
+ bin_append(general_field[i] - 43, 5, binary_string);
+ i++;
+ } else if ((general_field[i] >= 'A') && (general_field[i] <= 'Z')) {
+ bin_append(general_field[i] - 1, 7, binary_string);
+ i++;
+ } else if ((general_field[i] >= 'a') && (general_field[i] <= 'z')) {
+ bin_append(general_field[i] - 7, 7, binary_string);
+ i++;
+ } else {
+ bin_append(posn(isoiec_puncs, general_field[i]) + 232, 8, binary_string);
+ i++;
+ }
+ }
+ break;
+ }
+ }
+
+ *p_mode = mode;
+ *p_last_digit = last_digit;
+ return 1;
+}
diff --git a/backend/general_field.h b/backend/general_field.h
new file mode 100644
index 0000000..11db071
--- /dev/null
+++ b/backend/general_field.h
@@ -0,0 +1,47 @@
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2007-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#ifndef __GENERAL_FIELD_H
+#define __GENERAL_FIELD_H
+
+#define NUMERIC 110
+#define ALPHA 97
+#define ISOIEC 105
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+ INTERNAL int general_field_encode(char* general_field, int* p_mode, int* p_last_digit, char binary_string[]);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GENERAL_FIELD_H */
diff --git a/backend/gif.c b/backend/gif.c
new file mode 100644
index 0000000..c5b19ee
--- /dev/null
+++ b/backend/gif.c
@@ -0,0 +1,584 @@
+/* gif.c - Handles output to gif file */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <stdio.h>
+#include <string.h>
+#include "common.h"
+#include <math.h>
+#ifdef _MSC_VER
+#include <io.h>
+#include <fcntl.h>
+#include <malloc.h>
+#endif
+
+#define SSET "0123456789ABCDEF"
+
+/* Index of transparent color, -1 for no transparent color
+ * This might be set into a variable if transparency is activated as an option
+ */
+#define TRANSPARENT_INDEX (-1)
+
+typedef struct s_statestruct {
+ unsigned char * pOut;
+ unsigned char *pIn;
+ unsigned int InLen;
+ unsigned int OutLength;
+ unsigned int OutPosCur;
+ unsigned int OutByteCountPos;
+ unsigned short ClearCode;
+ unsigned short FreeCode;
+ char fByteCountByteSet;
+ unsigned char OutBitsFree;
+ unsigned short NodeAxon[4096];
+ unsigned short NodeNext[4096];
+ unsigned char NodePix[4096];
+ unsigned char colourCode[10];
+ unsigned char colourPaletteIndex[10];
+ int colourCount;
+} statestruct;
+
+/* Transform a Pixel to a lzw colourmap index and move to next pixel.
+ * All colour values are listed in colourCode with corresponding palette index
+ */
+static unsigned char NextPaletteIndex(statestruct *pState)
+{
+ unsigned char pixelColour;
+ int colourIndex;
+ pixelColour = *(pState->pIn);
+ (pState->pIn)++;
+ (pState->InLen)--;
+ for (colourIndex = 0; colourIndex < pState->colourCount; colourIndex++) {
+ if (pixelColour == pState->colourCode[colourIndex])
+ return pState->colourPaletteIndex[colourIndex];
+
+ }
+ return 0; /* Not reached */
+}
+
+
+static char BufferNextByte(statestruct *pState) {
+ (pState->OutPosCur)++;
+ /* Check if this position is a byte count position
+ * fg_f_bytecountbyte_set indicates, if byte count position bytes should be
+ * inserted in general.
+ * If this is true, and the distance to the last byte count position is 256
+ * (e.g. 255 bytes in between), a byte count byte is inserted, and the value
+ * of the last one is set to 255.
+ * */
+ if (pState->fByteCountByteSet && (pState->OutByteCountPos + 256 == pState->OutPosCur)) {
+ (pState->pOut)[pState->OutByteCountPos] = 255;
+ pState->OutByteCountPos = pState->OutPosCur;
+ (pState->OutPosCur)++;
+ }
+ if (pState->OutPosCur >= pState->OutLength)
+ return 1;
+
+ (pState->pOut)[pState->OutPosCur] = 0x00;
+ return 0;
+}
+
+static char AddCodeToBuffer(statestruct *pState, unsigned short CodeIn, unsigned char CodeBits) {
+ /* Check, if we may fill up the current byte completely */
+ if (CodeBits >= pState->OutBitsFree) {
+ (pState->pOut)[pState->OutPosCur] |= (unsigned char)
+ (CodeIn << (8 - pState->OutBitsFree));
+ if (BufferNextByte(pState))
+ return -1;
+ CodeIn = (unsigned short) (CodeIn >> pState->OutBitsFree);
+ CodeBits -= pState->OutBitsFree;
+ pState->OutBitsFree = 8;
+ /* Write a full byte if there are at least 8 code bits left */
+ if (CodeBits >= pState->OutBitsFree) {
+ (pState->pOut)[pState->OutPosCur] = (unsigned char) CodeIn;
+ if (BufferNextByte(pState))
+ return -1;
+ CodeIn = (unsigned short) (CodeIn >> 8);
+ CodeBits -= 8;
+ }
+ }
+ /* The remaining bits of CodeIn fit in the current byte. */
+ if (CodeBits > 0) {
+ (pState->pOut)[pState->OutPosCur] |= (unsigned char)
+ (CodeIn << (8 - pState->OutBitsFree));
+ pState->OutBitsFree -= CodeBits;
+ }
+ return 0;
+}
+
+static void FlushStringTable(statestruct *pState) {
+ unsigned short Pos;
+ for (Pos = 0; Pos < pState->ClearCode; Pos++) {
+ (pState->NodeAxon)[Pos] = 0;
+ }
+}
+
+static unsigned short FindPixelOutlet(statestruct *pState, unsigned short HeadNode, unsigned char Byte) {
+ unsigned short Outlet;
+
+ Outlet = (pState->NodeAxon)[HeadNode];
+ while (Outlet) {
+ if ((pState->NodePix)[Outlet] == Byte)
+ return Outlet;
+ Outlet = (pState->NodeNext)[Outlet];
+ }
+ return 0;
+}
+
+static char NextCode(statestruct *pState, unsigned char * pPixelValueCur, unsigned char CodeBits) {
+ unsigned short UpNode;
+ unsigned short DownNode;
+ /* start with the root node for last pixel chain */
+ UpNode = *pPixelValueCur;
+ if ((pState->InLen) == 0)
+ return AddCodeToBuffer(pState, UpNode, CodeBits);
+
+ *pPixelValueCur = NextPaletteIndex(pState);
+ /* Follow the string table and the data stream to the end of the longest string that has a code */
+ while (0 != (DownNode = FindPixelOutlet(pState, UpNode, *pPixelValueCur))) {
+ UpNode = DownNode;
+ if ((pState->InLen) == 0)
+ return AddCodeToBuffer(pState, UpNode, CodeBits);
+
+ *pPixelValueCur = NextPaletteIndex(pState);
+ }
+ /* Submit 'UpNode' which is the code of the longest string */
+ if (AddCodeToBuffer(pState, UpNode, CodeBits))
+ return -1;
+ /* ... and extend the string by appending 'PixelValueCur' */
+ /* Create a successor node for 'PixelValueCur' whose code is 'freecode' */
+ (pState->NodePix)[pState->FreeCode] = *pPixelValueCur;
+ (pState->NodeAxon)[pState->FreeCode] = (pState->NodeNext)[pState->FreeCode] = 0;
+ /* ...and link it to the end of the chain emanating from fg_axon[UpNode]. */
+ DownNode = (pState->NodeAxon)[UpNode];
+ if (!DownNode) {
+ (pState->NodeAxon)[UpNode] = pState->FreeCode;
+ } else {
+ while ((pState->NodeNext)[DownNode]) {
+ DownNode = (pState->NodeNext)[DownNode];
+ }
+ (pState->NodeNext)[DownNode] = pState->FreeCode;
+ }
+ return 1;
+}
+
+static int gif_lzw(statestruct *pState, int paletteBitSize) {
+ unsigned char PixelValueCur;
+ unsigned char CodeBits;
+ unsigned short Pos;
+
+ // > Get first data byte
+ if (pState->InLen == 0)
+ return 0;
+ PixelValueCur = NextPaletteIndex(pState);
+ /* Number of bits per data item (=pixel)
+ * We need at least a value of 2, otherwise the cc and eoi code consumes
+ * the whole string table
+ */
+ if (paletteBitSize == 1)
+ paletteBitSize = 2;
+
+ /* initial size of compression codes */
+ CodeBits = paletteBitSize+1;
+ pState->ClearCode = (1 << paletteBitSize);
+ pState->FreeCode = pState->ClearCode+2;
+ pState->OutBitsFree = 8;
+ pState->OutPosCur = -1;
+ pState->fByteCountByteSet = 0;
+
+ if (BufferNextByte(pState))
+ return 0;
+
+ for (Pos = 0; Pos < pState->ClearCode; Pos++)
+ (pState->NodePix)[Pos] = (unsigned char) Pos;
+
+ FlushStringTable(pState);
+
+ /* Write what the GIF specification calls the "code size". */
+ (pState->pOut)[pState->OutPosCur] = paletteBitSize;
+ /* Reserve first bytecount byte */
+ if (BufferNextByte(pState))
+ return 0;
+ pState->OutByteCountPos = pState->OutPosCur;
+ if (BufferNextByte(pState))
+ return 0;
+ pState->fByteCountByteSet = 1;
+ /* Submit one 'ClearCode' as the first code */
+ if (AddCodeToBuffer(pState, pState->ClearCode, CodeBits))
+ return 0;
+
+ for (;;) {
+ char Res;
+ /* generate and save the next code, which may consist of multiple input pixels. */
+ Res = NextCode(pState, &PixelValueCur, CodeBits);
+ if (Res < 0)
+ return 0;
+ //* Check for end of data stream */
+ if (!Res) {
+ /* submit 'eoi' as the last item of the code stream */
+ if (AddCodeToBuffer(pState, (unsigned short) (pState->ClearCode + 1), CodeBits))
+ return 0;
+ pState->fByteCountByteSet = 0;
+ if (pState->OutBitsFree < 8) {
+ if (BufferNextByte(pState))
+ return 0;
+ }
+ // > Update last bytecount byte;
+ if (pState->OutByteCountPos < pState->OutPosCur) {
+ (pState->pOut)[pState->OutByteCountPos] = (unsigned char) (pState->OutPosCur - pState->OutByteCountPos - 1);
+ }
+ pState->OutPosCur++;
+ return pState->OutPosCur;
+ }
+ /* Check for currently last code */
+ if (pState->FreeCode == (1U << CodeBits))
+ CodeBits++;
+ pState->FreeCode++;
+ /* Check for full stringtable */
+ if (pState->FreeCode == 0xfff) {
+ FlushStringTable(pState);
+ if (AddCodeToBuffer(pState, pState->ClearCode, CodeBits))
+ return 0;
+
+ CodeBits = (unsigned char) (1 + paletteBitSize);
+ pState->FreeCode = (unsigned short) (pState->ClearCode + 2);
+ }
+ }
+}
+
+/*
+ * Called function to save in gif format
+ */
+INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
+ unsigned char outbuf[10];
+ FILE *gif_file;
+ unsigned short usTemp;
+ int byte_out;
+ int colourCount;
+ unsigned char paletteRGB[10][3];
+ int paletteCount, paletteCountCur, paletteIndex;
+ int pixelIndex;
+ int paletteBitSize;
+ int paletteSize;
+ statestruct State;
+
+ unsigned char backgroundColourIndex;
+ unsigned char RGBCur[3];
+
+ int colourIndex;
+
+ int fFound;
+
+ unsigned char pixelColour;
+
+ /* Allow for overhead of 4 == code size + byte count + overflow byte + zero terminator */
+ unsigned int lzoutbufSize = symbol->bitmap_height * symbol->bitmap_width + 4;
+#ifdef _MSC_VER
+ char * lzwoutbuf;
+#endif
+
+#ifndef _MSC_VER
+ char lzwoutbuf[lzoutbufSize];
+#else
+ lzwoutbuf = (char *) _alloca(lzoutbufSize);
+#endif /* _MSC_VER */
+
+ /* 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, "610: Can't open output file");
+ return ZINT_ERROR_FILE_ACCESS;
+ }
+#endif
+ gif_file = stdout;
+ } else {
+ if (!(gif_file = fopen(symbol->outfile, "wb"))) {
+ strcpy(symbol->errtxt, "611: Can't open output file");
+ return ZINT_ERROR_FILE_ACCESS;
+ }
+ }
+
+ /*
+ * Build a table of the used palette items.
+ * Currently, there are the following 10 colour codes:
+ * '0': standard background
+ * '1': standard foreground
+ * 'W': white
+ * 'C': cyan
+ * 'B': blue
+ * 'M': magenta
+ * 'R': red
+ * 'Y': yellow
+ * 'G': green
+ * 'K': black
+ * '0' and '1' may be identical to one of the other values
+ *
+ * A data structure is set up as follows:
+ * state.colourCode: list of colour codes
+ * paletteIndex: palette index of the corresponding colour code
+ * There are colourCount entries in the upper lists.
+ * paletteRGB: RGB value at the palette position
+ * There are paletteCount entries.
+ * This value is smaller to colourCount, if multiple colour codes have the
+ * same RGB value and point to the same palette value.
+ * Example:
+ * 0 1 W K are present. 0 is equal to white, while 1 is blue
+ * The resulting tables are:
+ * paletteItem: ['0']=0 (white), ['1']=1 (blue), ['W']=0 (white),
+ * ['K']=2 (black)
+ * Thus, there are 4 colour codes and 3 palette entries.
+
+ */
+ colourCount = 0;
+ paletteCount = 0;
+ /* loop over all pixels */
+ for ( pixelIndex = 0; pixelIndex < (symbol->bitmap_height * symbol->bitmap_width); pixelIndex++)
+ {
+ fFound = 0;
+ /* get pixel colour code */
+ pixelColour = pixelbuf[pixelIndex];
+ /* look, if colour code is already in colour list */
+ for (colourIndex = 0; colourIndex < colourCount; colourIndex++) {
+ if ((State.colourCode)[colourIndex] == pixelColour) {
+ fFound = 1;
+ break;
+ }
+ }
+ /* If colour is already present, go to next colour code */
+ if (fFound)
+ continue;
+
+ /* Colour code not present - add colour code */
+ /* Get RGB value */
+ switch (pixelColour) {
+ case '0': /* standard background */
+ RGBCur[0] = (unsigned char) (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]);
+ RGBCur[1] = (unsigned char) (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
+ RGBCur[2] = (unsigned char) (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);
+ break;
+ case '1': /* standard foreground */
+ RGBCur[0] = (unsigned char) (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]);
+ RGBCur[1] = (unsigned char) (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]);
+ RGBCur[2] = (unsigned char) (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]);
+ break;
+ case 'W': /* white */
+ RGBCur[0] = 255; RGBCur[1] = 255; RGBCur[2] = 255;
+ break;
+ case 'C': /* cyan */
+ RGBCur[0] = 0; RGBCur[1] = 255; RGBCur[2] = 255;
+ break;
+ case 'B': /* blue */
+ RGBCur[0] = 0; RGBCur[1] = 0; RGBCur[2] = 255;
+ break;
+ case 'M': /* magenta */
+ RGBCur[0] = 255; RGBCur[1] = 0; RGBCur[2] = 255;
+ break;
+ case 'R': /* red */
+ RGBCur[0] = 255; RGBCur[1] = 0; RGBCur[2] = 0;
+ break;
+ case 'Y': /* yellow */
+ RGBCur[0] = 255; RGBCur[1] = 255; RGBCur[2] = 0;
+ break;
+ case 'G': /* green */
+ RGBCur[0] = 0; RGBCur[1] = 255; RGBCur[2] = 0;
+ break;
+ case 'K': /* black */
+ RGBCur[0] = 0; RGBCur[1] = 0; RGBCur[2] = 0;
+ break;
+ default: /* error case - return */
+ strcpy(symbol->errtxt, "611: unknown pixel colour");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ /* Search, if RGB value is already present */
+ fFound = 0;
+ for (paletteIndex = 0; paletteIndex < paletteCount; paletteIndex++) {
+ if (RGBCur[0] == paletteRGB[paletteIndex][0]
+ && RGBCur[1] == paletteRGB[paletteIndex][1]
+ && RGBCur[2] == paletteRGB[paletteIndex][2])
+ {
+ fFound = 1;
+ break;
+ }
+ }
+ /* RGB not present, add it */
+ if (!fFound) {
+ paletteIndex = paletteCount;
+ paletteRGB[paletteIndex][0] = RGBCur[0];
+ paletteRGB[paletteIndex][1] = RGBCur[1];
+
+ paletteRGB[paletteIndex][2] = RGBCur[2];
+
+ paletteCount++;
+ }
+ /* Add palette index to current colour code */
+ (State.colourCode)[colourCount] = pixelColour;
+ (State.colourPaletteIndex)[colourCount] = paletteIndex;
+ colourCount++;
+ }
+ State.colourCount = colourCount;
+
+ /* find palette bit size from palette size*/
+
+ /* 1,2 -> 1, 3,4 ->2, 5,6,7,8->3 */
+ paletteBitSize = 0;
+ paletteCountCur = paletteCount-1;
+ while (paletteCountCur != 0) {
+ paletteBitSize++;
+ paletteCountCur >>= 1;
+ }
+ /* Minimum is 1 */
+ if (paletteBitSize == 0)
+ paletteBitSize = 1;
+
+ /* palette size 2 ^ bit size */
+ paletteSize = 1<<paletteBitSize;
+
+ /* GIF signature (6) */
+ memcpy(outbuf, "GIF87a", 6);
+ if (TRANSPARENT_INDEX != -1)
+ outbuf[4] = '9';
+
+ fwrite(outbuf, 6, 1, gif_file);
+ /* Screen Descriptor (7) */
+ /* Screen Width */
+ usTemp = (unsigned short) symbol->bitmap_width;
+ outbuf[0] = (unsigned char) (0xff & usTemp);
+ outbuf[1] = (unsigned char) ((0xff00 & usTemp) / 0x100);
+ /* Screen Height */
+ usTemp = (unsigned short) symbol->bitmap_height;
+ outbuf[2] = (unsigned char) (0xff & usTemp);
+ outbuf[3] = (unsigned char) ((0xff00 & usTemp) / 0x100);
+ /* write ImageBits-1 to the three least significant bits of byte 5 of
+ * the Screen Descriptor
+ * Bits 76543210
+ * 1 : Global colour map
+ * 111 : 8 bit colour depth of the palette
+ * 0 : Not ordered in decreasing importance
+ * xxx : palette bit zize - 1
+ */
+ outbuf[4] = (unsigned char) (0xf0 | (0x7 & (paletteBitSize - 1)));
+
+ /*
+ * Background colour index
+ * Default to 0. If colour code 0 or K is present, it is used as index
+ */
+
+ backgroundColourIndex = 0;
+ for (colourIndex = 0; colourIndex < colourCount; colourIndex++) {
+ if ((State.colourCode)[colourIndex] == '0' || (State.colourCode)[colourIndex] == 'W') {
+ backgroundColourIndex = (State.colourPaletteIndex)[colourIndex];
+ break;
+ }
+ }
+ outbuf[5] = backgroundColourIndex;
+ /* Byte 7 must be 0x00 */
+ outbuf[6] = 0x00;
+ fwrite(outbuf, 7, 1, gif_file);
+ /* Global Color Table (paletteSize*3) */
+ fwrite(paletteRGB, 3*paletteCount, 1, gif_file);
+ /* add unused palette items to fill palette size */
+ for (paletteIndex = paletteCount; paletteIndex < paletteSize; paletteIndex++) {
+ unsigned char RGBCur[3] = {0,0,0};
+ fwrite(RGBCur, 3, 1, gif_file);
+ }
+
+ /* Graphic control extension (8) */
+ /* A graphic control extension block is used for overlay gifs.
+ * This is necessary to define a transparent color.
+ */
+ if (TRANSPARENT_INDEX != -1) {
+ /* Extension Introducer = '!' */
+ outbuf[0] = '\x21';
+ /* Graphic Control Label */
+ outbuf[1] = '\xf9';
+ /* Block Size */
+ outbuf[2] = 4;
+ /* Packet fields:
+ * 3 Reserved
+ * 3 Disposal Method: 0 No Action, 1 No Dispose, 2: Background, 3: Prev.
+ * 1 User Input Flag: 0: no user input, 1: user input
+ * 1 Transparent Color Flag: 0: No Transparency, 1: Transparency index
+ */
+ outbuf[3] = 1;
+ /* Delay Time */
+ outbuf[4] = 0;
+ outbuf[5] = 0;
+ /* Transparent Color Index */
+ outbuf[6] = (unsigned char) TRANSPARENT_INDEX;
+ /* Block Terminator */
+ outbuf[7] = 0;
+ fwrite(outbuf, 8, 1, gif_file);
+ }
+ /* Image Descriptor */
+ /* Image separator character = ',' */
+ outbuf[0] = 0x2c;
+ /* "Image Left" */
+ outbuf[1] = 0x00;
+ outbuf[2] = 0x00;
+ /* "Image Top" */
+ outbuf[3] = 0x00;
+ outbuf[4] = 0x00;
+ /* Image Width (low byte first) */
+ outbuf[5] = (unsigned char) (0xff & symbol->bitmap_width);
+ outbuf[6] = (unsigned char) ((0xff00 & symbol->bitmap_width) / 0x100);
+ /* Image Height */
+ outbuf[7] = (unsigned char) (0xff & symbol->bitmap_height);
+ outbuf[8] = (unsigned char) ((0xff00 & symbol->bitmap_height) / 0x100);
+
+ /* Byte 10 contains the interlaced flag and
+ * information on the local color table.
+ * There is no local color table if its most significant bit is reset.
+ */
+ outbuf[9] = 0x00;
+ fwrite(outbuf, 10, 1, gif_file);
+
+ /* prepare state array */
+ State.pIn = (unsigned char *) pixelbuf;
+ State.InLen = symbol->bitmap_height * symbol->bitmap_width;
+ State.pOut = (unsigned char *) lzwoutbuf;
+ State.OutLength = lzoutbufSize;
+
+ /* call lzw encoding */
+ byte_out = gif_lzw(&State, paletteBitSize);
+ if (byte_out <= 0) {
+ fclose(gif_file);
+ return ZINT_ERROR_MEMORY;
+ }
+ fwrite(lzwoutbuf, byte_out, 1, gif_file);
+
+ /* GIF terminator */
+ fputc('\x3b', gif_file);
+ fclose(gif_file);
+
+ return 0;
+}
diff --git a/backend/gridmtx.c b/backend/gridmtx.c
new file mode 100644
index 0000000..627057d
--- /dev/null
+++ b/backend/gridmtx.c
@@ -0,0 +1,1123 @@
+/* gridmtx.c - Grid Matrix
+
+ libzint - the open source barcode library
+ Copyright (C) 2009-2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/* This file implements Grid Matrix as specified in
+ AIM Global Document Number AIMD014 Rev. 1.63 Revised 9 Dec 2008 */
+
+#include <stdio.h>
+#include <string.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+#include "common.h"
+#include "reedsol.h"
+#include "gridmtx.h"
+#include "gb2312.h"
+
+/* define_mode() stuff */
+
+/* Bits multiplied by this for costs, so as to be whole integer divisible by 2 and 3 */
+#define GM_MULT 6
+
+static const char numeral_nondigits[] = " +-.,"; /* Non-digit numeral set, excluding EOL (carriage return/linefeed) */
+
+/* Whether in numeral or not. If in numeral, *p_numeral_end is set to position after numeral, and *p_numeral_cost is set to per-numeral cost */
+static int in_numeral(const unsigned int gbdata[], const size_t length, const unsigned int posn, unsigned int* p_numeral_end, unsigned int* p_numeral_cost) {
+ unsigned int i, digit_cnt, nondigit, nondigit_posn;
+
+ if (posn < *p_numeral_end) {
+ return 1;
+ }
+
+ /* Attempt to calculate the average 'cost' of using numeric mode in number of bits (times GM_MULT) */
+ /* 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) */
+ for (i = posn, digit_cnt = 0, nondigit = 0, nondigit_posn = 0; i < length && i < posn + 4 && digit_cnt < 3; i++) {
+ if (gbdata[i] >= '0' && gbdata[i] <= '9') {
+ digit_cnt++;
+ } else if (strchr(numeral_nondigits, gbdata[i])) {
+ if (nondigit) {
+ break;
+ }
+ nondigit = 1;
+ nondigit_posn = i;
+ } else if (i < length - 1 && gbdata[i] == 13 && gbdata[i + 1] == 10) {
+ if (nondigit) {
+ break;
+ }
+ i++;
+ nondigit = 2;
+ nondigit_posn = i;
+ } else {
+ break;
+ }
+ }
+ if (digit_cnt == 0) { /* Must have at least one digit */
+ *p_numeral_end = 0;
+ return 0;
+ }
+ if (nondigit && nondigit_posn == i - 1) { /* Non-digit can't be at end */
+ nondigit = 0;
+ }
+ *p_numeral_end = posn + digit_cnt + nondigit;
+ /* Calculate per-numeral cost where 120 == (10 + 10) * GM_MULT, 60 == 10 * GM_MULT */
+ if (digit_cnt == 3) {
+ *p_numeral_cost = nondigit == 2 ? 24 /* (120 / 5) */ : nondigit == 1 ? 30 /* (120 / 4) */ : 20 /* (60 / 3) */;
+ } else if (digit_cnt == 2) {
+ *p_numeral_cost = nondigit == 2 ? 30 /* (120 / 4) */ : nondigit == 1 ? 40 /* (120 / 3) */ : 30 /* (60 / 2) */;
+ } else {
+ *p_numeral_cost = nondigit == 2 ? 40 /* (120 / 3) */ : nondigit == 1 ? 60 /* (120 / 2) */ : 60 /* (60 / 1) */;
+ }
+ return 1;
+}
+
+/* Encoding modes */
+#define GM_CHINESE 'H'
+#define GM_NUMBER 'N'
+#define GM_LOWER 'L'
+#define GM_UPPER 'U'
+#define GM_MIXED 'M'
+#define GM_BYTE 'B'
+/* Note Control is a submode of Lower, Upper and Mixed modes */
+
+/* Indexes into mode_types array */
+#define GM_H 0 /* Chinese (Hanzi) */
+#define GM_N 1 /* Numeral */
+#define GM_L 2 /* Lower case */
+#define GM_U 3 /* Upper case */
+#define GM_M 4 /* Mixed */
+#define GM_B 5 /* Byte */
+
+#define GM_NUM_MODES 6
+
+/* Initial mode costs */
+static unsigned int head_costs[GM_NUM_MODES] = {
+/* H N (+pad prefix) L U M B (+byte count) */
+ 4 * GM_MULT, (4 + 2) * GM_MULT, 4 * GM_MULT, 4 * GM_MULT, 4 * GM_MULT, (4 + 9) * GM_MULT
+};
+
+static unsigned int* gm_head_costs(unsigned int state[]) {
+ (void)state; /* Unused */
+ return head_costs;
+}
+
+/* Cost of switching modes from k to j - see AIMD014 Rev. 1.63 Table 9 – Type conversion codes */
+static unsigned int gm_switch_cost(unsigned int state[], const int k, const int j) {
+ static const unsigned int switch_costs[GM_NUM_MODES][GM_NUM_MODES] = {
+ /* H N L U M B */
+ /*H*/ { 0, (13 + 2) * GM_MULT, 13 * GM_MULT, 13 * GM_MULT, 13 * GM_MULT, (13 + 9) * GM_MULT },
+ /*N*/ { 10 * GM_MULT, 0, 10 * GM_MULT, 10 * GM_MULT, 10 * GM_MULT, (10 + 9) * GM_MULT },
+ /*L*/ { 5 * GM_MULT, (5 + 2) * GM_MULT, 0, 5 * GM_MULT, 7 * GM_MULT, (7 + 9) * GM_MULT },
+ /*U*/ { 5 * GM_MULT, (5 + 2) * GM_MULT, 5 * GM_MULT, 0, 7 * GM_MULT, (7 + 9) * GM_MULT },
+ /*M*/ { 10 * GM_MULT, (10 + 2) * GM_MULT, 10 * GM_MULT, 10 * GM_MULT, 0, (10 + 9) * GM_MULT },
+ /*B*/ { 4 * GM_MULT, (4 + 2) * GM_MULT, 4 * GM_MULT, 4 * GM_MULT, 4 * GM_MULT, 0 },
+ };
+
+ (void)state; /* Unused */
+ return switch_costs[k][j];
+}
+
+/* Final end-of-data cost - see AIMD014 Rev. 1.63 Table 9 – Type conversion codes */
+static unsigned int gm_eod_cost(unsigned int state[], const int k) {
+ static const unsigned int eod_costs[GM_NUM_MODES] = {
+ /* H N L U M B */
+ 13 * GM_MULT, 10 * GM_MULT, 5 * GM_MULT, 5 * GM_MULT, 10 * GM_MULT, 4 * GM_MULT
+ };
+
+ (void)state; /* Unused */
+ return eod_costs[k];
+}
+
+/* Calculate cost of encoding current character */
+static void gm_cur_cost(unsigned int state[], const unsigned int gbdata[], const size_t length, const int i, char* char_modes, unsigned int prev_costs[], unsigned int cur_costs[]) {
+ int cm_i = i * GM_NUM_MODES;
+ int double_byte, space, numeric, lower, upper, control, double_digit, eol;
+ unsigned int* p_numeral_end = &state[0];
+ unsigned int* p_numeral_cost = &state[1];
+ unsigned int* p_byte_count = &state[2];
+
+ double_byte = gbdata[i] > 0xFF;
+ space = gbdata[i] == ' ';
+ numeric = gbdata[i] >= '0' && gbdata[i] <= '9';
+ lower = gbdata[i] >= 'a' && gbdata[i] <= 'z';
+ upper = gbdata[i] >= 'A' && gbdata[i] <= 'Z';
+ control = !space && !numeric && !lower && !upper && gbdata[i] < 0x7F; /* Exclude DEL */
+ double_digit = i < (int) length - 1 && numeric && gbdata[i + 1] >= '0' && gbdata[i + 1] <= '9';
+ eol = i < (int) length - 1 && gbdata[i] == 13 && gbdata[i + 1] == 10;
+
+ /* Hanzi mode can encode anything */
+ cur_costs[GM_H] = prev_costs[GM_H] + (double_digit || eol ? 39 : 78); /* (6.5 : 13) * GM_MULT */
+ char_modes[cm_i + GM_H] = GM_CHINESE;
+
+ /* Byte mode can encode anything */
+ if (*p_byte_count == 512 || (double_byte && *p_byte_count == 511)) {
+ cur_costs[GM_B] = head_costs[GM_B];
+ if (double_byte && *p_byte_count == 511) {
+ cur_costs[GM_B] += 48; /* 8 * GM_MULT */
+ double_byte = 0; /* Splitting double-byte so mark as single */
+ }
+ *p_byte_count = 0;
+ }
+ cur_costs[GM_B] += prev_costs[GM_B] + (double_byte ? 96 : 48); /* (16 : 8) * GM_MULT */
+ char_modes[cm_i + GM_B] = GM_BYTE;
+ *p_byte_count += double_byte ? 2 : 1;
+
+ if (in_numeral(gbdata, length, i, p_numeral_end, p_numeral_cost)) {
+ cur_costs[GM_N] = prev_costs[GM_N] + *p_numeral_cost;
+ char_modes[cm_i + GM_N] = GM_NUMBER;
+ }
+
+ if (control) {
+ cur_costs[GM_L] = prev_costs[GM_L] + 78; /* (7 + 6) * GM_MULT */
+ char_modes[cm_i + GM_L] = GM_LOWER;
+ cur_costs[GM_U] = prev_costs[GM_U] + 78; /* (7 + 6) * GM_MULT */
+ char_modes[cm_i + GM_U] = GM_UPPER;
+ cur_costs[GM_M] = prev_costs[GM_M] + 96; /* (10 + 6) * GM_MULT */
+ char_modes[cm_i + GM_M] = GM_MIXED;
+ } else {
+ if (lower || space) {
+ cur_costs[GM_L] = prev_costs[GM_L] + 30; /* 5 * GM_MULT */
+ char_modes[cm_i + GM_L] = GM_LOWER;
+ }
+ if (upper || space) {
+ cur_costs[GM_U] = prev_costs[GM_U] + 30; /* 5 * GM_MULT */
+ char_modes[cm_i + GM_U] = GM_UPPER;
+ }
+ if (numeric || lower || upper || space) {
+ cur_costs[GM_M] = prev_costs[GM_M] + 36; /* 6 * GM_MULT */
+ char_modes[cm_i + GM_M] = GM_MIXED;
+ }
+ }
+}
+
+/* Calculate optimized encoding modes */
+static void define_mode(char* mode, const unsigned int gbdata[], const size_t length, const int debug) {
+ static const char mode_types[] = { GM_CHINESE, GM_NUMBER, GM_LOWER, GM_UPPER, GM_MIXED, GM_BYTE }; /* Must be in same order as GM_H etc */
+ unsigned int state[3] = { 0 /*numeral_end*/, 0 /*numeral_cost*/, 0 /*byte_count*/ };
+
+ pn_define_mode(mode, gbdata, length, debug, state, mode_types, GM_NUM_MODES, gm_head_costs, gm_switch_cost, gm_eod_cost, gm_cur_cost);
+}
+
+/* Add the length indicator for byte encoded blocks */
+static void add_byte_count(char binary[], const size_t byte_count_posn, const int byte_count) {
+ /* AIMD014 6.3.7: "Let L be the number of bytes of input data to be encoded in the 8-bit binary data set.
+ * First output (L-1) as a 9-bit binary prefix to record the number of bytes..." */
+ bin_append_posn(byte_count - 1, 9, binary, byte_count_posn);
+}
+
+/* Add a control character to the data stream */
+static void add_shift_char(char binary[], int shifty, int debug) {
+ int i;
+ int glyph = 0;
+
+ for (i = 0; i < 64; i++) {
+ if (shift_set[i] == shifty) {
+ glyph = i;
+ break;
+ }
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("SHIFT [%d] ", glyph);
+ }
+
+ bin_append(glyph, 6, binary);
+}
+
+static int gm_encode(unsigned int gbdata[], const size_t length, char binary[], const int reader, const int eci, int debug) {
+ /* 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 */
+ unsigned int sp;
+ int current_mode, last_mode;
+ unsigned int glyph = 0;
+ int c1, c2, done;
+ int p = 0, ppos;
+ int numbuf[3], punt = 0;
+ size_t number_pad_posn, byte_count_posn = 0;
+ int byte_count = 0;
+ int shift;
+#ifndef _MSC_VER
+ char mode[length];
+#else
+ char* mode = (char*) _alloca(length);
+#endif
+
+ strcpy(binary, "");
+
+ sp = 0;
+ current_mode = 0;
+ last_mode = 0;
+ number_pad_posn = 0;
+
+ if (reader) {
+ bin_append(10, 4, binary); /* FNC3 - Reader Initialisation */
+ }
+
+ if (eci != 0) {
+ /* ECI assignment according to Table 8 */
+ bin_append(12, 4, binary); /* ECI */
+ if (eci <= 1023) {
+ bin_append(eci, 11, binary);
+ }
+ if ((eci >= 1024) && (eci <= 32767)) {
+ strcat(binary, "10");
+ bin_append(eci, 15, binary);
+ }
+ if (eci >= 32768) {
+ strcat(binary, "11");
+ bin_append(eci, 20, binary);
+ }
+ }
+
+ define_mode(mode, gbdata, length, debug);
+
+ do {
+ int next_mode = mode[sp];
+
+ if (next_mode != current_mode) {
+ switch (current_mode) {
+ case 0:
+ switch (next_mode) {
+ case GM_CHINESE: bin_append(1, 4, binary);
+ break;
+ case GM_NUMBER: bin_append(2, 4, binary);
+ break;
+ case GM_LOWER: bin_append(3, 4, binary);
+ break;
+ case GM_UPPER: bin_append(4, 4, binary);
+ break;
+ case GM_MIXED: bin_append(5, 4, binary);
+ break;
+ case GM_BYTE: bin_append(6, 4, binary);
+ break;
+ }
+ break;
+ case GM_CHINESE:
+ switch (next_mode) {
+ case GM_NUMBER: bin_append(8161, 13, binary);
+ break;
+ case GM_LOWER: bin_append(8162, 13, binary);
+ break;
+ case GM_UPPER: bin_append(8163, 13, binary);
+ break;
+ case GM_MIXED: bin_append(8164, 13, binary);
+ break;
+ case GM_BYTE: bin_append(8165, 13, binary);
+ break;
+ }
+ 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 digits
+ case 3: binary[number_pad_posn] = '0';
+ binary[number_pad_posn + 1] = '0';
+ break; // 0 pad digits
+ }
+ switch (next_mode) {
+ case GM_CHINESE: bin_append(1019, 10, binary);
+ break;
+ case GM_LOWER: bin_append(1020, 10, binary);
+ break;
+ case GM_UPPER: bin_append(1021, 10, binary);
+ break;
+ case GM_MIXED: bin_append(1022, 10, binary);
+ break;
+ case GM_BYTE: bin_append(1023, 10, binary);
+ break;
+ }
+ break;
+ case GM_LOWER:
+ case GM_UPPER:
+ switch (next_mode) {
+ case GM_CHINESE: bin_append(28, 5, binary);
+ break;
+ case GM_NUMBER: bin_append(29, 5, binary);
+ break;
+ case GM_LOWER:
+ case GM_UPPER: bin_append(30, 5, binary);
+ break;
+ case GM_MIXED: bin_append(124, 7, binary);
+ break;
+ case GM_BYTE: bin_append(126, 7, binary);
+ break;
+ }
+ break;
+ case GM_MIXED:
+ switch (next_mode) {
+ case GM_CHINESE: bin_append(1009, 10, binary);
+ break;
+ case GM_NUMBER: bin_append(1010, 10, binary);
+ break;
+ case GM_LOWER: bin_append(1011, 10, binary);
+ break;
+ case GM_UPPER: bin_append(1012, 10, binary);
+ break;
+ case GM_BYTE: bin_append(1015, 10, binary);
+ break;
+ }
+ 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: bin_append(1, 4, binary);
+ break;
+ case GM_NUMBER: bin_append(2, 4, binary);
+ break;
+ case GM_LOWER: bin_append(3, 4, binary);
+ break;
+ case GM_UPPER: bin_append(4, 4, binary);
+ break;
+ case GM_MIXED: bin_append(5, 4, binary);
+ break;
+ }
+ break;
+ }
+ if (debug & ZINT_DEBUG_PRINT) {
+ 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 >= 0xa1) && (c1 <= 0xa9)) {
+ glyph = (0x60 * (c1 - 0xa1)) + (c2 - 0xa0);
+ } else if ((c1 >= 0xb0) && (c1 <= 0xf7)) {
+ glyph = (0x60 * (c1 - 0xb0 + 9)) + (c2 - 0xa0);
+ }
+ done = 1; /* GB 2312 always within above ranges */
+ }
+ if (!(done)) {
+ if (sp != (length - 1)) {
+ if ((gbdata[sp] == 13) && (gbdata[sp + 1] == 10)) {
+ /* 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++;
+ done = 1;
+ }
+ }
+ }
+ if (!(done)) {
+ /* Byte value */
+ glyph = 7777 + gbdata[sp];
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("[%d] ", glyph);
+ }
+
+ bin_append(glyph, 13, binary);
+ 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);
+ strcat(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];
+ p++;
+ } else if (strchr(numeral_nondigits, gbdata[sp])) {
+ if (ppos != -1) {
+ break;
+ }
+ punt = gbdata[sp];
+ ppos = p;
+ } else if (sp < (length - 1) && (gbdata[sp] == 13) && (gbdata[sp + 1] == 10)) {
+ /* <end of line> */
+ if (ppos != -1) {
+ break;
+ }
+ punt = gbdata[sp];
+ sp++;
+ ppos = p;
+ } else {
+ break;
+ }
+ sp++;
+ } while ((p < 3) && (sp < length) && mode[sp] == GM_NUMBER);
+
+ if (ppos != -1) {
+ switch (punt) {
+ case ' ': glyph = 0;
+ break;
+ case '+': glyph = 3;
+ break;
+ case '-': glyph = 6;
+ break;
+ case '.': glyph = 9;
+ break;
+ case ',': glyph = 12;
+ break;
+ case 13: glyph = 15;
+ break;
+ }
+ glyph += ppos;
+ glyph += 1000;
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("[%d] ", glyph);
+ }
+
+ bin_append(glyph, 10, binary);
+ }
+
+ glyph = (100 * (numbuf[0] - '0')) + (10 * (numbuf[1] - '0')) + (numbuf[2] - '0');
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("[%d] ", glyph);
+ }
+
+ bin_append(glyph, 10, binary);
+ break;
+
+ case GM_BYTE:
+ if (last_mode != current_mode) {
+ /* Reserve space for byte block length indicator (9 bits) */
+ byte_count_posn = strlen(binary);
+ strcat(binary, "LLLLLLLLL");
+ }
+ glyph = gbdata[sp];
+ if (byte_count == 512 || (glyph > 0xFF && byte_count == 511)) {
+ /* Maximum byte block size is 512 bytes. If longer is needed then start a new block */
+ if (glyph > 0xFF && byte_count == 511) { /* Split double-byte */
+ bin_append(glyph >> 8, 8, binary);
+ glyph &= 0xFF;
+ byte_count++;
+ }
+ add_byte_count(binary, byte_count_posn, byte_count);
+ bin_append(7, 4, binary);
+ byte_count_posn = strlen(binary);
+ strcat(binary, "LLLLLLLLL");
+ byte_count = 0;
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("[%d] ", glyph);
+ }
+ bin_append(glyph, glyph > 0xFF ? 16 : 8, binary);
+ sp++;
+ byte_count++;
+ if (glyph > 0xFF) {
+ 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 & ZINT_DEBUG_PRINT) {
+ printf("[%d] ", glyph);
+ }
+
+ bin_append(glyph, 6, binary);
+ } else {
+ /* Shift Mode character */
+ bin_append(1014, 10, binary); /* shift indicator */
+ add_shift_char(binary, gbdata[sp], debug);
+ }
+
+ 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 & ZINT_DEBUG_PRINT) {
+ printf("[%d] ", glyph);
+ }
+
+ bin_append(glyph, 5, binary);
+ } else {
+ /* Shift Mode character */
+ bin_append(125, 7, binary); /* shift indicator */
+ add_shift_char(binary, gbdata[sp], debug);
+ }
+
+ 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 & ZINT_DEBUG_PRINT) {
+ printf("[%d] ", glyph);
+ }
+
+ bin_append(glyph, 5, binary);
+ } else {
+ /* Shift Mode character */
+ bin_append(125, 7, binary); /* shift indicator */
+ add_shift_char(binary, gbdata[sp], debug);
+ }
+
+ sp++;
+ break;
+ }
+ if (strlen(binary) > 9191) {
+ return ZINT_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: bin_append(8160, 13, binary);
+ break;
+ case GM_NUMBER: bin_append(1018, 10, binary);
+ break;
+ case GM_LOWER:
+ case GM_UPPER: bin_append(27, 5, binary);
+ break;
+ case GM_MIXED: bin_append(1008, 10, binary);
+ break;
+ case GM_BYTE: bin_append(0, 4, binary);
+ break;
+ }
+
+ /* Add padding bits if required */
+ p = 7 - (strlen(binary) % 7);
+ if (p % 7) {
+ bin_append(0, p, binary);
+ }
+
+ if (strlen(binary) > 9191) {
+ return ZINT_ERROR_TOO_LONG;
+ }
+ return 0;
+}
+
+static void gm_add_ecc(const char binary[], const size_t data_posn, const int layers, const int ecc_level, unsigned char word[]) {
+ int data_cw, i, j, wp, p;
+ int n1, b1, n2, b2, e1, b3, e2;
+ int block_size, ecc_size;
+ unsigned char data[1320], block[130];
+ unsigned char data_block[115], ecc_block[70];
+
+ data_cw = gm_data_codewords[((layers - 1) * 5) + (ecc_level - 1)];
+
+ for (i = 0; i < 1320; i++) {
+ data[i] = 0;
+ }
+
+ /* Convert from binary stream to 7-bit codewords */
+ for (i = 0; i < (int) data_posn; i++) {
+ for (p = 0; p < 7; p++) {
+ if (binary[i * 7 + p] == '1') {
+ data[i] += (0x40 >> p);
+ }
+ }
+ }
+
+ /* Add padding codewords */
+ data[data_posn] = 0x00;
+ for (i = (int) (data_posn + 1); i < data_cw; i++) {
+ if (i & 1) {
+ data[i] = 0x7e;
+ } else {
+ data[i] = 0x00;
+ }
+ }
+
+ /* 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++) {
+ int data_size;
+ 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)];
+ }
+ }
+}
+
+static 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';
+ }
+}
+
+static void place_data_in_grid(unsigned char 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);
+ }
+ }
+}
+
+/* Place the layer ID into each macromodule */
+static void place_layer_id(char* grid, int size, int layers, int modules, int ecc_level) {
+ 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';
+ }
+ }
+ }
+}
+
+INTERNAL int grid_matrix(struct zint_symbol *symbol, const unsigned char source[], size_t length) {
+ int size, modules, error_number;
+ int auto_layers, min_layers, layers, auto_ecc_level, min_ecc_level, ecc_level;
+ int x, y, i;
+ int full_multibyte;
+ char binary[9300];
+ int data_cw, input_latch = 0;
+ unsigned char word[1460];
+ int data_max, reader = 0;
+
+#ifndef _MSC_VER
+ unsigned int gbdata[length + 1];
+#else
+ char* grid;
+ unsigned int* gbdata = (unsigned int *) _alloca((length + 1) * sizeof (unsigned int));
+#endif
+
+ for (i = 0; i < 1460; i++) {
+ word[i] = 0;
+ }
+
+ full_multibyte = symbol->option_3 == ZINT_FULL_MULTIBYTE; /* If set use Hanzi mode in DATA_MODE or for single-byte Latin */
+
+ if ((symbol->input_mode & 0x07) == DATA_MODE) {
+ gb2312_cpy(source, &length, gbdata, full_multibyte);
+ } else {
+ int done = 0;
+ if (symbol->eci != 29) { /* Unless ECI 29 (GB) */
+ /* Try single byte (Latin) conversion first */
+ int error_number = gb2312_utf8tosb(symbol->eci && symbol->eci <= 899 ? symbol->eci : 3, source, &length, gbdata, full_multibyte);
+ if (error_number == 0) {
+ done = 1;
+ } else if (symbol->eci && symbol->eci <= 899) {
+ strcpy(symbol->errtxt, "575: Invalid characters in input data");
+ return error_number;
+ }
+ }
+ if (!done) {
+ /* Try GB 2312 (EUC-CN) */
+ int error_number = gb2312_utf8tomb(symbol, source, &length, gbdata);
+ if (error_number != 0) {
+ return error_number;
+ }
+ }
+ }
+
+ if (symbol->output_options & READER_INIT) reader = 1;
+
+ if (symbol->eci > 811799) {
+ strcpy(symbol->errtxt, "533: Invalid ECI");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ error_number = gm_encode(gbdata, length, binary, reader, symbol->eci, symbol->debug);
+ if (error_number != 0) {
+ strcpy(symbol->errtxt, "531: Input data too long");
+ return error_number;
+ }
+
+ /* Determine the size of the symbol */
+ data_cw = (int)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;
+
+ if ((symbol->option_2 >= 1) && (symbol->option_2 <= 13)) {
+ input_latch = 1;
+ if (symbol->option_2 >= min_layers) {
+ layers = symbol->option_2;
+ } else {
+ strcpy(symbol->errtxt, "534: Input data too long for selected symbol size");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ }
+
+ 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;
+
+ min_ecc_level = 1;
+ if (layers == 1) {
+ min_ecc_level = 4;
+ }
+ if (layers == 2) {
+ min_ecc_level = 2;
+ }
+
+ 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)]) {
+ if (input_latch && ecc_level > min_ecc_level) { /* If layers user-specified (option_2), try reducing ECC level first */
+ do {
+ ecc_level--;
+ } while ((data_cw > gm_data_codewords[(5 * (layers - 1)) + (ecc_level - 1)]) && (ecc_level > min_ecc_level));
+ }
+ while (data_cw > gm_data_codewords[(5 * (layers - 1)) + (ecc_level - 1)] && (layers < 13)) {
+ layers++;
+ }
+ while (data_cw > gm_data_codewords[(5 * (layers - 1)) + (ecc_level - 1)] && ecc_level > 1) { /* ECC min level 1 for layers > 2 */
+ ecc_level--;
+ }
+ }
+
+ 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, "532: Input data too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ gm_add_ecc(binary, data_cw, layers, ecc_level, word);
+#ifdef ZINT_TEST
+ if (symbol->debug & ZINT_DEBUG_TEST) debug_test_codeword_dump(symbol, word, data_cw);
+#endif
+ size = 6 + (layers * 12);
+ modules = 1 + (layers * 2);
+
+#ifndef _MSC_VER
+ char grid[size * size];
+#else
+ 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++) {
+ int dark = 1 - (x & 1);
+ 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 0000000..f0d58c8
--- /dev/null
+++ b/backend/gridmtx.h
@@ -0,0 +1,178 @@
+/* gridmtx.h - definitions for Grid Matrix
+
+ libzint - the open source barcode library
+ Copyright (C) 2009-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#define EUROPIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz "
+
+static const 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 const unsigned short int gm_recommend_cw[] = {
+ 9, 30, 59, 114, 170, 237, 315, 405, 506, 618, 741, 875, 1021
+};
+
+static const unsigned short int gm_max_cw[] = {
+ 11, 40, 79, 146, 218, 305, 405, 521, 650, 794, 953, 1125, 1313
+};
+
+static const unsigned short 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 const char gm_n1[] = {
+ 18, 50, 98, 81, 121, 113, 113, 116, 121, 126, 118, 125, 122
+};
+
+static const char gm_b1[] = {
+ 1, 1, 1, 2, 2, 2, 2, 3, 2, 7, 5, 10, 6
+};
+
+static const char gm_b2[] = {
+ 0, 0, 0, 0, 0, 1, 2, 2, 4, 0, 4, 0, 6
+};
+
+/* Values from table A.1 */
+static const char 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, 40, 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 const unsigned short 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
index dbad2ca..39791f8 100644
--- a/backend/gs1.c
+++ b/backend/gs1.c
@@ -2,7 +2,7 @@
/*
libzint - the open source barcode library
- Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -28,13 +28,13 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
#include <string.h>
-#include <stdlib.h>
#include <stdio.h>
#ifdef _MSC_VER
-#include <malloc.h>
+#include <malloc.h>
#endif
#include "common.h"
#include "gs1.h"
@@ -43,280 +43,658 @@
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, ")");
-}
+static void itostr(char ai_string[], int ai_value) {
+ int thou, hund, ten, unit;
+ char temp[2];
-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:
- case 2:
- case 3: if(data_length[i] != 14) { error_latch = 1; } break;
- case 4: if(data_length[i] != 16) { error_latch = 1; } break;
- case 11:
- case 12:
- case 13:
- case 14:
- case 15:
- case 16:
- case 17:
- case 18:
- case 19: if(data_length[i] != 6) { error_latch = 1; } break;
- case 20: if(data_length[i] != 2) { error_latch = 1; } break;
- case 23:
- case 24:
- case 25:
- case 39:
- case 40:
- case 41:
- case 42:
- case 70:
- case 80:
- case 81: error_latch = 2; break;
- }
- if(
- ((ai_value[i] >= 100) && (ai_value[i] <= 179))
- || ((ai_value[i] >= 1000) && (ai_value[i] <= 1799))
- || ((ai_value[i] >= 200) && (ai_value[i] <= 229))
- || ((ai_value[i] >= 2000) && (ai_value[i] <= 2299))
- || ((ai_value[i] >= 300) && (ai_value[i] <= 309))
- || ((ai_value[i] >= 3000) && (ai_value[i] <= 3099))
- || ((ai_value[i] >= 31) && (ai_value[i] <= 36))
- || ((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))
- || ((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))
- || ((ai_value[i] >= 700) && (ai_value[i] <= 703))
- || ((ai_value[i] >= 800) && (ai_value[i] <= 810))
- || ((ai_value[i] >= 900) && (ai_value[i] <= 999))
- || ((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;
- }
+ 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));
- /* 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))
- || ((last_ai >= 11) && (last_ai <= 20))
- || (last_ai == 23) /* legacy support - see 5.3.8.2.2 */
- || ((last_ai >= 31) && (last_ai <= 36))
- || (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;
+ temp[1] = '\0';
+ if (ai_value >= 1000) {
+ temp[0] = itoc(thou);
+ strcat(ai_string, temp);
+ }
+ if (ai_value >= 100) {
+ temp[0] = itoc(hund);
+ strcat(ai_string, temp);
+ }
+ temp[0] = itoc(ten);
+ strcat(ai_string, temp);
+ temp[0] = itoc(unit);
+ strcat(ai_string, temp);
+ strcat(ai_string, ")");
}
-int ugs1_verify(struct zint_symbol *symbol, unsigned char source[], const unsigned int src_len, unsigned char reduced[])
-{
- /* Only to keep the compiler happy */
+INTERNAL int gs1_verify(struct zint_symbol *symbol, const unsigned char source[], const size_t src_len, char reduced[]) {
+ int i, j, last_ai, ai_latch;
+ char ai_string[7]; /* 6 char max "(NNNN)" */
+ int bracket_level, max_bracket_level, ai_length, max_ai_length, min_ai_length;
+ int ai_count;
+ int error_latch;
+#ifdef _MSC_VER
+ int *ai_value;
+ int *ai_location;
+ int *data_location;
+ int *data_length;
+#endif
+ int ai_max = ustrchr_cnt(source, src_len, '[') + 1; /* Plus 1 so non-zero */
#ifndef _MSC_VER
- char temp[src_len + 5];
+ int ai_value[ai_max], ai_location[ai_max], data_location[ai_max], data_length[ai_max];
#else
- char* temp = (char*)_alloca(src_len + 5);
+ ai_value = (int*) _alloca(ai_max * sizeof(int));
+ ai_location = (int*) _alloca(ai_max * sizeof(int));
+ data_location = (int*) _alloca(ai_max * sizeof(int));
+ data_length = (int*) _alloca(ai_max * sizeof(int));
#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;
+
+ /* Detect extended ASCII characters */
+ for (i = 0; i < (int) src_len; i++) {
+ if (source[i] >= 128) {
+ strcpy(symbol->errtxt, "250: Extended ASCII characters are not supported by GS1");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ if (source[i] == '\0') {
+ strcpy(symbol->errtxt, "262: NUL characters not permitted in GS1 mode");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ if (source[i] < 32) {
+ strcpy(symbol->errtxt, "251: Control characters are not supported by GS1");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ if (source[i] == 127) {
+ strcpy(symbol->errtxt, "263: DEL characters are not supported by GS1");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ }
+
+ if (source[0] != '[') {
+ strcpy(symbol->errtxt, "252: Data does not start with an AI");
+ return ZINT_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 < (int) 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, "253: Malformed AI in input data (brackets don\'t match)");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ if (max_bracket_level > 1) {
+ /* Nested brackets */
+ strcpy(symbol->errtxt, "254: Found nested brackets in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ if (max_ai_length > 4) {
+ /* AI is too long */
+ strcpy(symbol->errtxt, "255: Invalid AI in input data (AI too long)");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ if (min_ai_length <= 1) {
+ /* AI is too short */
+ strcpy(symbol->errtxt, "256: Invalid AI in input data (AI too short)");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ if (ai_latch == 1) {
+ /* Non-numeric data in AI */
+ strcpy(symbol->errtxt, "257: Invalid AI in input data (non-numeric characters in AI)");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ ai_count = 0;
+ for (i = 1; i < (int) 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] != '[') && (data_location[i] + data_length[i] <= (int) src_len));
+ data_length[i]--;
+ }
+
+ for (i = 0; i < ai_count; i++) {
+ if (data_length[i] == 0) {
+ /* No data for given AI */
+ strcpy(symbol->errtxt, "258: Empty data field in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ }
+
+ strcpy(ai_string, "");
+
+ // Check for valid AI values and data lengths according to GS1 General
+ // Specification Release 19, January 2019
+ for (i = 0; i < ai_count; i++) {
+
+ error_latch = 2;
+ switch (ai_value[i]) {
+ // Length 2 Fixed
+ case 20: // VARIANT
+ if (data_length[i] != 2) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 3 Fixed
+ case 422: // ORIGIN
+ case 424: // COUNTRY PROCESS
+ case 426: // COUNTRY FULL PROCESS
+ if (data_length[i] != 3) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 4 Fixed
+ case 7040: // UIC+EXT
+ case 8111: // POINTS
+ if (data_length[i] != 4) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 6 Fixed
+ case 11: // PROD DATE
+ case 12: // DUE DATE
+ case 13: // PACK DATE
+ case 15: // BEST BY
+ case 16: // SELL BY
+ case 17: // USE BY
+ case 7006: // FIRST FREEZE DATE
+ case 8005: // PRICE PER UNIT
+ if (data_length[i] != 6) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 10 Fixed
+ case 7003: // EXPIRY TIME
+ if (data_length[i] != 10) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 13 Fixed
+ case 410: // SHIP TO LOC
+ case 411: // BILL TO
+ case 412: // PURCHASE FROM
+ case 413: // SHIP FOR LOC
+ case 414: // LOC NO
+ case 415: // PAY TO
+ case 416: // PROD/SERV LOC
+ case 417: // PARTY GLN
+ case 7001: // NSN
+ if (data_length[i] != 13) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 14 Fixed
+ case 1: // GTIN
+ case 2: // CONTENT
+ case 8001: // DIMENSIONS
+ if (data_length[i] != 14) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 17 Fixed
+ case 402: // GSIN
+ if (data_length[i] != 17) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 18 Fixed
+ case 0: // SSCC
+ case 8006: // ITIP
+ case 8017: // GSRN PROVIDER
+ case 8018: // GSRN RECIPIENT
+ case 8026: // ITIP CONTENT
+ if (data_length[i] != 18) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 2 Max
+ case 7010: // PROD METHOD
+ if (data_length[i] > 2) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 3 Max
+ case 427: // ORIGIN SUBDIVISION
+ case 7008: // AQUATIC SPECIES
+ if (data_length[i] > 3) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 4 Max
+ case 7004: // ACTIVE POTENCY
+ if (data_length[i] > 4) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 6 Max
+ case 242: // MTO VARIANT
+ if (data_length[i] > 6) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 8 Max
+ case 30: // VAR COUNT
+ case 37: // COUNT
+ if (data_length[i] > 8) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 10 Max
+ case 7009: // FISHING GEAR TYPE
+ case 8019: // SRIN
+ if (data_length[i] > 10) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 12 Max
+ case 7005: // CATCH AREA
+ case 8011: // CPID SERIAL
+ if (data_length[i] > 12) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 20 Max
+ case 10: // BATCH/LOT
+ case 21: // SERIAL
+ case 22: // CPV
+ case 243: // PCN
+ case 254: // GLN EXTENSION COMPONENT
+ case 420: // SHIP TO POST
+ case 7020: // REFURB LOT
+ case 7021: // FUNC STAT
+ case 7022: // REV STAT
+ case 710: // NHRN PZN
+ case 711: // NHRN CIP
+ case 712: // NHRN CN
+ case 713: // NHRN DRN
+ case 714: // NHRN AIM
+ case 7240: // PROTOCOL
+ case 8002: // CMT NO
+ case 8012: // VERSION
+ if (data_length[i] > 20) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 25 Max
+ case 8020: // REF NO
+ if (data_length[i] > 25) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 28 Max
+ case 235: // TPX
+ if (data_length[i] > 28) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 30 Max
+ case 240: // ADDITIONAL ID
+ case 241: // CUST PART NO
+ case 250: // SECONDARY SERIAL
+ case 251: // REF TO SOURCE
+ case 400: // ORDER NUMBER
+ case 401: // GINC
+ case 403: // ROUTE
+ case 7002: // MEAT CUT
+ case 7023: // GIAI ASSEMBLY
+ case 8004: // GIAI
+ case 8010: // CPID
+ case 8013: // BUDI-DI
+ case 90: // INTERNAL
+ if (data_length[i] > 30) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 34 Max
+ case 8007: // IBAN
+ if (data_length[i] > 34) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 50 Max
+ case 8009: // OPTSEN
+ if (data_length[i] > 50) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ // Length 70 Max
+ case 8110: // Coupon code
+ case 8112: // Paperless coupon code
+ case 8200: // PRODUCT URL
+ if (data_length[i] > 70) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ break;
+
+ }
+
+ if (ai_value[i] == 253) { // GDTI
+ if ((data_length[i] < 13) || (data_length[i] > 30)) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if (ai_value[i] == 255) { // GCN
+ if ((data_length[i] < 13) || (data_length[i] > 25)) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if ((ai_value[i] >= 3100) && (ai_value[i] <= 3169)) {
+ if (data_length[i] != 6) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if ((ai_value[i] >= 3200) && (ai_value[i] <= 3379)) {
+ if (data_length[i] != 6) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if ((ai_value[i] >= 3400) && (ai_value[i] <= 3579)) {
+ if (data_length[i] != 6) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if ((ai_value[i] >= 3600) && (ai_value[i] <= 3699)) {
+ if (data_length[i] != 6) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if ((ai_value[i] >= 3900) && (ai_value[i] <= 3909)) { // AMOUNT
+ if (data_length[i] > 15) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if ((ai_value[i] >= 3910) && (ai_value[i] <= 3919)) { // AMOUNT
+ if ((data_length[i] < 4) || (data_length[i] > 18)) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if ((ai_value[i] >= 3920) && (ai_value[i] <= 3929)) { // PRICE
+ if (data_length[i] > 15) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if ((ai_value[i] >= 3930) && (ai_value[i] <= 3939)) { // PRICE
+ if ((data_length[i] < 4) || (data_length[i] > 18)) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if ((ai_value[i] >= 3940) && (ai_value[i] <= 3949)) { // PRCNT OFF
+ if (data_length[i] != 4) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if (ai_value[i] == 421) { // SHIP TO POST
+ if ((data_length[i] < 4) || (data_length[i] > 12)) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if ((ai_value[i] == 423) || (ai_value[i] == 425)) {
+ // COUNTRY INITIAL PROCESS || COUNTRY DISASSEMBLY
+ if ((data_length[i] < 4) || (data_length[i] > 15)) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if (ai_value[i] == 7007) { // HARVEST DATE
+ if ((data_length[i] != 6) && (data_length[i] != 12)) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if ((ai_value[i] >= 7030) && (ai_value[i] <= 7039)) { // PROCESSOR #
+ if ((data_length[i] < 4) || (data_length[i] > 30)) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if ((ai_value[i] >= 7230) && (ai_value[i] <= 7239)) { // CERT #
+ if ((data_length[i] < 3) || (data_length[i] > 30)) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if (ai_value[i] == 8003) { // GRAI
+ if ((data_length[i] < 15) || (data_length[i] > 30)) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if (ai_value[i] == 8008) { // PROD TIME
+ if ((data_length[i] != 8) && (data_length[i] != 10) && (data_length[i] != 12)) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if ((ai_value[i] >= 91) && (ai_value[i] <= 99)) { // INTERNAL
+ if (data_length[i] > 90) {
+ error_latch = 1;
+ } else {
+ error_latch = 0;
+ }
+ }
+
+ if (error_latch == 1) {
+ itostr(ai_string, ai_value[i]);
+ strcpy(symbol->errtxt, "259: Invalid data length for AI ");
+ strcat(symbol->errtxt, ai_string);
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ if (error_latch == 2) {
+ itostr(ai_string, ai_value[i]);
+ strcpy(symbol->errtxt, "260: Invalid AI value ");
+ strcat(symbol->errtxt, ai_string);
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ }
+
+ /* Resolve AI data - put resulting string in 'reduced' */
+ j = 0;
+ last_ai = 0;
+ ai_latch = 1;
+ for (i = 0; i < (int) 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))
+ || ((last_ai >= 11) && (last_ai <= 20))
+ || (last_ai == 23) /* legacy support - see 5.3.8.2.2 */
+ || ((last_ai >= 31) && (last_ai <= 36))
+ || (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;
}
diff --git a/backend/gs1.h b/backend/gs1.h
index 8b345a2..228af50 100644
--- a/backend/gs1.h
+++ b/backend/gs1.h
@@ -2,7 +2,7 @@
/*
libzint - the open source barcode library
- Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2009-2017 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -28,7 +28,8 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
#ifndef __GS1_H
#define __GS1_H
@@ -36,11 +37,10 @@
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[]);
+ extern int gs1_verify(struct zint_symbol *symbol, const unsigned char source[], const size_t src_len, char reduced[]);
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#endif /* __GS1_H */ \ No newline at end of file
+#endif /* __GS1_H */
diff --git a/backend/hanxin.c b/backend/hanxin.c
new file mode 100644
index 0000000..15dff6b
--- /dev/null
+++ b/backend/hanxin.c
@@ -0,0 +1,1665 @@
+/* hanxin.c - Han Xin Code
+
+ libzint - the open source barcode library
+ Copyright (C) 2009-2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/* This code attempts to implement Han Xin Code according to ISO/IEC 20830 (draft 2019-10-10) (previously AIMD-015:2010 (Rev 0.8)) */
+
+#include <stdio.h>
+#include <string.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+#include "common.h"
+#include "reedsol.h"
+#include "hanxin.h"
+#include "gb2312.h"
+#include "gb18030.h"
+#include "assert.h"
+
+/* Find which submode to use for a text character */
+static int getsubmode(unsigned int input) {
+ int submode = 2;
+
+ if ((input >= '0') && (input <= '9')) {
+ submode = 1;
+ }
+
+ if ((input >= 'A') && (input <= 'Z')) {
+ submode = 1;
+ }
+
+ if ((input >= 'a') && (input <= 'z')) {
+ submode = 1;
+ }
+
+ return submode;
+}
+
+/* Return length of terminator for encoding mode */
+static int terminator_length(char mode) {
+ int result = 0;
+
+ switch (mode) {
+ case 'n':
+ result = 10;
+ break;
+ case 't':
+ result = 6;
+ break;
+ case '1':
+ case '2':
+ result = 12;
+ break;
+ case 'd':
+ result = 15;
+ break;
+ }
+
+ return result;
+}
+
+/* Calculate the length of the binary string */
+static int calculate_binlength(char mode[], unsigned int source[], const size_t length, int eci) {
+ size_t i;
+ char lastmode = '\0';
+ int est_binlen = 0;
+ int submode = 1;
+ int numeric_run = 0;
+
+ if (eci != 0) {
+ est_binlen += 4;
+ if (eci <= 127) {
+ est_binlen += 8;
+ } else if ((eci >= 128) && (eci <= 16383)) {
+ est_binlen += 16;
+ } else {
+ est_binlen += 24;
+ }
+ }
+
+ i = 0;
+ do {
+ if (mode[i] != lastmode) {
+ if (i > 0) {
+ est_binlen += terminator_length(lastmode);
+ }
+ /* GB 4-byte has indicator for each character (and no terminator) so not included here */
+ /* Region1/Region2 have special terminator to go directly into each other's mode so not included here */
+ if (mode[i] != 'f' || ((mode[i] == '1' && lastmode == '2') || (mode[i] == '2' && lastmode == '1'))) {
+ est_binlen += 4;
+ }
+ if (mode[i] == 'b') { /* Byte mode has byte count (and no terminator) */
+ est_binlen += 13;
+ }
+ lastmode = mode[i];
+ submode = 1;
+ numeric_run = 0;
+ }
+ switch (mode[i]) {
+ case 'n':
+ if (numeric_run % 3 == 0) {
+ est_binlen += 10;
+ }
+ numeric_run++;
+ break;
+ case 't':
+ if (getsubmode(source[i]) != submode) {
+ est_binlen += 6;
+ submode = getsubmode(source[i]);
+ }
+ est_binlen += 6;
+ break;
+ case 'b':
+ est_binlen += source[i] > 0xFF ? 16 : 8;
+ break;
+ case '1':
+ case '2':
+ est_binlen += 12;
+ break;
+ case 'd':
+ est_binlen += 15;
+ break;
+ case 'f':
+ est_binlen += 25;
+ i++;
+ break;
+ }
+ i++;
+ } while (i < length);
+
+ est_binlen += terminator_length(lastmode);
+
+ return est_binlen;
+}
+
+static int isRegion1(unsigned int glyph) {
+ int first_byte, second_byte;
+ int valid = 0;
+
+ first_byte = (glyph & 0xff00) >> 8;
+ second_byte = glyph & 0xff;
+
+ if ((first_byte >= 0xb0) && (first_byte <= 0xd7)) {
+ if ((second_byte >= 0xa1) && (second_byte <= 0xfe)) {
+ valid = 1;
+ }
+ }
+
+ if ((first_byte >= 0xa1) && (first_byte <= 0xa3)) {
+ if ((second_byte >= 0xa1) && (second_byte <= 0xfe)) {
+ valid = 1;
+ }
+ }
+
+ if ((glyph >= 0xa8a1) && (glyph <= 0xa8c0)) {
+ valid = 1;
+ }
+
+ return valid;
+}
+
+static int isRegion2(unsigned int glyph) {
+ int first_byte, second_byte;
+ int valid = 0;
+
+ first_byte = (glyph & 0xff00) >> 8;
+ second_byte = glyph & 0xff;
+
+ if ((first_byte >= 0xd8) && (first_byte <= 0xf7)) {
+ if ((second_byte >= 0xa1) && (second_byte <= 0xfe)) {
+ valid = 1;
+ }
+ }
+
+ return valid;
+}
+
+static int isDoubleByte(unsigned int glyph) {
+ int first_byte, second_byte;
+ int valid = 0;
+
+ first_byte = (glyph & 0xff00) >> 8;
+ second_byte = glyph & 0xff;
+
+ if ((first_byte >= 0x81) && (first_byte <= 0xfe)) {
+ if ((second_byte >= 0x40) && (second_byte <= 0x7e)) {
+ valid = 1;
+ }
+
+ if ((second_byte >= 0x80) && (second_byte <= 0xfe)) {
+ valid = 1;
+ }
+ }
+
+ return valid;
+}
+
+static int isFourByte(unsigned int glyph, unsigned int glyph2) {
+ int first_byte, second_byte;
+ int third_byte, fourth_byte;
+ int valid = 0;
+
+ first_byte = (glyph & 0xff00) >> 8;
+ second_byte = glyph & 0xff;
+ third_byte = (glyph2 & 0xff00) >> 8;
+ fourth_byte = glyph2 & 0xff;
+
+ if ((first_byte >= 0x81) && (first_byte <= 0xfe)) {
+ if ((second_byte >= 0x30) && (second_byte <= 0x39)) {
+ if ((third_byte >= 0x81) && (third_byte <= 0xfe)) {
+ if ((fourth_byte >= 0x30) && (fourth_byte <= 0x39)) {
+ valid = 1;
+ }
+ }
+ }
+ }
+
+ return valid;
+}
+
+/* Convert Text 1 sub-mode character to encoding value, as given in table 3 */
+static int lookup_text1(unsigned int input) {
+ int encoding_value = -1;
+
+ if ((input >= '0') && (input <= '9')) {
+ encoding_value = input - '0';
+ }
+
+ if ((input >= 'A') && (input <= 'Z')) {
+ encoding_value = input - 'A' + 10;
+ }
+
+ if ((input >= 'a') && (input <= 'z')) {
+ encoding_value = input - 'a' + 36;
+ }
+
+ return encoding_value;
+}
+
+/* Convert Text 2 sub-mode character to encoding value, as given in table 4 */
+static int lookup_text2(unsigned int input) {
+ int encoding_value = -1;
+
+ if (input <= 27) {
+ encoding_value = input;
+ }
+
+ if ((input >= ' ') && (input <= '/')) {
+ encoding_value = input - ' ' + 28;
+ }
+
+ if ((input >= ':') && (input <= '@')) {
+ encoding_value = input - ':' + 44;
+ }
+
+ if ((input >= '[') && (input <= 96)) {
+ encoding_value = input - '[' + 51;
+ }
+
+ if ((input >= '{') && (input <= 127)) {
+ encoding_value = input - '{' + 57;
+ }
+
+ return encoding_value;
+}
+
+/* hx_define_mode() stuff */
+
+/* Bits multiplied by this for costs, so as to be whole integer divisible by 2 and 3 */
+#define HX_MULT 6
+
+/* Whether in numeric or not. If in numeric, *p_end is set to position after numeric, and *p_cost is set to per-numeric cost */
+static int in_numeric(const unsigned int gbdata[], const size_t length, const unsigned int posn, unsigned int* p_end, unsigned int* p_cost) {
+ unsigned int i, digit_cnt;
+
+ if (posn < *p_end) {
+ return 1;
+ }
+
+ /* Attempt to calculate the average 'cost' of using numeric mode in number of bits (times HX_MULT) */
+ for (i = posn; i < length && i < posn + 4 && gbdata[i] >= '0' && gbdata[i] <= '9'; i++);
+
+ digit_cnt = i - posn;
+
+ if (digit_cnt == 0) {
+ *p_end = 0;
+ return 0;
+ }
+ *p_end = i;
+ *p_cost = digit_cnt == 1 ? 60 /* 10 * HX_MULT */ : digit_cnt == 2 ? 30 /* (10 / 2) * HX_MULT */ : 20 /* (10 / 3) * HX_MULT */;
+ return 1;
+}
+
+/* Whether in four-byte or not. If in four-byte, *p_fourbyte is set to position after four-byte, and *p_fourbyte_cost is set to per-position cost */
+static int in_fourbyte(const unsigned int gbdata[], const size_t length, const unsigned int posn, unsigned int* p_end, unsigned int* p_cost) {
+ if (posn < *p_end) {
+ return 1;
+ }
+
+ if (posn == length - 1 || !isFourByte(gbdata[posn], gbdata[posn + 1])) {
+ *p_end = 0;
+ return 0;
+ }
+ *p_end = posn + 2;
+ *p_cost = 75; /* ((4 + 21) / 2) * HX_MULT */
+ return 1;
+}
+
+/* Indexes into mode_types array */
+#define HX_N 0 /* Numeric */
+#define HX_T 1 /* Text */
+#define HX_B 2 /* Binary */
+#define HX_1 3 /* Common Chinese Region One */
+#define HX_2 4 /* Common Chinese Region Two */
+#define HX_D 5 /* GB 18030 2-byte Region */
+#define HX_F 6 /* GB 18030 4-byte Region */
+/* Note Unicode, GS1 and URI modes not implemented */
+
+#define HX_NUM_MODES 7
+
+/* Initial mode costs */
+static unsigned int* hx_head_costs(unsigned int state[]) {
+ static unsigned int head_costs[HX_NUM_MODES] = {
+ /* N T B 1 2 D F */
+ 4 * HX_MULT, 4 * HX_MULT, (4 + 13) * HX_MULT, 4 * HX_MULT, 4 * HX_MULT, 4 * HX_MULT, 0
+ };
+
+ (void)state; /* Unused */
+ return head_costs;
+}
+
+/* Cost of switching modes from k to j */
+static unsigned int hx_switch_cost(unsigned int state[], const int k, const int j) {
+ static const unsigned int switch_costs[HX_NUM_MODES][HX_NUM_MODES] = {
+ /* N T B 1 2 D F */
+ /*N*/ { 0, (10 + 4) * HX_MULT, (10 + 4 + 13) * HX_MULT, (10 + 4) * HX_MULT, (10 + 4) * HX_MULT, (10 + 4) * HX_MULT, 10 * HX_MULT },
+ /*T*/ { (6 + 4) * HX_MULT, 0, (6 + 4 + 13) * HX_MULT, (6 + 4) * HX_MULT, (6 + 4) * HX_MULT, (6 + 4) * HX_MULT, 6 * HX_MULT },
+ /*B*/ { 4 * HX_MULT, 4 * HX_MULT, 0, 4 * HX_MULT, 4 * HX_MULT, 4 * HX_MULT, 0 },
+ /*1*/ { (12 + 4) * HX_MULT, (12 + 4) * HX_MULT, (12 + 4 + 13) * HX_MULT, 0, 12 * HX_MULT, (12 + 4) * HX_MULT, 12 * HX_MULT },
+ /*2*/ { (12 + 4) * HX_MULT, (12 + 4) * HX_MULT, (12 + 4 + 13) * HX_MULT, 12 * HX_MULT, 0, (12 + 4) * HX_MULT, 12 * HX_MULT },
+ /*D*/ { (15 + 4) * HX_MULT, (15 + 4) * HX_MULT, (15 + 4 + 13) * HX_MULT, (15 + 4) * HX_MULT, (15 + 4) * HX_MULT, 0, 15 * HX_MULT },
+ /*F*/ { 4 * HX_MULT, 4 * HX_MULT, (4 + 13) * HX_MULT, 4 * HX_MULT, 4 * HX_MULT, 4 * HX_MULT, 0 },
+ };
+
+ (void)state; /* Unused */
+ return switch_costs[k][j];
+}
+
+/* Final end-of-data costs */
+static unsigned int hx_eod_cost(unsigned int state[], const int k) {
+ static const unsigned int eod_costs[HX_NUM_MODES] = {
+ /* N T B 1 2 D F */
+ 10 * HX_MULT, 6 * HX_MULT, 0, 12 * HX_MULT, 12 * HX_MULT, 15 * HX_MULT, 0
+ };
+
+ (void)state; /* Unused */
+ return eod_costs[k];
+}
+
+/* Calculate cost of encoding character */
+static void hx_cur_cost(unsigned int state[], const unsigned int gbdata[], const size_t length, const int i, char* char_modes, unsigned int prev_costs[], unsigned int cur_costs[]) {
+ int cm_i = i * HX_NUM_MODES;
+ int text1, text2;
+ unsigned int* p_numeric_end = &state[0];
+ unsigned int* p_numeric_cost = &state[1];
+ unsigned int* p_text_submode = &state[2];
+ unsigned int* p_fourbyte_end = &state[3];
+ unsigned int* p_fourbyte_cost = &state[4];
+
+ if (in_numeric(gbdata, length, i, p_numeric_end, p_numeric_cost)) {
+ cur_costs[HX_N] = prev_costs[HX_N] + *p_numeric_cost;
+ char_modes[cm_i + HX_N] = 'n';
+ }
+
+ text1 = lookup_text1(gbdata[i]) != -1;
+ text2 = lookup_text2(gbdata[i]) != -1;
+
+ if (text1 || text2) {
+ if ((*p_text_submode == 1 && text2) || (*p_text_submode == 2 && text1)) {
+ cur_costs[HX_T] = prev_costs[HX_T] + 72; /* (6 + 6) * HX_MULT */
+ *p_text_submode = text2 ? 2 : 1;
+ } else {
+ cur_costs[HX_T] = prev_costs[HX_T] + 36; /* 6 * HX_MULT */
+ }
+ char_modes[cm_i + HX_T] = 't';
+ } else {
+ *p_text_submode = 1;
+ }
+
+ /* Binary mode can encode anything */
+ cur_costs[HX_B] = prev_costs[HX_B] + (gbdata[i] > 0xFF ? 96 : 48); /* (16 : 8) * HX_MULT */
+ char_modes[cm_i + HX_B] = 'b';
+
+ if (isRegion1(gbdata[i])) {
+ cur_costs[HX_1] = prev_costs[HX_1] + 72; /* 12 * HX_MULT */
+ char_modes[cm_i + HX_1] = '1';
+ }
+ if (isRegion2(gbdata[i])) {
+ cur_costs[HX_2] = prev_costs[HX_2] + 72; /* 12 * HX_MULT */
+ char_modes[cm_i + HX_2] = '2';
+ }
+ if (isDoubleByte(gbdata[i])) {
+ cur_costs[HX_D] = prev_costs[HX_D] + 90; /* 15 * HX_MULT */
+ char_modes[cm_i + HX_D] = 'd';
+ }
+ if (in_fourbyte(gbdata, length, i, p_fourbyte_end, p_fourbyte_cost)) {
+ cur_costs[HX_F] = prev_costs[HX_F] + *p_fourbyte_cost;
+ char_modes[cm_i + HX_F] = 'f';
+ }
+}
+
+/* Calculate optimized encoding modes */
+static void hx_define_mode(char* mode, const unsigned int gbdata[], const size_t length, const int debug) {
+ static const char mode_types[] = { 'n', 't', 'b', '1', '2', 'd', 'f' }; /* Must be in same order as HX_N etc */
+ unsigned int state[5] = { 0 /*numeric_end*/, 0 /*numeric_cost*/, 1 /*text_submode*/, 0 /*fourbyte_end*/, 0 /*fourbyte_cost*/ };
+
+ pn_define_mode(mode, gbdata, length, debug, state, mode_types, HX_NUM_MODES, hx_head_costs, hx_switch_cost, hx_eod_cost, hx_cur_cost);
+}
+
+/* Convert input data to binary stream */
+static void calculate_binary(char binary[], char mode[], unsigned int source[], const size_t length, const int eci, int debug) {
+ unsigned int position = 0;
+ int i, count, encoding_value;
+ int first_byte, second_byte;
+ int third_byte, fourth_byte;
+ int glyph;
+ int submode;
+
+ if (eci != 0) {
+ /* Encoding ECI assignment number, according to Table 5 */
+ bin_append(8, 4, binary); // ECI
+ if (eci <= 127) {
+ bin_append(eci, 8, binary);
+ }
+ if ((eci >= 128) && (eci <= 16383)) {
+ strcat(binary, "10");
+ bin_append(eci, 14, binary);
+ }
+ if (eci >= 16384) {
+ strcat(binary, "110");
+ bin_append(eci, 21, binary);
+ }
+ }
+
+ do {
+ int block_length = 0;
+ int double_byte = 0;
+ do {
+ if (mode[position] == 'b' && source[position + block_length] > 0xFF) {
+ double_byte++;
+ }
+ block_length++;
+ } while (position + block_length < length && mode[position + block_length] == mode[position]);
+
+ switch (mode[position]) {
+ case 'n':
+ /* Numeric mode */
+ /* Mode indicator */
+ bin_append(1, 4, binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Numeric\n");
+ }
+
+ count = 0; /* Suppress gcc -Wmaybe-uninitialized */
+ i = 0;
+
+ while (i < block_length) {
+ int first = 0;
+
+ first = posn(NEON, (char) source[position + i]);
+ count = 1;
+ encoding_value = first;
+
+ if (i + 1 < block_length && mode[position + i + 1] == 'n') {
+ int second = posn(NEON, (char) source[position + i + 1]);
+ count = 2;
+ encoding_value = (encoding_value * 10) + second;
+
+ if (i + 2 < block_length && mode[position + i + 2] == 'n') {
+ int third = posn(NEON, (char) source[position + i + 2]);
+ count = 3;
+ encoding_value = (encoding_value * 10) + third;
+ }
+ }
+
+ bin_append(encoding_value, 10, binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("0x%4x (%d)", encoding_value, encoding_value);
+ }
+
+ i += count;
+ }
+
+ /* Mode terminator depends on number of characters in last group (Table 2) */
+ switch (count) {
+ case 1:
+ bin_append(1021, 10, binary);
+ break;
+ case 2:
+ bin_append(1022, 10, binary);
+ break;
+ case 3:
+ bin_append(1023, 10, binary);
+ break;
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf(" (TERM %d)\n", count);
+ }
+
+ break;
+ case 't':
+ /* Text mode */
+ /* Mode indicator */
+ bin_append(2, 4, binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Text\n");
+ }
+
+ submode = 1;
+
+ i = 0;
+
+ while (i < block_length) {
+
+ if (getsubmode(source[i + position]) != submode) {
+ /* Change submode */
+ bin_append(62, 6, binary);
+ submode = getsubmode(source[i + position]);
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("SWITCH ");
+ }
+ }
+
+ if (submode == 1) {
+ encoding_value = lookup_text1(source[i + position]);
+ } else {
+ encoding_value = lookup_text2(source[i + position]);
+ }
+
+ bin_append(encoding_value, 6, binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("%.2x [ASC %.2x] ", encoding_value, source[i + position]);
+ }
+ i++;
+ }
+
+ /* Terminator */
+ bin_append(63, 6, binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("\n");
+ }
+ break;
+ case 'b':
+ /* Binary Mode */
+ /* Mode indicator */
+ bin_append(3, 4, binary);
+
+ /* Count indicator */
+ bin_append(block_length + double_byte, 13, binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Binary (length %d)\n", block_length + double_byte);
+ }
+
+ i = 0;
+
+ while (i < block_length) {
+
+ /* 8-bit bytes with no conversion */
+ bin_append(source[i + position], source[i + position] > 0xFF ? 16 : 8, binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("%d ", source[i + position]);
+ }
+
+ i++;
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("\n");
+ }
+ break;
+ case '1':
+ /* Region 1 encoding */
+ /* Mode indicator */
+ if (position == 0 || mode[position - 1] != '2') { /* Unless previous mode Region 2 */
+ bin_append(4, 4, binary);
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Region 1\n");
+ }
+
+ i = 0;
+
+ while (i < block_length) {
+ first_byte = (source[i + position] & 0xff00) >> 8;
+ second_byte = source[i + position] & 0xff;
+
+ /* Subset 1 */
+ glyph = (0x5e * (first_byte - 0xb0)) + (second_byte - 0xa1);
+
+ /* Subset 2 */
+ if ((first_byte >= 0xa1) && (first_byte <= 0xa3)) {
+ if ((second_byte >= 0xa1) && (second_byte <= 0xfe)) {
+ glyph = (0x5e * (first_byte - 0xa1)) + (second_byte - 0xa1) + 0xeb0;
+ }
+ }
+
+ /* Subset 3 */
+ if ((source[i + position] >= 0xa8a1) && (source[i + position] <= 0xa8c0)) {
+ glyph = (second_byte - 0xa1) + 0xfca;
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("%.4x [GB %.4x] ", glyph, source[i + position]);
+ }
+
+ bin_append(glyph, 12, binary);
+ i++;
+ }
+
+ /* Terminator */
+ bin_append(position == length - 1 || mode[position + 1] != '2' ? 4095 : 4094, 12, binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("\n");
+ }
+
+ break;
+ case '2':
+ /* Region 2 encoding */
+ /* Mode indicator */
+ if (position == 0 || mode[position - 1] != '1') { /* Unless previous mode Region 1 */
+ bin_append(5, 4, binary);
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Region 2\n");
+ }
+
+ i = 0;
+
+ while (i < block_length) {
+ first_byte = (source[i + position] & 0xff00) >> 8;
+ second_byte = source[i + position] & 0xff;
+
+ glyph = (0x5e * (first_byte - 0xd8)) + (second_byte - 0xa1);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("%.4x [GB %.4x] ", glyph, source[i + position]);
+ }
+
+ bin_append(glyph, 12, binary);
+ i++;
+ }
+
+ /* Terminator */
+ bin_append(position == length - 1 || mode[position + 1] != '1' ? 4095 : 4094, 12, binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("\n");
+ }
+ break;
+ case 'd':
+ /* Double byte encoding */
+ /* Mode indicator */
+ bin_append(6, 4, binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Double byte\n");
+ }
+
+ i = 0;
+
+ while (i < block_length) {
+ first_byte = (source[i + position] & 0xff00) >> 8;
+ second_byte = source[i + position] & 0xff;
+
+ if (second_byte <= 0x7e) {
+ glyph = (0xbe * (first_byte - 0x81)) + (second_byte - 0x40);
+ } else {
+ glyph = (0xbe * (first_byte - 0x81)) + (second_byte - 0x41);
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("%.4x ", glyph);
+ }
+
+ bin_append(glyph, 15, binary);
+ i++;
+ }
+
+ /* Terminator */
+ bin_append(32767, 15, binary);
+ /* Terminator sequence of length 12 is a mistake
+ - confirmed by Wang Yi */
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("\n");
+ }
+ break;
+ case 'f':
+ /* Four-byte encoding */
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Four byte\n");
+ }
+
+ i = 0;
+
+ while (i < block_length) {
+
+ /* Mode indicator */
+ bin_append(7, 4, binary);
+
+ first_byte = (source[i + position] & 0xff00) >> 8;
+ second_byte = source[i + position] & 0xff;
+ third_byte = (source[i + position + 1] & 0xff00) >> 8;
+ fourth_byte = source[i + position + 1] & 0xff;
+
+ glyph = (0x3138 * (first_byte - 0x81)) + (0x04ec * (second_byte - 0x30)) +
+ (0x0a * (third_byte - 0x81)) + (fourth_byte - 0x30);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("%d ", glyph);
+ }
+
+ bin_append(glyph, 21, binary);
+ i += 2;
+ }
+
+ /* No terminator */
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("\n");
+ }
+ break;
+
+ }
+
+ position += block_length;
+
+ } while (position < length);
+}
+
+/* Finder pattern for top left of symbol */
+static void hx_place_finder_top_left(unsigned char* grid, int size) {
+ int xp, yp;
+ int x = 0, y = 0;
+ char finder[] = {0x7F, 0x40, 0x5F, 0x50, 0x57, 0x57, 0x57};
+
+ for (xp = 0; xp < 7; xp++) {
+ for (yp = 0; yp < 7; yp++) {
+ if (finder[yp] & 0x40 >> xp) {
+ grid[((yp + y) * size) + (xp + x)] = 0x11;
+ } else {
+ grid[((yp + y) * size) + (xp + x)] = 0x10;
+ }
+ }
+ }
+}
+
+/* Finder pattern for top right and bottom left of symbol */
+static void hx_place_finder(unsigned char* grid, int size, int x, int y) {
+ int xp, yp;
+ char finder[] = {0x7F, 0x01, 0x7D, 0x05, 0x75, 0x75, 0x75};
+
+ for (xp = 0; xp < 7; xp++) {
+ for (yp = 0; yp < 7; yp++) {
+ if (finder[yp] & 0x40 >> xp) {
+ grid[((yp + y) * size) + (xp + x)] = 0x11;
+ } else {
+ grid[((yp + y) * size) + (xp + x)] = 0x10;
+ }
+ }
+ }
+}
+
+/* Finder pattern for bottom right of symbol */
+static void hx_place_finder_bottom_right(unsigned char* grid, int size) {
+ int xp, yp;
+ int x = size - 7, y = size - 7;
+ char finder[] = {0x75, 0x75, 0x75, 0x05, 0x7D, 0x01, 0x7F};
+
+ for (xp = 0; xp < 7; xp++) {
+ for (yp = 0; yp < 7; yp++) {
+ if (finder[yp] & 0x40 >> xp) {
+ grid[((yp + y) * size) + (xp + x)] = 0x11;
+ } else {
+ grid[((yp + y) * size) + (xp + x)] = 0x10;
+ }
+ }
+ }
+}
+
+/* Avoid plotting outside symbol or over finder patterns */
+static void hx_safe_plot(unsigned char *grid, int size, int x, int y, int value) {
+ if ((x >= 0) && (x < size)) {
+ if ((y >= 0) && (y < size)) {
+ if (grid[(y * size) + x] == 0) {
+ grid[(y * size) + x] = value;
+ }
+ }
+ }
+}
+
+/* Plot an alignment pattern around top and right of a module */
+static void hx_plot_alignment(unsigned char *grid, int size, int x, int y, int w, int h) {
+ int i;
+ hx_safe_plot(grid, size, x, y, 0x11);
+ hx_safe_plot(grid, size, x - 1, y + 1, 0x10);
+
+ for (i = 1; i <= w; i++) {
+ /* Top */
+ hx_safe_plot(grid, size, x - i, y, 0x11);
+ hx_safe_plot(grid, size, x - i - 1, y + 1, 0x10);
+ }
+
+ for (i = 1; i < h; i++) {
+ /* Right */
+ hx_safe_plot(grid, size, x, y + i, 0x11);
+ hx_safe_plot(grid, size, x - 1, y + i + 1, 0x10);
+ }
+}
+
+/* Plot assistant alignment patterns */
+static void hx_plot_assistant(unsigned char *grid, int size, int x, int y) {
+ hx_safe_plot(grid, size, x - 1, y - 1, 0x10);
+ hx_safe_plot(grid, size, x, y - 1, 0x10);
+ hx_safe_plot(grid, size, x + 1, y - 1, 0x10);
+ hx_safe_plot(grid, size, x - 1, y, 0x10);
+ hx_safe_plot(grid, size, x, y, 0x11);
+ hx_safe_plot(grid, size, x + 1, y, 0x10);
+ hx_safe_plot(grid, size, x - 1, y + 1, 0x10);
+ hx_safe_plot(grid, size, x, y + 1, 0x10);
+ hx_safe_plot(grid, size, x + 1, y + 1, 0x10);
+}
+
+/* Put static elements in the grid */
+static void hx_setup_grid(unsigned char* grid, int size, int version) {
+ int i, j;
+
+ for (i = 0; i < size; i++) {
+ for (j = 0; j < size; j++) {
+ grid[(i * size) + j] = 0;
+ }
+ }
+
+ /* Add finder patterns */
+ hx_place_finder_top_left(grid, size);
+ hx_place_finder(grid, size, 0, size - 7);
+ hx_place_finder(grid, size, size - 7, 0);
+ hx_place_finder_bottom_right(grid, size);
+
+ /* Add finder pattern separator region */
+ for (i = 0; i < 8; i++) {
+ /* Top left */
+ grid[(7 * size) + i] = 0x10;
+ grid[(i * size) + 7] = 0x10;
+
+ /* Top right */
+ grid[(7 * size) + (size - i - 1)] = 0x10;
+ grid[((size - i - 1) * size) + 7] = 0x10;
+
+ /* Bottom left */
+ grid[(i * size) + (size - 8)] = 0x10;
+ grid[((size - 8) * size) + i] = 0x10;
+
+ /* Bottom right */
+ grid[((size - 8) * size) + (size - i - 1)] = 0x10;
+ grid[((size - i - 1) * size) + (size - 8)] = 0x10;
+ }
+
+ /* Reserve function information region */
+ for (i = 0; i < 9; i++) {
+ /* Top left */
+ grid[(8 * size) + i] = 0x10;
+ grid[(i * size) + 8] = 0x10;
+
+ /* Top right */
+ grid[(8 * size) + (size - i - 1)] = 0x10;
+ grid[((size - i - 1) * size) + 8] = 0x10;
+
+ /* Bottom left */
+ grid[(i * size) + (size - 9)] = 0x10;
+ grid[((size - 9) * size) + i] = 0x10;
+
+ /* Bottom right */
+ grid[((size - 9) * size) + (size - i - 1)] = 0x10;
+ grid[((size - i - 1) * size) + (size - 9)] = 0x10;
+ }
+
+ if (version > 3) {
+ int k = hx_module_k[version - 1];
+ int r = hx_module_r[version - 1];
+ int m = hx_module_m[version - 1];
+ int x, y, row_switch, column_switch;
+ int module_height, module_width;
+ int mod_x, mod_y;
+
+ /* Add assistant alignment patterns to left and right */
+ y = 0;
+ mod_y = 0;
+ do {
+ if (mod_y < m) {
+ module_height = k;
+ } else {
+ module_height = r - 1;
+ }
+
+ if ((mod_y % 2) == 0) {
+ if ((m % 2) == 1) {
+ hx_plot_assistant(grid, size, 0, y);
+ }
+ } else {
+ if ((m % 2) == 0) {
+ hx_plot_assistant(grid, size, 0, y);
+ }
+ hx_plot_assistant(grid, size, size - 1, y);
+ }
+
+ mod_y++;
+ y += module_height;
+ } while (y < size);
+
+ /* Add assistant alignment patterns to top and bottom */
+ x = (size - 1);
+ mod_x = 0;
+ do {
+ if (mod_x < m) {
+ module_width = k;
+ } else {
+ module_width = r - 1;
+ }
+
+ if ((mod_x % 2) == 0) {
+ if ((m % 2) == 1) {
+ hx_plot_assistant(grid, size, x, (size - 1));
+ }
+ } else {
+ if ((m % 2) == 0) {
+ hx_plot_assistant(grid, size, x, (size - 1));
+ }
+ hx_plot_assistant(grid, size, x, 0);
+ }
+
+ mod_x++;
+ x -= module_width;
+ } while (x >= 0);
+
+ /* Add alignment pattern */
+ column_switch = 1;
+ y = 0;
+ mod_y = 0;
+ do {
+ if (mod_y < m) {
+ module_height = k;
+ } else {
+ module_height = r - 1;
+ }
+
+ if (column_switch == 1) {
+ row_switch = 1;
+ column_switch = 0;
+ } else {
+ row_switch = 0;
+ column_switch = 1;
+ }
+
+ x = (size - 1);
+ mod_x = 0;
+ do {
+ if (mod_x < m) {
+ module_width = k;
+ } else {
+ module_width = r - 1;
+ }
+
+ if (row_switch == 1) {
+ if (!(y == 0 && x == (size - 1))) {
+ hx_plot_alignment(grid, size, x, y, module_width, module_height);
+ }
+ row_switch = 0;
+ } else {
+ row_switch = 1;
+ }
+ mod_x++;
+ x -= module_width;
+ } while (x >= 0);
+
+ mod_y++;
+ y += module_height;
+ } while (y < size);
+ }
+}
+
+/* Calculate error correction codes */
+static void hx_add_ecc(unsigned char fullstream[], unsigned char datastream[], int data_codewords, int version, int ecc_level) {
+ unsigned char data_block[180];
+ unsigned char ecc_block[36];
+ int i, j, block;
+ int input_position = -1;
+ int output_position = -1;
+ int table_d1_pos = ((version - 1) * 36) + ((ecc_level - 1) * 9);
+
+ for (i = 0; i < 3; i++) {
+ int batch_size = hx_table_d1[table_d1_pos + (3 * i)];
+ int data_length = hx_table_d1[table_d1_pos + (3 * i) + 1];
+ int ecc_length = hx_table_d1[table_d1_pos + (3 * i) + 2];
+
+ for (block = 0; block < batch_size; block++) {
+ for (j = 0; j < data_length; j++) {
+ input_position++;
+ output_position++;
+ data_block[j] = input_position < data_codewords ? datastream[input_position] : 0;
+ fullstream[output_position] = data_block[j];
+ }
+
+ rs_init_gf(0x163); // x^8 + x^6 + x^5 + x + 1 = 0
+ rs_init_code(ecc_length, 1);
+ rs_encode(data_length, data_block, ecc_block);
+ rs_free();
+
+ for (j = 0; j < ecc_length; j++) {
+ output_position++;
+ fullstream[output_position] = ecc_block[ecc_length - j - 1];
+ }
+ }
+ }
+}
+
+/* Rearrange data in batches of 13 codewords (section 5.8.2) */
+static void make_picket_fence(unsigned char fullstream[], unsigned char picket_fence[], int streamsize) {
+ int i, start;
+ int output_position = 0;
+
+ for (start = 0; start < 13; start++) {
+ for (i = start; i < streamsize; i += 13) {
+ if (i < streamsize) {
+ picket_fence[output_position] = fullstream[i];
+ output_position++;
+ }
+ }
+ }
+}
+
+/* Evaluate a bitmask according to table 9 */
+static int hx_evaluate(unsigned char *eval, int size, int pattern) {
+ int x, y, block, weight;
+ int result = 0;
+ char state;
+ int p;
+ int a, b, afterCount, beforeCount;
+#ifndef _MSC_VER
+ char local[size * size];
+#else
+ char* local = (char *) _alloca((size * size) * sizeof (char));
+#endif
+
+ /* all four bitmask variants have been encoded in the 4 bits of the bytes
+ * that make up the grid array. select them for evaluation according to the
+ * desired pattern.*/
+ for (x = 0; x < size; x++) {
+ for (y = 0; y < size; y++) {
+ if (eval[(y * size) + x] & 0xf0) {
+ local[(y * size) + x] = 0;
+ } else if ((eval[(y * size) + x] & (0x01 << pattern)) != 0) {
+ local[(y * size) + x] = '1';
+ } else {
+ local[(y * size) + x] = '0';
+ }
+ }
+ }
+
+ /* Test 1: 1:1:1:1:3 or 3:1:1:1:1 ratio pattern in row/column */
+ /* Vertical */
+ for (x = 0; x < size; x++) {
+ for (y = 0; y < (size - 7); y++) {
+ if (local[(y * size) + x] == 0) {
+ continue;
+ }
+ p = 0;
+ for (weight = 0; weight < 7; weight++) {
+ if (local[((y + weight) * size) + x] == '1') {
+ p += (0x40 >> weight);
+ }
+ }
+ if ((p == 0x57) || (p == 0x75)) {
+ /* Pattern found, check before and after */
+ beforeCount = 0;
+ for (b = (y - 3); b < y; b++) {
+ if (b < 0) {
+ beforeCount++;
+ } else {
+ if (local[(b * size) + x] == '0') {
+ beforeCount++;
+ } else {
+ break;
+ }
+ }
+ }
+
+ afterCount = 0;
+ for (a = (y + 7); a <= (y + 9); a++) {
+ if (a >= size) {
+ afterCount++;
+ } else {
+ if (local[(a * size) + x] == '0') {
+ afterCount++;
+ } else {
+ break;
+ }
+ }
+ }
+
+ if ((beforeCount == 3) || (afterCount == 3)) {
+ /* Pattern is preceeded or followed by light area
+ 3 modules wide */
+ result += 50;
+ }
+ }
+ }
+ }
+
+ /* Horizontal */
+ for (y = 0; y < size; y++) {
+ for (x = 0; x < (size - 7); x++) {
+ if (local[(y * size) + x] == 0) {
+ continue;
+ }
+ p = 0;
+ for (weight = 0; weight < 7; weight++) {
+ if (local[(y * size) + x + weight] == '1') {
+ p += (0x40 >> weight);
+ }
+ }
+ if ((p == 0x57) || (p == 0x75)) {
+ /* Pattern found, check before and after */
+ beforeCount = 0;
+ for (b = (x - 3); b < x; b++) {
+ if (b < 0) {
+ beforeCount++;
+ } else {
+ if (local[(y * size) + b] == '0') {
+ beforeCount++;
+ } else {
+ break;
+ }
+ }
+ }
+
+ afterCount = 0;
+ for (a = (x + 7); a <= (x + 9); a++) {
+ if (a >= size) {
+ afterCount++;
+ } else {
+ if (local[(y * size) + a] == '0') {
+ afterCount++;
+ } else {
+ break;
+ }
+ }
+ }
+
+ if ((beforeCount == 3) || (afterCount == 3)) {
+ /* Pattern is preceeded or followed by light area
+ 3 modules wide */
+ result += 50;
+ }
+ }
+ }
+ }
+
+ /* Test 2: Adjacent modules in row/column in same colour */
+ /* In AIMD-15 section 5.8.3.2 it is stated... “In Table 9 below, i refers to the row
+ * position of the module.†- however i being the length of the run of the
+ * same colour (i.e. "block" below) in the same fashion as ISO/IEC 18004
+ * makes more sense. -- Confirmed by Wang Yi */
+ /* Fixed in ISO/IEC 20830 (draft 2019-10-10) section 5.8.3.2 "In Table 12 below, i refers to the modules with same color." */
+
+ /* Vertical */
+ for (x = 0; x < size; x++) {
+ block = 0;
+ state = 0;
+ for (y = 0; y < size; y++) {
+ if (local[(y * size) + x] == 0) {
+ if (block >= 3) {
+ result += (3 + block) * 4;
+ }
+ block = 0;
+ state = 0;
+ } else if (local[(y * size) + x] == state || state == 0) {
+ block++;
+ state = local[(y * size) + x];
+ } else {
+ if (block >= 3) {
+ result += (3 + block) * 4;
+ }
+ block = 1;
+ state = local[(y * size) + x];
+ }
+ }
+ if (block >= 3) {
+ result += (3 + block) * 4;
+ }
+ }
+
+ /* Horizontal */
+ for (y = 0; y < size; y++) {
+ state = local[y * size];
+ block = 0;
+ for (x = 0; x < size; x++) {
+ if (local[(y * size) + x] == 0) {
+ if (block >= 3) {
+ result += (3 + block) * 4;
+ }
+ block = 0;
+ state = 0;
+ } else if (local[(y * size) + x] == state || state == 0) {
+ block++;
+ state = local[(y * size) + x];
+ } else {
+ if (block >= 3) {
+ result += (3 + block) * 4;
+ }
+ block = 1;
+ state = local[(y * size) + x];
+ }
+ }
+ if (block >= 3) {
+ result += (3 + block) * 4;
+ }
+ }
+
+ return result;
+}
+
+/* Apply the four possible bitmasks for evaluation */
+/* TODO: Haven't been able to replicate (or even get close to) the penalty scores in ISO/IEC 20830 (draft 2019-10-10) Annex K examples */
+static int hx_apply_bitmask(unsigned char *grid, int size) {
+ int x, y;
+ int i, j;
+ int pattern, penalty[4];
+ int best_pattern, best_val;
+ int bit;
+ unsigned char p;
+
+#ifndef _MSC_VER
+ unsigned char mask[(unsigned int)(size * size)]; /* Cast to suppress gcc -Walloc-size-larger-than */
+ unsigned char eval[(unsigned int)(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;
+ j = x + 1;
+ i = y + 1;
+
+ if (!(grid[(y * size) + x] & 0xf0)) {
+ if ((i + j) % 2 == 0) {
+ mask[(y * size) + x] += 0x02;
+ }
+ if ((((i + j) % 3) + (j % 3)) % 2 == 0) {
+ mask[(y * size) + x] += 0x04;
+ }
+ if (((i % j) + (j % i) + (i % 3) + (j % 3)) % 2 == 0) {
+ mask[(y * size) + x] += 0x08;
+ }
+ }
+ }
+ }
+
+ // apply data masks to grid, result in eval
+ for (x = 0; x < size; x++) {
+ for (y = 0; y < size; y++) {
+ if (grid[(y * size) + x] & 0xf0) {
+ p = 0xf0;
+ } else if (grid[(y * size) + x] & 0x01) {
+ p = 0x0f;
+ } else {
+ p = 0x00;
+ }
+
+ eval[(y * size) + x] = mask[(y * size) + x] ^ p;
+ }
+ }
+
+ /* Evaluate result */
+ for (pattern = 0; pattern < 4; pattern++) {
+ penalty[pattern] = hx_evaluate(eval, size, pattern);
+ }
+
+ best_pattern = 0;
+ best_val = penalty[0];
+ for (pattern = 1; pattern < 4; 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;
+ }
+ if (bit == 1) {
+ if (grid[(y * size) + x] & 0x01) {
+ grid[(y * size) + x] = 0x00;
+ } else {
+ grid[(y * size) + x] = 0x01;
+ }
+ }
+ }
+ }
+
+ return best_pattern;
+}
+
+/* Han Xin Code - main */
+INTERNAL int han_xin(struct zint_symbol *symbol, const unsigned char source[], size_t length) {
+ int est_binlen;
+ int ecc_level = symbol->option_1;
+ int i, j, version;
+ int full_multibyte;
+ int data_codewords = 0, size;
+ int codewords;
+ int bitmask;
+ int bin_len;
+ char function_information[36];
+ unsigned char fi_cw[3] = {0, 0, 0};
+ unsigned char fi_ecc[4];
+
+#ifndef _MSC_VER
+ unsigned int gbdata[(length + 1) * 2];
+ char mode[length + 1];
+#else
+ unsigned int* gbdata = (unsigned int *) _alloca(((length + 1) * 2) * sizeof (unsigned int));
+ char* mode = (char *) _alloca((length + 1) * sizeof (char));
+ char* binary;
+ unsigned char *datastream;
+ unsigned char *fullstream;
+ unsigned char *picket_fence;
+ unsigned char *grid;
+#endif
+
+ full_multibyte = symbol->option_3 == ZINT_FULL_MULTIBYTE; /* If set use Hanzi mode in DATA_MODE or for single-byte Latin */
+
+ if ((symbol->input_mode & 0x07) == DATA_MODE) {
+ gb18030_cpy(source, &length, gbdata, full_multibyte);
+ } else {
+ int done = 0;
+ if (symbol->eci != 29) { /* Unless ECI 29 (GB) */
+ /* Try single byte (Latin) conversion first */
+ int error_number = gb18030_utf8tosb(symbol->eci && symbol->eci <= 899 ? symbol->eci : 3, source, &length, gbdata, full_multibyte);
+ if (error_number == 0) {
+ done = 1;
+ } else if (symbol->eci && symbol->eci <= 899) {
+ strcpy(symbol->errtxt, "575: Invalid characters in input data");
+ return error_number;
+ }
+ }
+ if (!done) {
+ /* Try GB 18030 */
+ int error_number = gb18030_utf8tomb(symbol, source, &length, gbdata);
+ if (error_number != 0) {
+ return error_number;
+ }
+ }
+ }
+
+ hx_define_mode(mode, gbdata, length, symbol->debug);
+
+ est_binlen = calculate_binlength(mode, gbdata, length, symbol->eci);
+
+#ifndef _MSC_VER
+ char binary[est_binlen + 1];
+#else
+ binary = (char *) _alloca((est_binlen + 1) * sizeof (char));
+#endif
+ memset(binary, 0, (est_binlen + 1) * sizeof (char));
+
+ if ((ecc_level <= 0) || (ecc_level >= 5)) {
+ ecc_level = 1;
+ }
+
+ calculate_binary(binary, mode, gbdata, length, symbol->eci, symbol->debug);
+ bin_len = strlen(binary);
+ codewords = bin_len / 8;
+ if (bin_len % 8 != 0) {
+ codewords++;
+ }
+
+ version = 85;
+ for (i = 84; i > 0; i--) {
+ switch (ecc_level) {
+ case 1:
+ if (hx_data_codewords_L1[i - 1] > codewords) {
+ version = i;
+ data_codewords = hx_data_codewords_L1[i - 1];
+ }
+ break;
+ case 2:
+ if (hx_data_codewords_L2[i - 1] > codewords) {
+ version = i;
+ data_codewords = hx_data_codewords_L2[i - 1];
+ }
+ break;
+ case 3:
+ if (hx_data_codewords_L3[i - 1] > codewords) {
+ version = i;
+ data_codewords = hx_data_codewords_L3[i - 1];
+ }
+ break;
+ case 4:
+ if (hx_data_codewords_L4[i - 1] > codewords) {
+ version = i;
+ data_codewords = hx_data_codewords_L4[i - 1];
+ }
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+
+ if (version == 85) {
+ strcpy(symbol->errtxt, "541: Input too long for selected error correction level");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ if ((symbol->option_2 < 0) || (symbol->option_2 > 84)) {
+ symbol->option_2 = 0;
+ }
+
+ if (symbol->option_2 > version) {
+ version = symbol->option_2;
+ }
+
+ if ((symbol->option_2 != 0) && (symbol->option_2 < version)) {
+ strcpy(symbol->errtxt, "542: Input too long for selected symbol size");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ /* If there is spare capacity, increase the level of ECC */
+
+ if (symbol->option_1 == -1 || symbol->option_1 != ecc_level) { /* Unless explicitly specified (within min/max bounds) by user */
+ if ((ecc_level == 1) && (codewords < hx_data_codewords_L2[version - 1])) {
+ ecc_level = 2;
+ data_codewords = hx_data_codewords_L2[version - 1];
+ }
+
+ if ((ecc_level == 2) && (codewords < hx_data_codewords_L3[version - 1])) {
+ ecc_level = 3;
+ data_codewords = hx_data_codewords_L3[version - 1];
+ }
+
+ if ((ecc_level == 3) && (codewords < hx_data_codewords_L4[version - 1])) {
+ ecc_level = 4;
+ data_codewords = hx_data_codewords_L4[version - 1];
+ }
+ }
+
+ size = (version * 2) + 21;
+
+#ifndef _MSC_VER
+ unsigned char datastream[data_codewords];
+ unsigned char fullstream[hx_total_codewords[version - 1]];
+ unsigned char picket_fence[hx_total_codewords[version - 1]];
+ unsigned char grid[size * size];
+#else
+ datastream = (unsigned char *) _alloca((data_codewords) * sizeof (unsigned char));
+ fullstream = (unsigned char *) _alloca((hx_total_codewords[version - 1]) * sizeof (unsigned char));
+ picket_fence = (unsigned char *) _alloca((hx_total_codewords[version - 1]) * sizeof (unsigned char));
+ grid = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
+#endif
+
+ for (i = 0; i < data_codewords; i++) {
+ datastream[i] = 0;
+ }
+
+ for (i = 0; i < bin_len; i++) {
+ if (binary[i] == '1') {
+ datastream[i / 8] += 0x80 >> (i % 8);
+ }
+ }
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Datastream length: %d\n", data_codewords);
+ printf("Datastream:\n");
+ for (i = 0; i < data_codewords; i++) {
+ printf("%.2x ", datastream[i]);
+ }
+ printf("\n");
+ }
+#ifdef ZINT_TEST
+ if (symbol->debug & ZINT_DEBUG_TEST) debug_test_codeword_dump(symbol, datastream, data_codewords);
+#endif
+
+ hx_setup_grid(grid, size, version);
+
+ hx_add_ecc(fullstream, datastream, data_codewords, version, ecc_level);
+
+ make_picket_fence(fullstream, picket_fence, hx_total_codewords[version - 1]);
+
+ /* Populate grid */
+ j = 0;
+ for (i = 0; i < (size * size); i++) {
+ if (grid[i] == 0x00) {
+ if (j < (hx_total_codewords[version - 1] * 8)) {
+ if (picket_fence[(j / 8)] & (0x80 >> (j % 8))) {
+ grid[i] = 0x01;
+ }
+ j++;
+ }
+ }
+ }
+
+ bitmask = hx_apply_bitmask(grid, size);
+
+ /* Form function information string */
+ for (i = 0; i < 34; i++) {
+ if (i % 2) {
+ function_information[i] = '1';
+ } else {
+ function_information[i] = '0';
+ }
+ }
+ function_information[34] = '\0';
+
+ for (i = 0; i < 8; i++) {
+ if ((version + 20) & (0x80 >> i)) {
+ function_information[i] = '1';
+ } else {
+ function_information[i] = '0';
+ }
+ }
+
+ for (i = 0; i < 2; i++) {
+ if ((ecc_level - 1) & (0x02 >> i)) {
+ function_information[i + 8] = '1';
+ } else {
+ function_information[i + 8] = '0';
+ }
+ }
+
+ for (i = 0; i < 2; i++) {
+ if (bitmask & (0x02 >> i)) {
+ function_information[i + 10] = '1';
+ } else {
+ function_information[i + 10] = '0';
+ }
+ }
+
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 4; j++) {
+ if (function_information[(i * 4) + j] == '1') {
+ fi_cw[i] += (0x08 >> j);
+ }
+ }
+ }
+
+ rs_init_gf(0x13);
+ rs_init_code(4, 1);
+ rs_encode(3, fi_cw, fi_ecc);
+ rs_free();
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ if (fi_ecc[3 - i] & (0x08 >> j)) {
+ function_information[(i * 4) + j + 12] = '1';
+ } else {
+ function_information[(i * 4) + j + 12] = '0';
+ }
+ }
+ }
+
+ /* Add function information to symbol */
+ for (i = 0; i < 9; i++) {
+ if (function_information[i] == '1') {
+ grid[(8 * size) + i] = 0x01;
+ grid[((size - 8 - 1) * size) + (size - i - 1)] = 0x01;
+ }
+ if (function_information[i + 8] == '1') {
+ grid[((8 - i) * size) + 8] = 0x01;
+ grid[((size - 8 - 1 + i) * size) + (size - 8 - 1)] = 0x01;
+ }
+ if (function_information[i + 17] == '1') {
+ grid[(i * size) + (size - 1 - 8)] = 0x01;
+ grid[((size - 1 - i) * size) + 8] = 0x01;
+ }
+ if (function_information[i + 25] == '1') {
+ grid[(8 * size) + (size - 1 - 8 + i)] = 0x01;
+ grid[((size - 1 - 8) * size) + (8 - i)] = 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/hanxin.h b/backend/hanxin.h
new file mode 100644
index 0000000..a5258d7
--- /dev/null
+++ b/backend/hanxin.h
@@ -0,0 +1,460 @@
+/* hanxin.h - definitions for Han Xin code
+
+ libzint - the open source barcode library
+ Copyright (C) 2009-2017 Robin Stuart <rstuart114@gmail.com>
+ Copyright (C) 2016 Zoe Stuart
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+
+/* Data from table B1: Data capacity of Han Xin Code */
+static const unsigned short int hx_total_codewords[] = {
+ 25, 37, 50, 54, 69, 84, 100, 117, 136, 155, 161, 181, 203, 225, 249,
+ 273, 299, 325, 353, 381, 411, 422, 453, 485, 518, 552, 587, 623, 660,
+ 698, 737, 754, 794, 836, 878, 922, 966, 1011, 1058, 1105, 1126, 1175,
+ 1224, 1275, 1327, 1380, 1434, 1489, 1513, 1569, 1628, 1686, 1745, 1805,
+ 1867, 1929, 1992, 2021, 2086, 2151, 2218, 2286, 2355, 2425, 2496, 2528,
+ 2600, 2673, 2749, 2824, 2900, 2977, 3056, 3135, 3171, 3252, 3334, 3416,
+ 3500, 3585, 3671, 3758, 3798, 3886
+};
+
+static const unsigned short int hx_data_codewords_L1[] = {
+ 21, 31, 42, 46, 57, 70, 84, 99, 114, 131, 135, 153, 171, 189, 209, 229,
+ 251, 273, 297, 321, 345, 354, 381, 407, 436, 464, 493, 523, 554, 586, 619,
+ 634, 666, 702, 738, 774, 812, 849, 888, 929, 946, 987, 1028, 1071, 1115,
+ 1160, 1204, 1251, 1271, 1317, 1368, 1416, 1465, 1517, 1569, 1621, 1674,
+ 1697, 1752, 1807, 1864, 1920, 1979, 2037, 2096, 2124, 2184, 2245, 2309,
+ 2372, 2436, 2501, 2568, 2633, 2663, 2732, 2800, 2870, 2940, 3011,
+ 3083, 3156, 3190, 3264
+};
+
+static const unsigned short int hx_data_codewords_L2[] = {
+ 17, 25, 34, 38, 49, 58, 70, 81, 96, 109, 113, 127, 143, 157, 175, 191, 209,
+ 227, 247, 267, 287, 296, 317, 339, 362, 386, 411, 437, 462, 488, 515, 528,
+ 556, 586, 614, 646, 676, 707, 740, 773, 788, 823, 856, 893, 929, 966, 1004,
+ 1043, 1059, 1099, 1140, 1180, 1221, 1263, 1307, 1351, 1394, 1415, 1460,
+ 1505, 1552, 1600, 1649, 1697, 1748, 1770, 1820, 1871, 1925, 1976, 2030,
+ 2083, 2140, 2195, 2219, 2276, 2334, 2392, 2450, 2509, 2569, 2630, 2658,
+ 2720
+};
+
+static const unsigned short int hx_data_codewords_L3[] = {
+ 13, 19, 26, 30, 37, 46, 54, 63, 74, 83, 87, 97, 109, 121, 135, 147, 161,
+ 175, 191, 205, 221, 228, 245, 261, 280, 298, 317, 337, 358, 376, 397, 408,
+ 428, 452, 474, 498, 522, 545, 572, 597, 608, 635, 660, 689, 717, 746, 774,
+ 805, 817, 847, 880, 910, 943, 975, 1009, 1041, 1076, 1091, 1126, 1161, 1198,
+ 1234, 1271, 1309, 1348, 1366, 1404, 1443, 1485, 1524, 1566, 1607, 1650, 1693,
+ 1713, 1756, 1800, 1844, 1890, 1935, 1983, 2030, 2050, 2098
+};
+
+static const unsigned short int hx_data_codewords_L4[] = {
+ 9, 15, 20, 22, 27, 34, 40, 47, 54, 61, 65, 73, 81, 89, 99, 109, 119, 129,
+ 141, 153, 165, 168, 181, 195, 208, 220, 235, 251, 264, 280, 295, 302, 318,
+ 334, 352, 368, 386, 405, 424, 441, 450, 469, 490, 509, 531, 552, 574, 595, 605,
+ 627, 652, 674, 697, 721, 747, 771, 796, 809, 834, 861, 892, 914, 941, 969, 998,
+ 1012, 1040, 1069, 1099, 1130, 1160, 1191, 1222, 1253, 1269, 1300, 1334,
+ 1366, 1400, 1433, 1469, 1504, 1520, 1554
+};
+
+/* Value 'k' from Annex A */
+static const char hx_module_k[] = {
+ 0, 0, 0, 14, 16, 16, 17, 18, 19, 20,
+ 14, 15, 16, 16, 17, 17, 18, 19, 20, 20,
+ 21, 16, 17, 17, 18, 18, 19, 19, 20, 20,
+ 21, 17, 17, 18, 18, 19, 19, 19, 20, 20,
+ 17, 17, 18, 18, 18, 19, 19, 19, 17, 17,
+ 18, 18, 18, 18, 19, 19, 19, 17, 17, 18,
+ 18, 18, 18, 19, 19, 17, 17, 17, 18, 18,
+ 18, 18, 19, 19, 17, 17, 17, 18, 18, 18,
+ 18, 18, 17, 17
+};
+
+/* Value 'r' from Annex A */
+static const char hx_module_r[] = {
+ 0, 0, 0, 15, 15, 17, 18, 19, 20, 21,
+ 15, 15, 15, 17, 17, 19, 19, 19, 19, 21,
+ 21, 17, 16, 18, 17, 19, 18, 20, 19, 21,
+ 20, 17, 19, 17, 19, 17, 19, 21, 19, 21,
+ 18, 20, 17, 19, 21, 18, 20, 22, 17, 19,
+ 15, 17, 19, 21, 17, 19, 21, 18, 20, 15,
+ 17, 19, 21, 16, 18, 17, 19, 21, 15, 17,
+ 19, 21, 15, 17, 18, 20, 22, 15, 17, 19,
+ 21, 23, 17, 19
+};
+
+/* Value of 'm' from Annex A */
+static const char hx_module_m[] = {
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
+ 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,
+ 5, 5, 5, 5, 5, 5, 5, 5, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 7, 7, 7,
+ 7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9,
+ 9, 9, 10, 10
+};
+
+/* Error correction block sizes from Table D1 */
+static const unsigned short int hx_table_d1[] = {
+ /* #blocks, k, 2t, #blocks, k, 2t, #blocks, k, 2t */
+ 1, 21, 4, 0, 0, 0, 0, 0, 0, // version 1
+ 1, 17, 8, 0, 0, 0, 0, 0, 0,
+ 1, 13, 12, 0, 0, 0, 0, 0, 0,
+ 1, 9, 16, 0, 0, 0, 0, 0, 0,
+ 1, 31, 6, 0, 0, 0, 0, 0, 0, // version 2
+ 1, 25, 12, 0, 0, 0, 0, 0, 0,
+ 1, 19, 18, 0, 0, 0, 0, 0, 0,
+ 1, 15, 22, 0, 0, 0, 0, 0, 0,
+ 1, 42, 8, 0, 0, 0, 0, 0, 0, // version 3
+ 1, 34, 16, 0, 0, 0, 0, 0, 0,
+ 1, 26, 24, 0, 0, 0, 0, 0, 0,
+ 1, 20, 30, 0, 0, 0, 0, 0, 0,
+ 1, 46, 8, 0, 0, 0, 0, 0, 0, // version 4
+ 1, 38, 16, 0, 0, 0, 0, 0, 0,
+ 1, 30, 24, 0, 0, 0, 0, 0, 0,
+ 1, 22, 32, 0, 0, 0, 0, 0, 0,
+ 1, 57, 12, 0, 0, 0, 0, 0, 0, // version 5
+ 1, 49, 20, 0, 0, 0, 0, 0, 0,
+ 1, 37, 32, 0, 0, 0, 0, 0, 0,
+ 1, 14, 20, 1, 13, 22, 0, 0, 0,
+ 1, 70, 14, 0, 0, 0, 0, 0, 0, // version 6
+ 1, 58, 26, 0, 0, 0, 0, 0, 0,
+ 1, 24, 20, 1, 22, 18, 0, 0, 0,
+ 1, 16, 24, 1, 18, 26, 0, 0, 0,
+ 1, 84, 16, 0, 0, 0, 0, 0, 0, // version 7
+ 1, 70, 30, 0, 0, 0, 0, 0, 0,
+ 1, 26, 22, 1, 28, 24, 0, 0, 0,
+ 2, 14, 20, 1, 12, 20, 0, 0, 0,
+ 1, 99, 18, 0, 0, 0, 0, 0, 0, // version 8
+ 1, 40, 18, 1, 41, 18, 0, 0, 0,
+ 1, 31, 26, 1, 32, 28, 0, 0, 0,
+ 2, 16, 24, 1, 15, 22, 0, 0, 0,
+ 1, 114, 22, 0, 0, 0, 0, 0, 0, // version 9
+ 2, 48, 20, 0, 0, 0, 0, 0, 0,
+ 2, 24, 20, 1, 26, 22, 0, 0, 0,
+ 2, 18, 28, 1, 18, 26, 0, 0, 0,
+ 1, 131, 24, 0, 0, 0, 0, 0, 0, // version 10
+ 1, 52, 22, 1, 57, 24, 0, 0, 0,
+ 2, 27, 24, 1, 29, 24, 0, 0, 0,
+ 2, 21, 32, 1, 19, 30, 0, 0, 0,
+ 1, 135, 26, 0, 0, 0, 0, 0, 0, // version 11
+ 1, 56, 24, 1, 57, 24, 0, 0, 0,
+ 2, 28, 24, 1, 31, 26, 0, 0, 0,
+ 2, 22, 32, 1, 21, 32, 0, 0, 0,
+ 1, 153, 28, 0, 0, 0, 0, 0, 0, // version 12
+ 1, 62, 26, 1, 65, 28, 0, 0, 0,
+ 2, 32, 28, 1, 33, 28, 0, 0, 0,
+ 3, 17, 26, 1, 22, 30, 0, 0, 0,
+ 1, 86, 16, 1, 85, 16, 0, 0, 0, // version 13
+ 1, 71, 30, 1, 72, 30, 0, 0, 0,
+ 2, 37, 32, 1, 35, 30, 0, 0, 0,
+ 3, 20, 30, 1, 21, 32, 0, 0, 0,
+ 1, 94, 18, 1, 95, 18, 0, 0, 0, // version 14
+ 2, 51, 22, 1, 55, 24, 0, 0, 0,
+ 3, 30, 26, 1, 31, 26, 0, 0, 0,
+ 4, 18, 28, 1, 17, 24, 0, 0, 0,
+ 1, 104, 20, 1, 105, 20, 0, 0, 0, // version 15
+ 2, 57, 24, 1, 61, 26, 0, 0, 0,
+ 3, 33, 28, 1, 36, 30, 0, 0, 0,
+ 4, 20, 30, 1, 19, 30, 0, 0, 0,
+ 1, 115, 22, 1, 114, 22, 0, 0, 0, // version 16
+ 2, 65, 28, 1, 61, 26, 0, 0, 0,
+ 3, 38, 32, 1, 33, 30, 0, 0, 0,
+ 5, 19, 28, 1, 14, 24, 0, 0, 0,
+ 1, 126, 24, 1, 125, 24, 0, 0, 0, // version 17
+ 2, 70, 30, 1, 69, 30, 0, 0, 0,
+ 4, 33, 28, 1, 29, 26, 0, 0, 0,
+ 5, 20, 30, 1, 19, 30, 0, 0, 0,
+ 1, 136, 26, 1, 137, 26, 0, 0, 0, //version 18
+ 3, 56, 24, 1, 59, 26, 0, 0, 0,
+ 5, 35, 30, 0, 0, 0, 0, 0, 0,
+ 6, 18, 28, 1, 21, 28, 0, 0, 0,
+ 1, 148, 28, 1, 149, 28, 0, 0, 0, // version 19
+ 3, 61, 26, 1, 64, 28, 0, 0, 0,
+ 7, 24, 20, 1, 23, 22, 0, 0, 0,
+ 6, 20, 30, 1, 21, 32, 0, 0, 0,
+ 3, 107, 20, 0, 0, 0, 0, 0, 0, // version 20
+ 3, 65, 28, 1, 72, 30, 0, 0, 0,
+ 7, 26, 22, 1, 23, 22, 0, 0, 0,
+ 7, 19, 28, 1, 20, 32, 0, 0, 0,
+ 3, 115, 22, 0, 0, 0, 0, 0, 0, // version 21
+ 4, 56, 24, 1, 63, 28, 0, 0, 0,
+ 7, 28, 24, 1, 25, 22, 0, 0, 0,
+ 8, 18, 28, 1, 21, 22, 0, 0, 0,
+ 2, 116, 22, 1, 122, 24, 0, 0, 0, // version 22
+ 4, 56, 24, 1, 72, 30, 0, 0, 0,
+ 7, 28, 24, 1, 32, 26, 0, 0, 0,
+ 8, 18, 28, 1, 24, 30, 0, 0, 0,
+ 3, 127, 24, 0, 0, 0, 0, 0, 0, // version 23
+ 5, 51, 22, 1, 62, 26, 0, 0, 0,
+ 7, 30, 26, 1, 35, 26, 0, 0, 0,
+ 8, 20, 30, 1, 21, 32, 0, 0, 0,
+ 2, 135, 26, 1, 137, 26, 0, 0, 0, // version 24
+ 5, 56, 24, 1, 59, 26, 0, 0, 0,
+ 7, 33, 28, 1, 30, 28, 0, 0, 0,
+ 11, 16, 24, 1, 19, 26, 0, 0, 0,
+ 3, 105, 20, 1, 121, 22, 0, 0, 0, // version 25
+ 5, 61, 26, 1, 57, 26, 0, 0, 0,
+ 9, 28, 24, 1, 28, 22, 0, 0, 0,
+ 10, 19, 28, 1, 18, 30, 0, 0, 0,
+ 2, 157, 30, 1, 150, 28, 0, 0, 0, // version 26
+ 5, 65, 28, 1, 61, 26, 0, 0, 0,
+ 8, 33, 28, 1, 34, 30, 0, 0, 0,
+ 10, 19, 28, 2, 15, 26, 0, 0, 0,
+ 3, 126, 24, 1, 115, 22, 0, 0, 0, // version 27
+ 7, 51, 22, 1, 54, 22, 0, 0, 0,
+ 8, 35, 30, 1, 37, 30, 0, 0, 0,
+ 15, 15, 22, 1, 10, 22, 0, 0, 0,
+ 4, 105, 20, 1, 103, 20, 0, 0, 0, // version 28
+ 7, 56, 24, 1, 45, 18, 0, 0, 0,
+ 10, 31, 26, 1, 27, 26, 0, 0, 0,
+ 10, 17, 26, 3, 20, 28, 1, 21, 28,
+ 3, 139, 26, 1, 137, 28, 0, 0, 0, // version 29
+ 6, 66, 28, 1, 66, 30, 0, 0, 0,
+ 9, 36, 30, 1, 34, 32, 0, 0, 0,
+ 13, 19, 28, 1, 17, 32, 0, 0, 0,
+ 6, 84, 16, 1, 82, 16, 0, 0, 0, // version 30
+ 6, 70, 30, 1, 68, 30, 0, 0, 0,
+ 7, 35, 30, 3, 33, 28, 1, 32, 28,
+ 13, 20, 30, 1, 20, 28, 0, 0, 0,
+ 5, 105, 20, 1, 94, 18, 0, 0, 0, // version 31
+ 6, 74, 32, 1, 71, 30, 0, 0, 0,
+ 11, 33, 28, 1, 34, 32, 0, 0, 0,
+ 13, 19, 28, 3, 16, 26, 0, 0, 0,
+ 4, 127, 24, 1, 126, 24, 0, 0, 0, // version 32
+ 7, 66, 28, 1, 66, 30, 0, 0, 0,
+ 12, 30, 24, 1, 24, 28, 1, 24, 30,
+ 15, 19, 28, 1, 17, 32, 0, 0, 0,
+ 7, 84, 16, 1, 78, 16, 0, 0, 0, // version 33
+ 7, 70, 30, 1, 66, 28, 0, 0, 0,
+ 12, 33, 28, 1, 32, 30, 0, 0, 0,
+ 14, 21, 32, 1, 24, 28, 0, 0, 0,
+ 5, 117, 22, 1, 117, 24, 0, 0, 0, // version 34
+ 8, 66, 28, 1, 58, 26, 0, 0, 0,
+ 11, 38, 32, 1, 34, 32, 0, 0, 0,
+ 15, 20, 30, 2, 17, 26, 0, 0, 0,
+ 4, 148, 28, 1, 146, 28, 0, 0, 0, // version 35
+ 8, 68, 30, 1, 70, 24, 0, 0, 0,
+ 10, 36, 32, 3, 38, 28, 0, 0, 0,
+ 16, 19, 28, 3, 16, 26, 0, 0, 0,
+ 4, 126, 24, 2, 135, 26, 0, 0, 0, // version 36
+ 8, 70, 28, 2, 43, 26, 0, 0, 0,
+ 13, 32, 28, 2, 41, 30, 0, 0, 0,
+ 17, 19, 28, 3, 15, 26, 0, 0, 0,
+ 5, 136, 26, 1, 132, 24, 0, 0, 0, // version 37
+ 5, 67, 30, 4, 68, 28, 1, 69, 28,
+ 14, 35, 30, 1, 32, 24, 0, 0, 0,
+ 18, 18, 26, 3, 16, 28, 1, 14, 28,
+ 3, 142, 26, 3, 141, 28, 0, 0, 0, // version 38
+ 8, 70, 30, 1, 73, 32, 1, 74, 32,
+ 12, 34, 30, 3, 34, 26, 1, 35, 28,
+ 18, 21, 32, 1, 27, 30, 0, 0, 0,
+ 5, 116, 22, 2, 103, 20, 1, 102, 20, // version 39
+ 9, 74, 32, 1, 74, 30, 0, 0, 0,
+ 14, 34, 28, 2, 32, 32, 1, 32, 30,
+ 19, 21, 32, 1, 25, 26, 0, 0, 0,
+ 7, 116, 22, 1, 117, 22, 0, 0, 0, // version 40
+ 11, 65, 28, 1, 58, 24, 0, 0, 0,
+ 15, 38, 32, 1, 27, 28, 0, 0, 0,
+ 20, 20, 30, 1, 20, 32, 1, 21, 32,
+ 6, 136, 26, 1, 130, 24, 0, 0, 0, // version 41
+ 11, 66, 28, 1, 62, 30, 0, 0, 0,
+ 14, 34, 28, 3, 34, 32, 1, 30, 30,
+ 18, 20, 30, 3, 20, 28, 2, 15, 26,
+ 5, 105, 20, 2, 115, 22, 2, 116, 22, // version 42
+ 10, 75, 32, 1, 73, 32, 0, 0, 0,
+ 16, 38, 32, 1, 27, 28, 0, 0, 0,
+ 22, 19, 28, 2, 16, 30, 1, 19, 30,
+ 6, 147, 28, 1, 146, 28, 0, 0, 0, // version 43
+ 11, 66, 28, 2, 65, 30, 0, 0, 0,
+ 18, 33, 28, 2, 33, 30, 0, 0, 0,
+ 22, 21, 32, 1, 28, 30, 0, 0, 0,
+ 6, 116, 22, 3, 125, 24, 0, 0, 0, // version 44
+ 11, 75, 32, 1, 68, 30, 0, 0, 0,
+ 13, 35, 28, 6, 34, 32, 1, 30, 30,
+ 23, 21, 32, 1, 26, 30, 0, 0, 0,
+ 7, 105, 20, 4, 95, 18, 0, 0, 0, // version 45
+ 12, 67, 28, 1, 63, 30, 1, 62, 32,
+ 21, 31, 26, 2, 33, 32, 0, 0, 0,
+ 23, 21, 32, 2, 24, 30, 0, 0, 0,
+ 10, 116, 22, 0, 0, 0, 0, 0, 0, // version 46
+ 12, 74, 32, 1, 78, 30, 0, 0, 0,
+ 18, 37, 32, 1, 39, 30, 1, 41, 28,
+ 25, 21, 32, 1, 27, 28, 0, 0, 0,
+ 5, 126, 24, 4, 115, 22, 1, 114, 22, // version 47
+ 12, 67, 28, 2, 66, 32, 1, 68, 30,
+ 21, 35, 30, 1, 39, 30, 0, 0, 0,
+ 26, 21, 32, 1, 28, 28, 0, 0, 0,
+ 9, 126, 24, 1, 117, 22, 0, 0, 0, // version 48
+ 13, 75, 32, 1, 68, 30, 0, 0, 0,
+ 20, 35, 30, 3, 35, 28, 0, 0, 0,
+ 27, 21, 32, 1, 28, 30, 0, 0, 0,
+ 9, 126, 24, 1, 137, 26, 0, 0, 0, // version 49
+ 13, 71, 30, 2, 68, 32, 0, 0, 0,
+ 20, 37, 32, 1, 39, 28, 1, 38, 28,
+ 24, 20, 32, 5, 25, 28, 0, 0, 0,
+ 8, 147, 28, 1, 141, 28, 0, 0, 0, // version 50
+ 10, 73, 32, 4, 74, 30, 1, 73, 30,
+ 16, 36, 32, 6, 39, 30, 1, 37, 30,
+ 27, 21, 32, 3, 20, 26, 0, 0, 0,
+ 9, 137, 26, 1, 135, 26, 0, 0, 0, // version 51
+ 12, 70, 30, 4, 75, 32, 0, 0, 0,
+ 24, 35, 30, 1, 40, 28, 0, 0, 0,
+ 23, 20, 32, 8, 24, 30, 0, 0, 0,
+ 14, 95, 18, 1, 86, 18, 0, 0, 0, // version 52
+ 13, 73, 32, 3, 77, 30, 0, 0, 0,
+ 24, 35, 30, 2, 35, 28, 0, 0, 0,
+ 26, 21, 32, 5, 21, 30, 1, 23, 30,
+ 9, 147, 28, 1, 142, 28, 0, 0, 0, // version 53
+ 10, 73, 30, 6, 70, 32, 1, 71, 32,
+ 25, 35, 30, 2, 34, 26, 0, 0, 0,
+ 29, 21, 32, 4, 22, 30, 0, 0, 0,
+ 11, 126, 24, 1, 131, 24, 0, 0, 0, // version 54
+ 16, 74, 32, 1, 79, 30, 0, 0, 0,
+ 25, 38, 32, 1, 25, 30, 0, 0, 0,
+ 33, 21, 32, 1, 28, 28, 0, 0, 0,
+ 14, 105, 20, 1, 99, 18, 0, 0, 0, // version 55
+ 19, 65, 28, 1, 72, 28, 0, 0, 0,
+ 24, 37, 32, 2, 40, 30, 1, 41, 30,
+ 31, 21, 32, 4, 24, 32, 0, 0, 0,
+ 10, 147, 28, 1, 151, 28, 0, 0, 0, // version 56
+ 15, 71, 30, 3, 71, 32, 1, 73, 32,
+ 24, 37, 32, 3, 38, 30, 1, 39, 30,
+ 36, 19, 30, 3, 29, 26, 0, 0, 0,
+ 15, 105, 20, 1, 99, 18, 0, 0, 0, // version 57
+ 19, 70, 30, 1, 64, 28, 0, 0, 0,
+ 27, 38, 32, 2, 25, 26, 0, 0, 0,
+ 38, 20, 30, 2, 18, 28, 0, 0, 0,
+ 14, 105, 20, 1, 113, 22, 1, 114, 22, // version 58
+ 17, 67, 30, 3, 92, 32, 0, 0, 0,
+ 30, 35, 30, 1, 41, 30, 0, 0, 0,
+ 36, 21, 32, 1, 26, 30, 1, 27, 30,
+ 11, 146, 28, 1, 146, 26, 0, 0, 0, // version 59
+ 20, 70, 30, 1, 60, 26, 0, 0, 0,
+ 29, 38, 32, 1, 24, 32, 0, 0, 0,
+ 40, 20, 30, 2, 17, 26, 0, 0, 0,
+ 3, 137, 26, 1, 136, 26, 10, 126, 24, // version 60
+ 22, 65, 28, 1, 75, 30, 0, 0, 0,
+ 30, 37, 32, 1, 51, 30, 0, 0, 0,
+ 42, 20, 30, 1, 21, 30, 0, 0, 0,
+ 12, 126, 24, 2, 118, 22, 1, 116, 22, // version 61
+ 19, 74, 32, 1, 74, 30, 1, 72, 28,
+ 30, 38, 32, 2, 29, 30, 0, 0, 0,
+ 39, 20, 32, 2, 37, 26, 1, 38, 26,
+ 12, 126, 24, 3, 136, 26, 0, 0, 0, // version 62
+ 21, 70, 30, 2, 65, 28, 0, 0, 0,
+ 34, 35, 30, 1, 44, 32, 0, 0, 0,
+ 42, 20, 30, 2, 19, 28, 2, 18, 28,
+ 12, 126, 24, 3, 117, 22, 1, 116, 22, // version 63
+ 25, 61, 26, 2, 62, 28, 0, 0, 0,
+ 34, 35, 30, 1, 40, 32, 1, 41, 32,
+ 45, 20, 30, 1, 20, 32, 1, 21, 32,
+ 15, 105, 20, 2, 115, 22, 2, 116, 22, // version 64
+ 25, 65, 28, 1, 72, 28, 0, 0, 0,
+ 18, 35, 30, 17, 37, 32, 1, 50, 32,
+ 42, 20, 30, 6, 19, 28, 1, 15, 28,
+ 19, 105, 20, 1, 101, 20, 0, 0, 0, // version 65
+ 33, 51, 22, 1, 65, 22, 0, 0, 0,
+ 40, 33, 28, 1, 28, 28, 0, 0, 0,
+ 49, 20, 30, 1, 18, 28, 0, 0, 0,
+ 18, 105, 20, 2, 117, 22, 0, 0, 0, // version 66
+ 26, 65, 28, 1, 80, 30, 0, 0, 0,
+ 35, 35, 30, 3, 35, 28, 1, 36, 28,
+ 52, 18, 28, 2, 38, 30, 0, 0, 0,
+ 26, 84, 16, 0, 0, 0, 0, 0, 0, // version 67
+ 26, 70, 30, 0, 0, 0, 0, 0, 0,
+ 45, 31, 26, 1, 9, 26, 0, 0, 0,
+ 52, 20, 30, 0, 0, 0, 0, 0, 0,
+ 16, 126, 24, 1, 114, 22, 1, 115, 22, // version 68
+ 23, 70, 30, 3, 65, 28, 1, 66, 28,
+ 40, 35, 30, 1, 43, 30, 0, 0, 0,
+ 46, 20, 30, 7, 19, 28, 1, 16, 28,
+ 19, 116, 22, 1, 105, 22, 0, 0, 0, // version 69
+ 20, 70, 30, 7, 66, 28, 1, 63, 28,
+ 40, 35, 30, 1, 42, 32, 1, 43, 32,
+ 54, 20, 30, 1, 19, 30, 0, 0, 0,
+ 17, 126, 24, 2, 115, 22, 0, 0, 0, // version 70
+ 24, 70, 30, 4, 74, 32, 0, 0, 0,
+ 48, 31, 26, 2, 18, 26, 0, 0, 0,
+ 54, 19, 28, 6, 15, 26, 1, 14, 26,
+ 29, 84, 16, 0, 0, 0, 0, 0, 0, // version 71
+ 29, 70, 30, 0, 0, 0, 0, 0, 0,
+ 6, 34, 30, 3, 36, 30, 38, 33, 28,
+ 58, 20, 30, 0, 0, 0, 0, 0, 0,
+ 16, 147, 28, 1, 149, 28, 0, 0, 0, // version 72
+ 31, 66, 28, 1, 37, 26, 0, 0, 0,
+ 48, 33, 28, 1, 23, 26, 0, 0, 0,
+ 53, 20, 30, 6, 19, 28, 1, 17, 28,
+ 20, 115, 22, 2, 134, 24, 0, 0, 0, // verdion 73
+ 29, 66, 28, 2, 56, 26, 2, 57, 26,
+ 45, 36, 30, 2, 15, 28, 0, 0, 0,
+ 59, 20, 30, 2, 21, 32, 0, 0, 0,
+ 17, 147, 28, 1, 134, 26, 0, 0, 0, // version 74
+ 26, 70, 30, 5, 75, 32, 0, 0, 0,
+ 47, 35, 30, 1, 48, 32, 0, 0, 0,
+ 64, 18, 28, 2, 33, 30, 1, 35, 30,
+ 22, 115, 22, 1, 133, 24, 0, 0, 0, // version 75
+ 33, 65, 28, 1, 74, 28, 0, 0, 0,
+ 43, 36, 30, 5, 27, 28, 1, 30, 28,
+ 57, 20, 30, 5, 21, 32, 1, 24, 32,
+ 18, 136, 26, 2, 142, 26, 0, 0, 0, // version 76
+ 33, 66, 28, 2, 49, 26, 0, 0, 0,
+ 48, 35, 30, 2, 38, 28, 0, 0, 0,
+ 64, 20, 30, 1, 20, 32, 0, 0, 0,
+ 19, 126, 24, 2, 135, 26, 1, 136, 26, // version 77
+ 32, 66, 28, 2, 55, 26, 2, 56, 26,
+ 49, 36, 30, 2, 18, 32, 0, 0, 0,
+ 65, 18, 28, 5, 27, 30, 1, 29, 30,
+ 20, 137, 26, 1, 130, 26, 0, 0, 0, // version 78
+ 30, 75, 32, 2, 71, 32, 0, 0, 0,
+ 46, 35, 30, 6, 39, 32, 0, 0, 0,
+ 3, 12, 30, 70, 19, 28, 0, 0, 0,
+ 20, 147, 28, 0, 0, 0, 0, 0, 0, // version 79
+ 35, 70, 30, 0, 0, 0, 0, 0, 0,
+ 49, 35, 30, 5, 35, 28, 0, 0, 0,
+ 70, 20, 30, 0, 0, 0, 0, 0, 0,
+ 21, 136, 26, 1, 155, 28, 0, 0, 0, // version 80
+ 34, 70, 30, 1, 64, 28, 1, 65, 28,
+ 54, 35, 30, 1, 45, 30, 0, 0, 0,
+ 68, 20, 30, 3, 18, 28, 1, 19, 28,
+ 19, 126, 24, 5, 115, 22, 1, 114, 22, // version 81
+ 33, 70, 30, 3, 65, 28, 1, 64, 28,
+ 52, 35, 30, 3, 41, 32, 1, 40, 32,
+ 67, 20, 30, 5, 21, 32, 1, 24, 32,
+ 2, 150, 28, 21, 136, 26, 0, 0, 0, // version 82
+ 32, 70, 30, 6, 65, 28, 0, 0, 0,
+ 52, 38, 32, 2, 27, 32, 0, 0, 0,
+ 73, 20, 30, 2, 22, 32, 0, 0, 0,
+ 21, 126, 24, 4, 136, 26, 0, 0, 0, // version 83
+ 30, 74, 32, 6, 73, 30, 0, 0, 0,
+ 54, 35, 30, 4, 40, 32, 0, 0, 0,
+ 75, 20, 30, 1, 20, 28, 0, 0, 0,
+ 30, 105, 20, 1, 114, 22, 0, 0, 0, // version 84
+ 3, 45, 22, 55, 47, 20, 0, 0, 0,
+ 2, 26, 26, 62, 33, 28, 0, 0, 0,
+ 79, 18, 28, 4, 33, 30, 0, 0, 0
+};
diff --git a/backend/imail.c b/backend/imail.c
new file mode 100644
index 0000000..1b90efe
--- /dev/null
+++ b/backend/imail.c
@@ -0,0 +1,442 @@
+/* imail.c - Handles Intelligent Mail (aka OneCode) for USPS */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/* The function "USPS_MSB_Math_CRC11GenerateFrameCheckSequence"
+ is Copyright (C) 2006 United States Postal Service */
+
+#include <stdio.h>
+#include "common.h"
+#include "large.h"
+
+#define SODIUM "0123456789-"
+
+/* The following lookup tables were generated using the code in Appendix C */
+
+static const 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 const 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 const unsigned short 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 bits 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)
+ ***************************************************************************/
+static 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;
+}
+
+INTERNAL 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], temp[2];
+ large_int accum;
+ large_int byte_array_reg;
+ unsigned char byte_array[13];
+ unsigned short usps_crc;
+ int codeword[10];
+ unsigned short characters[10];
+ short int bar_map[130];
+ int zip_len, len;
+
+ if (length > 32) {
+ strcpy(symbol->errtxt, "450: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(SODIUM, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "451: 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, "452: Invalid length tracking code");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ if (tracker[1] > '4') {
+ strcpy(symbol->errtxt, "454: Invalid Barcode Identifier");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ zip_len = strlen(zip);
+ if (zip_len != 0 && zip_len != 5 && zip_len != 9 && zip_len != 11) {
+ strcpy(symbol->errtxt, "453: Invalid ZIP code");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ /* *** Step 1 - Conversion of Data Fields into Binary Data *** */
+
+ /* Routing code first */
+
+ large_load_str_u64(&accum, (unsigned char *) zip, zip_len);
+
+ /* add weight to routing code */
+ if (zip_len > 9) {
+ large_add_u64(&accum, 1000100001);
+ } else if (zip_len > 5) {
+ large_add_u64(&accum, 100001);
+ } else if (zip_len > 0) {
+ large_add_u64(&accum, 1);
+ }
+
+ /* tracking code */
+
+ /* multiply by 10 */
+ large_mul_u64(&accum, 10);
+
+ /* add first digit of tracker */
+ large_add_u64(&accum, ctoi(tracker[0]));
+
+ /* multiply by 5 */
+ large_mul_u64(&accum, 5);
+
+ /* add second digit */
+ large_add_u64(&accum, ctoi(tracker[1]));
+
+ /* and then the rest */
+
+ for (read = 2, len = strlen(tracker); read < len; read++) {
+
+ large_mul_u64(&accum, 10);
+ large_add_u64(&accum, ctoi(tracker[read]));
+ }
+
+ /* *** Step 2 - Generation of 11-bit CRC on Binary Data *** */
+
+ large_load(&byte_array_reg, &accum);
+
+ large_unset_bit(&byte_array_reg, 102);
+ large_unset_bit(&byte_array_reg, 103);
+
+ large_uchar_array(&byte_array_reg, byte_array, 13, 8 /*bits*/);
+
+ usps_crc = USPS_MSB_Math_CRC11GenerateFrameCheckSequence(byte_array);
+
+ /* *** Step 3 - Conversion from Binary Data to Codewords *** */
+
+ /* start with codeword J which is base 636 */
+ codeword[9] = large_div_u64(&accum, 636);
+
+ /* then codewords I to B with base 1365 */
+
+ for (j = 8; j > 0; j--) {
+ codeword[j] = large_div_u64(&accum, 1365);
+ }
+
+ codeword[0] = large_lo(&accum);
+
+ /* *** Step 4 - Inserting Additional Information into Codewords *** */
+
+ codeword[9] = codeword[9] * 2;
+
+ if (usps_crc >= 1024) {
+ codeword[0] += 659;
+ }
+
+ /* *** 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];
+ }
+ }
+
+ for (i = 0; i < 10; i++) {
+ if (usps_crc & (1 << i)) {
+ characters[i] = 0x1FFF - characters[i];
+ }
+ }
+
+ /* *** Step 6 - Conversion from Characters to the Intelligent Mail Barcode *** */
+ for (i = 0; i < 10; i++) {
+ for (j = 0; j < 13; j++) {
+ if (characters[i] & (1 << j)) {
+ bar_map[AppxD_IV[(13 * i) + j] - 1] = 1;
+ } else {
+ bar_map[AppxD_IV[(13 * i) + j] - 1] = 0;
+ }
+ }
+ }
+
+ 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);
+ strcat(data_pattern, temp);
+ }
+
+ /* Translate 4-state data pattern to symbol */
+ read = 0;
+ for (i = 0, len = strlen(data_pattern); i < len; 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] = 3;
+ symbol->row_height[1] = 2;
+ symbol->row_height[2] = 3;
+
+ symbol->rows = 3;
+ symbol->width = read - 1;
+ return error_number;
+}
diff --git a/backend/large.c b/backend/large.c
index ff44ecd..6f7d7af 100644
--- a/backend/large.c
+++ b/backend/large.c
@@ -2,7 +2,7 @@
/*
libzint - the open source barcode library
- Copyright (C) 2008 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -28,211 +28,290 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
+/* `large_mul_u64()` and `large_div_u64()` are adapted from articles by F. W. Jacob
+ * https://www.codeproject.com/Tips/618570/UInt-Multiplication-Squaring
+ * "This article, along with any associated source code and files, is licensed under The BSD License"
+ * http://www.codeproject.com/Tips/785014/UInt-Division-Modulus
+ * "This article, along with any associated source code and files, is licensed under The BSD License"
+ *
+ * These in turn are based on Hacker's Delight (2nd Edition, 2012) by Henry S. Warren, Jr.
+ * "You are free to use, copy, and distribute any of the code on this web site, whether modified by you or not."
+ * https://web.archive.org/web/20190716204559/http://www.hackersdelight.org/permissions.htm
+ *
+ * `clz_u64()` and other bits and pieces are adapted from r128.h by Alan Hickman (fahickman)
+ * https://github.com/fahickman/r128/blob/master/r128.h
+ * "R128 is released into the public domain. See LICENSE for details." LICENSE is The Unlicense.
+ */
#include <stdio.h>
-#include <string.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
#include "common.h"
#include "large.h"
-static const 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;
- }
- }
+#define MASK32 0xFFFFFFFF
+
+/* Convert decimal string `s` of (at most) length `length` to 64-bit and place in 128-bit `t` */
+INTERNAL void large_load_str_u64(large_int *t, const unsigned char *s, int length) {
+ uint64_t val = 0;
+ const unsigned char *se = s + length;
+ for (; s < se && *s >= '0' && *s <= '9'; s++) {
+ val *= 10;
+ val += *s - '0';
+ }
+ t->lo = val;
+ t->hi = 0;
}
-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);
+/* Add 128-bit `s` to 128-bit `t` */
+INTERNAL void large_add(large_int *t, const large_int *s) {
+ t->lo += s->lo;
+ t->hi += s->hi + (t->lo < s->lo);
}
-void shiftdown(short int buffer[])
-{
- int i;
-
- buffer[102] = 0;
- buffer[103] = 0;
+/* Add 64-bit `s` to 128-bit `t` */
+INTERNAL void large_add_u64(large_int *t, uint64_t s) {
+ t->lo += s;
+ if (t->lo < s) {
+ t->hi++;
+ }
+}
- for(i = 0; i < 102; i++) {
- buffer[i] = buffer[i + 1];
- }
+/* Subtract 64-bit `s` from 128-bit `t` */
+INTERNAL void large_sub_u64(large_int *t, uint64_t s) {
+ uint64_t r = t->lo - s;
+ if (r > t->lo) {
+ t->hi--;
+ }
+ t->lo = r;
}
-void shiftup(short int buffer[])
-{
- int i;
-
- for(i = 102; i > 0; i--) {
- buffer[i] = buffer[i - 1];
- }
-
- buffer[0] = 0;
+/* Multiply 128-bit `t` by 64-bit `s`
+ * See Jacob `mult64to128()` and Warren Section 8-2
+ * Note '0' denotes low 32-bits, '1' high 32-bits
+ * if p00 == s0 * tlo0
+ * k00 == carry of p00
+ * p01 == s0 * tlo1
+ * k01 == carry of (p01 + k00)
+ * p10 == s1 * tlo0
+ * k10 == carry of p10
+ * p11 == s1 * tlo1 (unmasked, i.e. including unshifted carry if any)
+ * then t->lo == (p01 + p10 + k00) << 32 + p00
+ * and t->hi == p11 + k10 + k01 + thi * s
+ *
+ * (thi) tlo1 tlo0
+ * x s1 s0
+ * -------------------------
+ * p00
+ * k01 p01 + k00
+ * p10
+ * p11 + k10
+ */
+INTERNAL void large_mul_u64(large_int *t, uint64_t s) {
+ uint64_t thi = t->hi;
+ uint64_t tlo0 = t->lo & MASK32;
+ uint64_t tlo1 = t->lo >> 32;
+
+ uint64_t s0 = s & MASK32;
+ uint64_t s1 = s >> 32;
+
+ uint64_t tmp = s0 * tlo0; /* p00 (unmasked) */
+ uint64_t p00 = tmp & MASK32;
+ uint64_t k10;
+
+ tmp = (s1 * tlo0) + (tmp >> 32); /* (p10 + k00) (p10 unmasked) */
+ k10 = tmp >> 32;
+
+ tmp = (s0 * tlo1) + (tmp & MASK32); /* (p01 + p10 + k00) (p01 unmasked) */
+
+ t->lo = (tmp << 32) + p00; /* (p01 + p10 + k00) << 32 + p00 (note any carry from unmasked p01 shifted out) */
+ t->hi = (s1 * tlo1) + k10 + (tmp >> 32) + thi * s; /* p11 + k10 + k01 + thi * s */
}
-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;
+/* Count leading zeroes. See Hickman `r128__clz64()` */
+STATIC_UNLESS_ZINT_TEST int clz_u64(uint64_t x) {
+ uint64_t n = 64, y;
+ y = x >> 32; if (y) { n -= 32; x = y; }
+ y = x >> 16; if (y) { n -= 16; x = y; }
+ y = x >> 8; if (y) { n -= 8; x = y; }
+ y = x >> 4; if (y) { n -= 4; x = y; }
+ y = x >> 2; if (y) { n -= 2; x = y; }
+ y = x >> 1; if (y) { n -= 1; x = y; }
+ return (int) (n - x);
}
-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);
- }
+/* Divide 128-bit dividend `t` by 64-bit divisor `v`
+ * See Jacob `divmod128by128/64()` and Warren Section 9–2 (divmu64.c.txt)
+ * Note digits are 32-bit parts */
+INTERNAL uint64_t large_div_u64(large_int *t, uint64_t v) {
+ const uint64_t b = 0x100000000; /* Number base (2**32) */
+ uint64_t qhi = 0; /* High digit of returned quotient */
+
+ uint64_t tnhi, tnlo, tnlo1, tnlo0, vn1, vn0; /* Normalized forms of (parts of) t and v */
+ uint64_t rnhilo1; /* Remainder after dividing 1st 3 digits of t by v */
+ uint64_t qhat1, qhat0; /* Estimated quotient digits */
+ uint64_t rhat; /* Remainder of estimated quotient digit */
+ uint64_t tmp;
+ int norm_shift;
+
+ /* Deal with single-digit (i.e. 32-bit) divisor here */
+ if (v < b) {
+ qhi = t->hi / v;
+ tmp = ((t->hi - qhi * v) << 32) + (t->lo >> 32); /* k * b + tlo1 */
+ qhat1 = tmp / v;
+ tmp = ((tmp - qhat1 * v) << 32) + (t->lo & MASK32); /* k * b + tlo0 */
+ qhat0 = tmp / v;
+ t->lo = (qhat1 << 32) | qhat0;
+ t->hi = qhi;
+ return tmp - qhat0 * v;
+ }
+
+ /* Main algorithm requires t->hi < v */
+ if (t->hi >= v) {
+ qhi = t->hi / v;
+ t->hi %= v;
+ }
+
+ /* Normalize by shifting v left just enough so that its high-order
+ * bit is on, and shift t left the same amount. Note don't need extra
+ * high-end digit for dividend as t->hi < v */
+
+ norm_shift = clz_u64(v);
+ v <<= norm_shift;
+ vn1 = v >> 32;
+ vn0 = v & MASK32;
+
+ if (norm_shift > 0) {
+ tnhi = (t->hi << norm_shift) | (t->lo >> (64 - norm_shift));
+ tnlo = t->lo << norm_shift;
+ } else {
+ tnhi = t->hi;
+ tnlo = t->lo;
+ }
+
+ tnlo1 = tnlo >> 32;
+ tnlo0 = tnlo & MASK32;
+
+ /* Compute qhat1 estimate */
+
+ qhat1 = tnhi / vn1; /* Divide first digit of v into first 2 digits of t */
+ rhat = tnhi % vn1;
+
+ /* Loop until qhat1 one digit and <= (rhat * b + 3rd digit of t) / vn0 */
+ for (tmp = qhat1 * vn0; qhat1 >= b || tmp > (rhat << 32) + tnlo1; tmp -= vn0) {
+ --qhat1;
+ rhat += vn1;
+ if (rhat >= b) { /* Must check here as (rhat << 32) would overflow */
+ break; /* qhat1 * vn0 < b * b (since vn0 < b) */
+ }
+ }
+ /* Note qhat1 will be exact as have fully divided by 2-digit divisor
+ * (can only be too high by 1 (and require "add back" step) if divisor at least 3 digits) */
+
+ rnhilo1 = (tnhi << 32) + tnlo1 - (qhat1 * v); /* Note high digit (if any) of both tnhi and (qhat1 * v) shifted out */
+
+ /* Compute qhat0 estimate */
+
+ qhat0 = rnhilo1 / vn1; /* Divide first digit of v into 2-digit remains of first 3 digits of t */
+ rhat = rnhilo1 % vn1;
+
+ /* Loop until qhat0 one digit and <= (rhat * b + 4th digit of t) / vn0 */
+ for (tmp = qhat0 * vn0; qhat0 >= b || tmp > (rhat << 32) + tnlo0; tmp -= vn0) {
+ --qhat0;
+ rhat += vn1;
+ if (rhat >= b) {
+ break;
+ }
+ }
+ /* Similarly qhat0 will be exact */
+
+ t->lo = (qhat1 << 32) | qhat0;
+ t->hi = qhi;
+
+ /* Unnormalize remainder */
+ return ((rnhilo1 << 32) + tnlo0 - (qhat0 * v)) >> norm_shift;
+}
+
+/* Unset a bit (zero-based) */
+INTERNAL void large_unset_bit(large_int *t, int bit) {
+ if (bit < 64) {
+ t->lo &= ~(((uint64_t) 1) << bit);
+ } else if (bit < 128) {
+ t->hi &= ~(((uint64_t) 1) << (bit - 64));
+ }
+}
+
+/* Ouput large_int into an unsigned int array of size `size`, each element containing `bits` bits */
+INTERNAL void large_uint_array(const large_int *t, unsigned int *uint_array, int size, int bits) {
+ int i, j;
+ uint64_t mask;
+ if (bits <= 0) {
+ bits = 8;
+ } else if (bits > 32) {
+ bits = 32;
+ }
+ mask = ~(((uint64_t) -1) << bits);
+ for (i = 0, j = 0; i < size && j < 64; i++, j += bits) {
+ uint_array[size - 1 - i] = (t->lo >> j) & mask; /* Little-endian order */
+ }
+ if (i < size) {
+ if (j != 64) {
+ j -= 64;
+ /* (first j bits of t->hi) << (bits - j) | (last (bits - j) bits of t->lo) */
+ uint_array[size - i] = ((t->hi & ~((((uint64_t) -1) << j))) << (bits - j)) | (t->lo >> (64 - (bits - j)) & mask);
+ } else {
+ j = 0;
+ }
+ for (; i < size && j < 64; i++, j += bits) {
+ uint_array[size - 1 - i] = (t->hi >> j) & mask;
+ }
+ if (i < size && j != 128) {
+ uint_array[size - 1 - i] = t->hi >> (j - bits) & mask;
+ }
+ }
}
-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");
+/* As `large_uint_array()` above, except output to unsigned char array */
+INTERNAL void large_uchar_array(const large_int *t, unsigned char *uchar_array, int size, int bits) {
+ int i;
+#ifndef _MSC_VER
+ unsigned int uint_array[size ? size : 1]; /* Avoid run-time warning if size is 0 */
+#else
+ unsigned int *uint_array = (unsigned int *) _alloca((size ? size : 1) * sizeof(unsigned int));
+#endif
+
+ large_uint_array(t, uint_array, size, bits);
+
+ for (i = 0; i < size; i++) {
+ uchar_array[i] = uint_array[i];
+ }
+}
+
+/* Output formatted large_int to stdout */
+INTERNAL void large_print(large_int *t) {
+ char buf[35]; /* 2 (0x) + 32 (hex) + 1 */
+
+ puts(large_dump(t, buf));
+}
+
+/* Format large_int into buffer, which should be at least 35 chars in size */
+INTERNAL char *large_dump(large_int *t, char *buf) {
+ unsigned int tlo1 = large_lo(t) >> 32;
+ unsigned int tlo0 = large_lo(t) & MASK32;
+ unsigned int thi1 = large_hi(t) >> 32;
+ unsigned int thi0 = large_hi(t) & MASK32;
+
+ if (thi1) {
+ sprintf(buf, "0x%X%08X%08X%08X", thi1, thi0, tlo1, tlo0);
+ } else if (thi0) {
+ sprintf(buf, "0x%X%08X%08X", thi0, tlo1, tlo0);
+ } else if (tlo1) {
+ sprintf(buf, "0x%X%08X", tlo1, tlo0);
+ } else {
+ sprintf(buf, "0x%X", tlo0);
+ }
+ return buf;
}
diff --git a/backend/large.h b/backend/large.h
index 74f9a61..06325f5 100644
--- a/backend/large.h
+++ b/backend/large.h
@@ -2,7 +2,7 @@
/*
libzint - the open source barcode library
- Copyright (C) 2008 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -29,20 +29,49 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
+/* vim: set ts=4 sw=4 et : */
#ifndef __LARGE_H
#define __LARGE_H
+#ifndef _MSC_VER
+#include <stdint.h>
+#else
+#include "ms_stdint.h"
+#endif
+
#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[]);
+typedef struct { uint64_t lo; uint64_t hi; } large_int;
+
+#define large_lo(s) ((s)->lo)
+#define large_hi(s) ((s)->hi)
+
+/* Set 128-bit `t` from 128-bit `s` */
+#define large_load(t, s) do { (t)->lo = (s)->lo; (t)->hi = (s)->hi; } while (0)
+
+/* Set 128-bit `t` from 64-bit `s` */
+#define large_load_u64(t, s) do { (t)->lo = (s); (t)->hi = 0; } while (0)
+
+INTERNAL void large_load_str_u64(large_int *t, const unsigned char *s, int length);
+
+INTERNAL void large_add(large_int *t, const large_int *s);
+INTERNAL void large_add_u64(large_int *t, uint64_t s);
+
+INTERNAL void large_sub_u64(large_int *t, uint64_t s);
+
+INTERNAL void large_mul_u64(large_int *t, uint64_t s);
+
+INTERNAL uint64_t large_div_u64(large_int *t, uint64_t v);
+
+INTERNAL void large_unset_bit(large_int *t, int bit);
+
+INTERNAL void large_uint_array(const large_int *t, unsigned int *uint_array, int size, int bits);
+INTERNAL void large_uchar_array(const large_int *t, unsigned char *uchar_array, int size, int bits);
+
+INTERNAL void large_print(large_int *t);
+INTERNAL char *large_dump(large_int *t, char *buf);
#ifdef __cplusplus
}
diff --git a/backend/library.c b/backend/library.c
index cbedb1f..a9714af 100644
--- a/backend/library.c
+++ b/backend/library.c
@@ -1,7 +1,7 @@
/* library.c - external functions of libzint
libzint - the open source barcode library
- Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -27,696 +27,1536 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <errno.h>
#ifdef _MSC_VER
-#include <malloc.h>
+#include <malloc.h>
#endif
#include "common.h"
#include "gs1.h"
-#define TECHNETIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"
-
-struct zint_symbol *ZBarcode_Create()
-{
- struct zint_symbol *symbol = (struct zint_symbol*)calloc(1, sizeof(struct zint_symbol));
-
- if (!symbol) return NULL;
-
- symbol->symbology = BARCODE_CODE128;
- strcpy(symbol->fgcolour, "000000");
- strcpy(symbol->bgcolour, "ffffff");
- strcpy(symbol->outfile, "out.png");
- symbol->scale = 1.0;
- symbol->option_1 = -1;
- symbol->option_3 = 928; // PDF_MAX
- symbol->show_hrt = 1; // Show human readable text
- return symbol;
+#define TECHNETIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%"
+
+struct zint_symbol *ZBarcode_Create() {
+ struct zint_symbol *symbol;
+
+ 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 = 0;
+ symbol->show_hrt = 1; // Show human readable text
+ symbol->fontsize = 8;
+ symbol->input_mode = DATA_MODE;
+ symbol->bitmap = NULL;
+ symbol->bitmap_width = 0;
+ symbol->bitmap_height = 0;
+ symbol->eci = 0; // Default 0 uses ECI 3
+ symbol->dot_size = 4.0 / 5.0;
+ symbol->vector = NULL;
+ symbol->debug = 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;
+INTERNAL void vector_free(struct zint_symbol *symbol); /* Free vector structures */
+
+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;
+ memset(symbol->text, 0, sizeof(symbol->text));
+ symbol->errtxt[0] = '\0';
+ if (symbol->bitmap != NULL) {
+ free(symbol->bitmap);
+ symbol->bitmap = NULL;
+ }
+ symbol->bitmap_width = 0;
+ symbol->bitmap_height = 0;
+
+ // If there is a rendered version, ensure its memory is released
+ vector_free(symbol);
}
-void ZBarcode_Delete(struct zint_symbol *symbol)
-{
- if (symbol->bitmap != NULL)
- free(symbol->bitmap);
-
- // If there is a rendered version, ensure it's memory is released
- if (symbol->rendered != NULL) {
- struct zint_render_line *line, *l;
- struct zint_render_string *string, *s;
-
- // Free lines
- line = symbol->rendered->lines;
- while(line) {
- l = line;
- line = line->next;
- free(l);
- }
- // Free Strings
- string = symbol->rendered->strings;
- while (string) {
- s = string;
- string = string->next;
- free(s->text);
- free(s);
- }
-
- // Free Render
- free(symbol->rendered);
- }
- free(symbol);
+void ZBarcode_Delete(struct zint_symbol *symbol) {
+ if (symbol->bitmap != NULL)
+ free(symbol->bitmap);
+
+ // If there is a rendered version, ensure its memory is released
+ vector_free(symbol);
+
+ 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 interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Interleaved */
-extern int code_128(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 128 and NVE-18 */
-extern int qr_code(struct zint_symbol *symbol, unsigned char source[], int length); /* QR Code */
-
-extern int render_plot(struct zint_symbol *symbol, float width, float height);
-
-extern int bmp_handle(struct zint_symbol *symbol, int rotate_angle);
-
-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);
- }
+INTERNAL int get_best_eci(unsigned char source[], size_t length); /* Calculate suitable ECI mode */
+INTERNAL int utf_to_eci(const int eci, const unsigned char source[], unsigned char dest[], size_t *length); /* Convert Unicode to other encodings */
+
+
+INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN system barcodes */
+INTERNAL int c39(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* Code 3 from 9 (or Code 39) */
+INTERNAL int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmazentral Nummer (PZN) */
+INTERNAL int ec39(struct zint_symbol *symbol, unsigned char source[], int length); /* Extended Code 3 from 9 (or Code 39+) */
+INTERNAL int codabar(struct zint_symbol *symbol, unsigned char source[], int length); /* Codabar - a simple substitution cipher */
+INTERNAL int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Standard (& Matrix) */
+INTERNAL int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Industrial */
+INTERNAL int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 IATA */
+INTERNAL int interleaved_two_of_five(struct zint_symbol *symbol, const unsigned char source[], size_t length); /* Code 2 of 5 Interleaved */
+INTERNAL int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 2 of 5 Data Logic */
+INTERNAL int itf14(struct zint_symbol *symbol, unsigned char source[], int length); /* ITF-14 */
+INTERNAL int dpleit(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Leitcode */
+INTERNAL int dpident(struct zint_symbol *symbol, unsigned char source[], int length); /* Deutsche Post Identcode */
+INTERNAL int c93(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 93 - a re-working of Code 39+, generates 2 check digits */
+INTERNAL int code_128(struct zint_symbol *symbol, const unsigned char source[], const size_t length); /* Code 128 and NVE-18 */
+INTERNAL int ean_128(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* EAN-128 (GS1-128) */
+INTERNAL int code_11(struct zint_symbol *symbol, unsigned char source[], int length); /* Code 11 */
+INTERNAL int msi_handle(struct zint_symbol *symbol, unsigned char source[], int length); /* MSI Plessey */
+INTERNAL int telepen(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* Telepen ASCII */
+INTERNAL int telepen_num(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* Telepen Numeric */
+INTERNAL int plessey(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* Plessey Code */
+INTERNAL int pharma_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode One Track */
+INTERNAL int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length); /* Flattermarken */
+INTERNAL int fim(struct zint_symbol *symbol, unsigned char source[], int length); /* Facing Identification Mark */
+INTERNAL int pharma_two(struct zint_symbol *symbol, unsigned char source[], int length); /* Pharmacode Two Track */
+INTERNAL int post_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* Postnet */
+INTERNAL int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* PLANET */
+INTERNAL int imail(struct zint_symbol *symbol, unsigned char source[], int length); /* Intelligent Mail (aka USPS OneCode) */
+INTERNAL int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length); /* RM4SCC */
+INTERNAL int australia_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Australia Post 4-state */
+INTERNAL int code16k(struct zint_symbol *symbol, unsigned char source[],const size_t length); /* Code 16k */
+INTERNAL int pdf417enc(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* PDF417 */
+INTERNAL int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size_t length); /* Micro PDF417 */
+INTERNAL int maxicode(struct zint_symbol *symbol, unsigned char source[], int length); /* Maxicode */
+INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS-14 */
+INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Limited */
+INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int length); /* RSS Expanded */
+INTERNAL int composite(struct zint_symbol *symbol, unsigned char source[], int length); /* Composite Symbology */
+INTERNAL int kix_code(struct zint_symbol *symbol, unsigned char source[], int length); /* TNT KIX Code */
+INTERNAL int aztec(struct zint_symbol *symbol, unsigned char source[], const size_t length); /* Aztec Code */
+INTERNAL int code32(struct zint_symbol *symbol, unsigned char source[], int length); /* Italian Pharmacode */
+INTERNAL int daft_code(struct zint_symbol *symbol, unsigned char source[], int length); /* DAFT Code */
+INTERNAL int ean_14(struct zint_symbol *symbol, unsigned char source[], int length); /* EAN-14 */
+INTERNAL int nve_18(struct zint_symbol *symbol, unsigned char source[], int length); /* NVE-18 */
+INTERNAL int microqr(struct zint_symbol *symbol, const unsigned char source[], size_t length); /* Micro QR Code */
+INTERNAL int aztec_runes(struct zint_symbol *symbol, unsigned char source[], int length); /* Aztec Runes */
+INTERNAL int korea_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Korea Post */
+INTERNAL int japan_post(struct zint_symbol *symbol, unsigned char source[], int length); /* Japanese Post */
+INTERNAL int code_49(struct zint_symbol *symbol, unsigned char source[], const int length); /* Code 49 */
+INTERNAL int channel_code(struct zint_symbol *symbol, unsigned char source[], int length); /* Channel Code */
+INTERNAL int code_one(struct zint_symbol *symbol, unsigned char source[], int length); /* Code One */
+INTERNAL int grid_matrix(struct zint_symbol *symbol, const unsigned char source[], size_t length); /* Grid Matrix */
+INTERNAL int han_xin(struct zint_symbol * symbol, const unsigned char source[], size_t length); /* Han Xin */
+INTERNAL int dotcode(struct zint_symbol * symbol, const unsigned char source[], int length); /* DotCode */
+INTERNAL int codablock(struct zint_symbol * symbol, const unsigned char source[], const size_t length); /* Codablock */
+INTERNAL int upnqr(struct zint_symbol *symbol, const unsigned char source[], size_t length); /* UPNQR */
+INTERNAL int qr_code(struct zint_symbol *symbol, const unsigned char source[], size_t length); /* QR Code */
+INTERNAL int dmatrix(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length); /* Data Matrix (IEC16022) */
+INTERNAL int vin(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length); /* VIN Code (Vehicle Identification Number) */
+INTERNAL int mailmark(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length); /* Royal Mail 4-state Mailmark */
+INTERNAL int ultracode(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length); /* Ultracode */
+INTERNAL int rmqr(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length); /* rMQR */
+
+INTERNAL int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type); /* Plot to PNG/BMP/PCX */
+INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_type); /* Plot to EPS/EMF/SVG */
+
+static void error_tag(char error_string[], int error_number) {
+
+ if (error_number != 0) {
+ char error_buffer[100];
+ strcpy(error_buffer, error_string);
+
+ if (error_number > 4) {
+ strcpy(error_string, "Error ");
+ } else {
+ strcpy(error_string, "Warning ");
+ }
+
+ strcat(error_string, error_buffer);
+ }
}
-int dump_plot(struct zint_symbol *symbol)
-{
- FILE *f;
- int i, r;
-
- if(symbol->output_options & BARCODE_STDOUT) {
- f = stdout;
- } else {
- f = fopen(symbol->outfile, "w");
- if(!f) {
- strcpy(symbol->errtxt, "Could not open output file");
- return ERROR_FILE_ACCESS;
- }
- }
-
- fputs("[\n", f);
- for (r = 0; r < symbol->rows; r++) {
- fputs(" [ ", f);
- for (i = 0; i < symbol->width; i++) {
- fputs(module_is_set(symbol, r, i) ? "1 " : "0 ", f);
- }
- fputs("]\n", f);
- }
- fputs("]\n", f);
-
- if(!(symbol->output_options & BARCODE_STDOUT))
+/* Output a hexadecimal representation of the rendered symbol */
+static int dump_plot(struct zint_symbol *symbol) {
+ FILE *f;
+ int i, r;
+ char hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
+ '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+ int space = 0;
+
+ if (symbol->output_options & BARCODE_STDOUT) {
+ f = stdout;
+ } else {
+ f = fopen(symbol->outfile, "w");
+ if (!f) {
+ strcpy(symbol->errtxt, "201: Could not open output file");
+ return ZINT_ERROR_FILE_ACCESS;
+ }
+ }
+
+ for (r = 0; r < symbol->rows; r++) {
+ int byt = 0;
+ for (i = 0; i < symbol->width; i++) {
+ byt = byt << 1;
+ if (module_is_set(symbol, r, i)) {
+ byt += 1;
+ }
+ if (((i + 1) % 4) == 0) {
+ fputc(hex[byt], f);
+ space++;
+ byt = 0;
+ }
+ if (space == 2) {
+ fputc(' ', f);
+ space = 0;
+ }
+ }
+
+ if ((symbol->width % 4) != 0) {
+ byt = byt << (4 - (symbol->width % 4));
+ fputc(hex[byt], f);
+ }
+ fputs("\n", f);
+ space = 0;
+ }
+
+ if (symbol->output_options & BARCODE_STDOUT) {
+ fflush(f);
+ } else {
fclose(f);
+ }
+
+ return 0;
+}
+
+/* Process health industry bar code data */
+static int hibc(struct zint_symbol *symbol, unsigned char source[], size_t length) {
+ size_t i;
+ int counter, error_number;
+ char to_process[113], temp[2], check_digit;
+
+ /* without "+" and check: max 110 characters in HIBC 2.6 */
+ if (length > 110) {
+ strcpy(symbol->errtxt, "202: Data too long for HIBC LIC");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ to_upper(source);
+ error_number = is_sane(TECHNETIUM, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "203: 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';
+
+ strcat(to_process, (char *) source);
+ strcat(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*) "*");
+ strcat((char*) symbol->text, to_process);
+ strcat((char*) symbol->text, "*");
+ break;
+ case BARCODE_HIBC_39:
+ symbol->option_2 = 0;
+ error_number = c39(symbol, (unsigned char *) to_process, length);
+ ustrcpy(symbol->text, (unsigned char*) "*");
+ strcat((char*) symbol->text, to_process);
+ strcat((char*) symbol->text, "*");
+ 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;
+ case BARCODE_HIBC_BLOCKF:
+ error_number = codablock(symbol, (unsigned char *) to_process, length);
+ break;
+ }
+
+ return error_number;
+}
+
+static void check_row_heights(struct zint_symbol *symbol) {
+ /* Check that rows with undefined heights are never less than 5x */
+ int large_bar_count = 0;
+ int i;
+ int preset_height = 0;
+ int large_bar_height = 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;
+ } else {
+ large_bar_height = (symbol->height - preset_height) / large_bar_count;
+ }
+
+ if (large_bar_height < 5) {
+ for (i = 0; i < symbol->rows; i++) {
+ if (symbol->row_height[i] == 0) {
+ symbol->row_height[i] = 5;
+ preset_height += 5;
+ }
+ }
+ symbol->height = preset_height;
+ }
+}
+
+static int check_force_gs1(const int symbology) {
+ /* Returns 1 if symbology MUST have GS1 data */
- return 0;
+ int result = is_composite(symbology);
+
+ switch (symbology) {
+ case BARCODE_EAN128:
+ case BARCODE_EAN14:
+ case BARCODE_NVE18:
+ case BARCODE_RSS_EXP:
+ case BARCODE_RSS_EXPSTACK:
+ result = 1;
+ break;
+ }
+
+ return result;
}
-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_QR:
- error_number = qr_code(symbol, (unsigned char *)to_process, length);
- break;
- }
-
- return error_number;
+static int gs1_compliant(const int symbology) {
+ /* Returns 1 if symbology supports GS1 data */
+
+ int result = check_force_gs1(symbology);
+
+ switch (symbology) {
+ case BARCODE_CODE16K:
+ case BARCODE_AZTEC:
+ case BARCODE_DATAMATRIX:
+ case BARCODE_CODEONE:
+ case BARCODE_CODE49:
+ case BARCODE_QRCODE:
+ case BARCODE_DOTCODE:
+ case BARCODE_RMQR:
+ case BARCODE_ULTRA:
+ result = 1;
+ break;
+ }
+
+ return result;
}
-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;
+static int is_matrix(const int symbology) {
+ /* Returns 1 if symbology is a matrix design */
+
+ int result = 0;
+
+ switch (symbology) {
+ case BARCODE_QRCODE:
+ case BARCODE_DATAMATRIX:
+ case BARCODE_MICROQR:
+ case BARCODE_HIBC_DM:
+ case BARCODE_AZTEC:
+ case BARCODE_HIBC_QR:
+ case BARCODE_HIBC_AZTEC:
+ case BARCODE_AZRUNE:
+ case BARCODE_CODEONE:
+ case BARCODE_GRIDMATRIX:
+ case BARCODE_HANXIN:
+ case BARCODE_DOTCODE:
+ case BARCODE_UPNQR:
+ case BARCODE_RMQR:
+ 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;
+static int is_linear(const int symbology) {
+ /* Returns 1 if symbology is linear (1 dimensional) */
+
+ int result = 0;
+ switch (symbology) {
+ 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_EANX_CHK:
+ case BARCODE_EAN128:
+ case BARCODE_CODABAR:
+ case BARCODE_CODE128:
+ case BARCODE_DPLEIT:
+ case BARCODE_DPIDENT:
+ 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_UPCA_CHK:
+ case BARCODE_UPCE:
+ case BARCODE_UPCE_CHK:
+ case BARCODE_MSI_PLESSEY:
+ case BARCODE_FIM:
+ case BARCODE_LOGMARS:
+ case BARCODE_PHARMA:
+ case BARCODE_PZN:
+ case BARCODE_CODE128B:
+ case BARCODE_ISBNX:
+ case BARCODE_EAN14:
+ case BARCODE_NVE18:
+ case BARCODE_KOREAPOST:
+ case BARCODE_ONECODE:
+ case BARCODE_PLESSEY:
+ case BARCODE_TELEPEN_NUM:
+ case BARCODE_ITF14:
+ case BARCODE_HIBC_128:
+ case BARCODE_HIBC_39:
+ 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_CHANNEL:
+ case BARCODE_VIN:
+ 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;
- }
+static int supports_eci(const int symbology) {
+ /* Returns 1 if symbology can encode the ECI character */
- return error_number;
+ int result = 0;
+
+ switch (symbology) {
+ case BARCODE_AZTEC:
+ case BARCODE_DATAMATRIX:
+ case BARCODE_MAXICODE:
+ case BARCODE_MICROPDF417:
+ case BARCODE_PDF417:
+ case BARCODE_PDF417TRUNC:
+ case BARCODE_QRCODE:
+ case BARCODE_DOTCODE:
+ case BARCODE_GRIDMATRIX:
+ case BARCODE_HANXIN:
+ case BARCODE_ULTRA:
+ result = 1;
+ break;
+ }
+
+ return result;
}
-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;
-
+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_EANX_CHK:
+ 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_UPCA_CHK:
+ case BARCODE_UPCE:
+ case BARCODE_UPCE_CHK:
+ case BARCODE_POSTNET:
+ case BARCODE_MSI_PLESSEY:
+ case BARCODE_FIM:
+ case BARCODE_LOGMARS:
+ case BARCODE_PHARMA:
+ case BARCODE_PZN:
+ case BARCODE_PHARMA_TWO:
+ case BARCODE_PDF417:
+ case BARCODE_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_HIBC_BLOCKF:
+ 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:
+ case BARCODE_HANXIN:
+ case BARCODE_DOTCODE:
+ case BARCODE_CODABLOCKF:
+ case BARCODE_UPNQR:
+ case BARCODE_VIN:
+ case BARCODE_MAILMARK:
+ case BARCODE_ULTRA:
+ case BARCODE_RMQR:
+ result = 1;
+ break;
+ }
+
+ return result;
+}
+
+static int reduced_charset(struct zint_symbol *symbol, const unsigned char *source, size_t in_length);
+
+static int extended_or_reduced_charset(struct zint_symbol *symbol, const unsigned char *source, const int length) {
+ int error_number = 0;
+
+ switch (symbol->symbology) {
+ /* These are the "elite" standards which have support for specific character sets */
+ 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;
+ case BARCODE_HANXIN: error_number = han_xin(symbol, source, length);
+ break;
+ case BARCODE_UPNQR: error_number = upnqr(symbol, source, length);
+ break;
+ case BARCODE_RMQR: error_number = rmqr(symbol, source, length);
+ break;
+ default: error_number = reduced_charset(symbol, source, length);
+ break;
+ }
+
+ return error_number;
+}
+
+static int reduced_charset(struct zint_symbol *symbol, const unsigned char *source, size_t in_length) {
+ /* These are the "norm" standards which only support Latin-1 at most, though a few support ECI */
+ int error_number = 0;
+
+#ifndef _MSC_VER
+ unsigned char preprocessed[in_length + 1];
+#else
+ unsigned char* preprocessed = (unsigned char*) _alloca(in_length + 1);
+#endif
+
+ if (symbol->symbology == BARCODE_ITF14) {
+ symbol->whitespace_width = 20;
+ symbol->border_width = 8;
+ if (!(symbol->output_options & BARCODE_BOX)) {
+ symbol->output_options += BARCODE_BOX;
+ }
+ }
+
+ switch (symbol->input_mode & 0x07) {
+ case DATA_MODE:
+ case GS1_MODE:
+ memcpy(preprocessed, source, in_length);
+ preprocessed[in_length] = '\0';
+ break;
+ case UNICODE_MODE:
+ /* Prior check ensures ECI only set for those that support it */
+ error_number = utf_to_eci(symbol->eci && symbol->eci <= 899 ? symbol->eci : 3, source, preprocessed, &in_length);
+ if (error_number != 0) {
+ strcpy(symbol->errtxt, "204: Invalid characters in input data");
+ return error_number;
+ }
+ break;
+ }
+
+ if ((symbol->height == 0) && is_linear(symbol->symbology)) {
+ symbol->height = 50;
+ }
+
+ switch (symbol->symbology) {
+ case BARCODE_C25MATRIX: error_number = matrix_two_of_five(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_C25IND: error_number = industrial_two_of_five(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_C25INTER: error_number = interleaved_two_of_five(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_C25IATA: error_number = iata_two_of_five(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_C25LOGIC: error_number = logic_two_of_five(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_DPLEIT: error_number = dpleit(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_DPIDENT: error_number = dpident(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_UPCA:
+ case BARCODE_UPCA_CHK:
+ case BARCODE_UPCE:
+ case BARCODE_UPCE_CHK:
+ case BARCODE_EANX:
+ case BARCODE_EANX_CHK:
+ error_number = eanx(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_EAN128: error_number = ean_128(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_CODE39: error_number = c39(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_PZN: error_number = pharmazentral(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_EXCODE39: error_number = ec39(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_CODABAR: error_number = codabar(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_CODE93: error_number = c93(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_LOGMARS: error_number = c39(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_CODE128:
+ case BARCODE_CODE128B:
+ error_number = code_128(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_NVE18: error_number = nve_18(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_CODE11: error_number = code_11(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_MSI_PLESSEY: error_number = msi_handle(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_TELEPEN: error_number = telepen(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_TELEPEN_NUM: error_number = telepen_num(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_PHARMA: error_number = pharma_one(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_PLESSEY: error_number = plessey(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_ITF14: error_number = itf14(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_FLAT: error_number = flattermarken(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_FIM: error_number = fim(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_POSTNET: error_number = post_plot(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_PLANET: error_number = planet_plot(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_RM4SCC: error_number = royal_plot(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_AUSPOST:
+ case BARCODE_AUSREPLY:
+ case BARCODE_AUSROUTE:
+ case BARCODE_AUSREDIRECT:
+ error_number = australia_post(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_CODE16K: error_number = code16k(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_PHARMA_TWO: error_number = pharma_two(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_ONECODE: error_number = imail(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_ISBNX: error_number = eanx(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_RSS14:
+ case BARCODE_RSS14STACK:
+ case BARCODE_RSS14STACK_OMNI:
+ error_number = rss14(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_RSS_LTD: error_number = rsslimited(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_RSS_EXP:
+ case BARCODE_RSS_EXPSTACK:
+ error_number = rssexpanded(symbol, preprocessed, in_length);
+ break;
+ 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:
+ error_number = composite(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_KIX: error_number = kix_code(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_CODE32: error_number = code32(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_DAFT: error_number = daft_code(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_EAN14:
+ error_number = ean_14(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_AZRUNE: error_number = aztec_runes(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_KOREAPOST: error_number = korea_post(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_HIBC_128:
+ case BARCODE_HIBC_39:
+ case BARCODE_HIBC_DM:
+ case BARCODE_HIBC_QR:
+ case BARCODE_HIBC_PDF:
+ case BARCODE_HIBC_MICPDF:
+ case BARCODE_HIBC_AZTEC:
+ case BARCODE_HIBC_BLOCKF:
+ error_number = hibc(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_JAPANPOST: error_number = japan_post(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_CODE49: error_number = code_49(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_CHANNEL: error_number = channel_code(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_CODEONE: error_number = code_one(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_DATAMATRIX: error_number = dmatrix(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_PDF417:
+ case BARCODE_PDF417TRUNC:
+ error_number = pdf417enc(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_MICROPDF417: error_number = micro_pdf417(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_MAXICODE: error_number = maxicode(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_AZTEC: error_number = aztec(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_DOTCODE: error_number = dotcode(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_CODABLOCKF: error_number = codablock(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_VIN: error_number = vin(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_MAILMARK: error_number = mailmark(symbol, preprocessed, in_length);
+ break;
+ case BARCODE_ULTRA: error_number = ultracode(symbol, preprocessed, in_length);
+ break;
+ }
+
+ return error_number;
+}
+
+static void strip_bom(unsigned char *source, int *input_length) {
+ int i;
+
+ if (*input_length > 3) {
+ if((source[0] == 0xef) && (source[1] == 0xbb) && (source[2] == 0xbf)) {
+ /* BOM at start of input data, strip in accordance with RFC 3629 */
+ for (i = 3; i < *input_length; i++) {
+ source[i - 3] = source[i];
+ }
+ *input_length -= 3;
+ }
+ }
+}
+
+static int escape_char_process(struct zint_symbol *symbol, unsigned char *input_string, int *length) {
+ int error_number;
+ int in_posn, out_posn;
+ int hex1, hex2;
+
#ifndef _MSC_VER
- unsigned char preprocessed[length + 1];
+ unsigned char escaped_string[*length + 1];
#else
- unsigned char* preprocessed = (unsigned char*)_alloca(length + 1);
+ unsigned char* escaped_string = (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(source, preprocessed, &length);
- if(error_number != 0) {
- strcpy(symbol->errtxt, "error: Invalid character in input string (only Latin-1 characters supported)");
- return error_number;
- }
- break;
- }
-
- switch(symbol->symbology) {
- case BARCODE_C25INTER: error_number = interleaved_two_of_five(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_CODE39: error_number = c39(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_ISBNX: error_number = eanx(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;
- }
-
- return error_number;
+
+ in_posn = 0;
+ out_posn = 0;
+
+ do {
+ if (input_string[in_posn] == '\\') {
+ if (in_posn + 1 >= *length) {
+ strcpy(symbol->errtxt, "236: Incomplete escape character in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ switch (input_string[in_posn + 1]) {
+ case '0': escaped_string[out_posn] = 0x00; /* Null */
+ in_posn += 2;
+ break;
+ case 'E': escaped_string[out_posn] = 0x04; /* End of Transmission */
+ in_posn += 2;
+ break;
+ case 'a': escaped_string[out_posn] = 0x07; /* Bell */
+ in_posn += 2;
+ break;
+ case 'b': escaped_string[out_posn] = 0x08; /* Backspace */
+ in_posn += 2;
+ break;
+ case 't': escaped_string[out_posn] = 0x09; /* Horizontal tab */
+ in_posn += 2;
+ break;
+ case 'n': escaped_string[out_posn] = 0x0a; /* Line feed */
+ in_posn += 2;
+ break;
+ case 'v': escaped_string[out_posn] = 0x0b; /* Vertical tab */
+ in_posn += 2;
+ break;
+ case 'f': escaped_string[out_posn] = 0x0c; /* Form feed */
+ in_posn += 2;
+ break;
+ case 'r': escaped_string[out_posn] = 0x0d; /* Carriage return */
+ in_posn += 2;
+ break;
+ case 'e': escaped_string[out_posn] = 0x1b; /* Escape */
+ in_posn += 2;
+ break;
+ case 'G': escaped_string[out_posn] = 0x1d; /* Group Separator */
+ in_posn += 2;
+ break;
+ case 'R': escaped_string[out_posn] = 0x1e; /* Record Separator */
+ in_posn += 2;
+ break;
+ case 'x': if (in_posn + 4 > *length) {
+ strcpy(symbol->errtxt, "232: Incomplete escape character in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ hex1 = ctoi(input_string[in_posn + 2]);
+ hex2 = ctoi(input_string[in_posn + 3]);
+ if ((hex1 >= 0) && (hex2 >= 0)) {
+ if (hex1 > 7 && (symbol->input_mode & 0x07) == UNICODE_MODE) {
+ // Convert to UTF-8
+ escaped_string[out_posn] = 0xc0 + (hex1 >> 2);
+ out_posn++;
+ escaped_string[out_posn] = 0x80 + ((hex1 & 0x03) << 4) + hex2;
+ } else {
+ escaped_string[out_posn] = (hex1 << 4) + hex2;
+ }
+ in_posn += 4;
+ } else {
+ strcpy(symbol->errtxt, "233: Corrupt escape character in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ break;
+ case '\\': escaped_string[out_posn] = '\\';
+ in_posn += 2;
+ break;
+ default: strcpy(symbol->errtxt, "234: Unrecognised escape character in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ break;
+ }
+ } else {
+ escaped_string[out_posn] = input_string[in_posn];
+ in_posn++;
+ }
+ out_posn++;
+ } while (in_posn < *length);
+
+ memcpy(input_string, escaped_string, out_posn);
+ input_string[out_posn] = '\0';
+ *length = out_posn;
+
+ error_number = 0;
+
+ 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;
- }
-
-
+int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int in_length) {
+ int error_number, error_buffer, i;
+#ifdef _MSC_VER
+ unsigned char* local_source;
+#endif
+ error_number = 0;
+
+ if (in_length <= 0) {
+ in_length = (int)ustrlen(source);
+ }
+ if (in_length <= 0) {
+ strcpy(symbol->errtxt, "205: No input data");
+ error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA);
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ if (strcmp(symbol->outfile, "") == 0) {
+#ifdef NO_PNG
+ strcpy(symbol->outfile, "out.gif");
+#else
+ strcpy(symbol->outfile, "out.png");
+#endif
+ }
#ifndef _MSC_VER
- unsigned char local_source[length + 1];
+ unsigned char local_source[in_length + 1];
#else
- unsigned char* local_source = (unsigned char*)_alloca(length + 1);
+ local_source = (unsigned char*) _alloca(in_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;
+
+ /* First check the symbology field */
+ if (symbol->symbology < 1) {
+ strcpy(symbol->errtxt, "206: Symbology out of range, using Code 128");
+ symbol->symbology = BARCODE_CODE128;
+ error_number = ZINT_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 == 15) {
+ symbol->symbology = BARCODE_EANX;
+ }
+ if (symbol->symbology == 17) {
+ symbol->symbology = BARCODE_UPCA;
+ }
+ if (symbol->symbology == 19) {
+ strcpy(symbol->errtxt, "207: Codabar 18 not supported, using Codabar");
+ symbol->symbology = BARCODE_CODABAR;
+ error_number = ZINT_WARN_INVALID_OPTION;
+ }
+ if (symbol->symbology == 26) {
+ symbol->symbology = BARCODE_UPCA;
+ }
+ if (symbol->symbology == 27) {
+ strcpy(symbol->errtxt, "208: UPCD1 not supported");
+ error_number = ZINT_ERROR_INVALID_OPTION;
+ }
+ if (symbol->symbology == 33) {
+ symbol->symbology = BARCODE_EAN128;
+ }
+ if (symbol->symbology == 36) {
+ symbol->symbology = BARCODE_UPCA;
+ }
+ 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, "210: General Parcel Code not supported, using Code 128");
+ symbol->symbology = BARCODE_CODE128;
+ error_number = ZINT_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 == 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, "212: Symbology out of range, using Code 128");
+ symbol->symbology = BARCODE_CODE128;
+ error_number = ZINT_WARN_INVALID_OPTION;
+ }
+ if ((symbol->symbology >= 94) && (symbol->symbology <= 96)) {
+ strcpy(symbol->errtxt, "213: Symbology out of range, using Code 128");
+ symbol->symbology = BARCODE_CODE128;
+ error_number = ZINT_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 == 114)) {
+ strcpy(symbol->errtxt, "214: Symbology out of range, using Code 128");
+ symbol->symbology = BARCODE_CODE128;
+ error_number = ZINT_WARN_INVALID_OPTION;
+ }
+ if (symbol->symbology == 115) {
+ symbol->symbology = BARCODE_DOTCODE;
+ }
+ if ((symbol->symbology >= 117) && (symbol->symbology <= 127)) {
+ if (symbol->symbology != 121) {
+ strcpy(symbol->errtxt, "215: Symbology out of range, using Code 128");
+ symbol->symbology = BARCODE_CODE128;
+ error_number = ZINT_WARN_INVALID_OPTION;
+ }
+ }
+ /* Everything from 128 up is Zint-specific */
+ if (symbol->symbology > 145) {
+ strcpy(symbol->errtxt, "216: Symbology out of range, using Code 128");
+ symbol->symbology = BARCODE_CODE128;
+ error_number = ZINT_WARN_INVALID_OPTION;
+ }
+
+ if ((!(supports_eci(symbol->symbology))) && (symbol->eci != 0)) {
+ strcpy(symbol->errtxt, "217: Symbology does not support ECI switching");
+ error_number = ZINT_ERROR_INVALID_OPTION;
+ }
+
+ if ((symbol->eci < 0) || (symbol->eci == 1) || (symbol->eci == 2) || (symbol->eci > 999999)) {
+ strcpy(symbol->errtxt, "218: Invalid ECI mode");
+ error_number = ZINT_ERROR_INVALID_OPTION;
+ }
+
+ if ((symbol->dot_size < 0.01) || (symbol->dot_size > 20.0)) {
+ strcpy(symbol->errtxt, "221: Invalid dot size");
+ error_number = ZINT_ERROR_INVALID_OPTION;
+ }
+
+ if ((symbol->input_mode & 0x07) > 2) {
+ symbol->input_mode = DATA_MODE; /* Reset completely */
+ }
+
+ if (error_number > 4) {
+ error_tag(symbol->errtxt, error_number);
+ return error_number;
+ } else {
+ error_buffer = error_number;
+ }
+
+ memcpy(local_source, source, in_length);
+ local_source[in_length] = '\0';
+
+ /* Start acting on input mode */
+ if (symbol->input_mode & ESCAPE_MODE) {
+ error_number = escape_char_process(symbol, local_source, &in_length);
+ if (error_number != 0) {
+ error_tag(symbol->errtxt, error_number);
+ return error_number;
+ }
+ }
+
+ if ((symbol->input_mode & 0x07) == UNICODE_MODE) {
+ strip_bom(local_source, &in_length);
+ }
+
+ if (((symbol->input_mode & 0x07) == GS1_MODE) || (check_force_gs1(symbol->symbology))) {
+ if (gs1_compliant(symbol->symbology) == 1) {
+ // Reduce input for composite and non-forced symbologies, others (EAN128 and RSS_EXP based) will handle it themselves
+ if (is_composite(symbol->symbology) || !check_force_gs1(symbol->symbology)) {
+#ifndef _MSC_VER
+ char reduced[in_length + 1];
+#else
+ char* reduced = (char*) _alloca(in_length + 1);
+#endif
+ error_number = gs1_verify(symbol, local_source, in_length, reduced);
+ if (error_number != 0) {
+ error_tag(symbol->errtxt, error_number);
+ return error_number;
+ }
+ ustrcpy(local_source, reduced); // Cannot contain nul char
+ in_length = (int) ustrlen(local_source);
+ }
+ } else {
+ strcpy(symbol->errtxt, "220: Selected symbology does not support GS1 mode");
+ error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION);
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+ }
+
+ error_number = extended_or_reduced_charset(symbol, local_source, in_length);
+
+ if ((error_number == ZINT_ERROR_INVALID_DATA) && symbol->eci == 0 && supports_eci(symbol->symbology)
+ && (symbol->input_mode & 0x07) == UNICODE_MODE) {
+ /* Try another ECI mode */
+ symbol->eci = get_best_eci(local_source, in_length);
+
+ error_number = extended_or_reduced_charset(symbol, local_source, in_length);
+
+ if (error_number == 0) {
+ error_number = ZINT_WARN_USES_ECI;
+ if (!(symbol->debug & ZINT_DEBUG_TEST)) {
+ strcpy(symbol->errtxt, "222: Encoded data includes ECI");
+ }
+ if (symbol->debug & ZINT_DEBUG_PRINT) printf("Data ECI %d\n", symbol->eci);
+ }
+ }
+
+ if (error_number == 0) {
+ if ((symbol->symbology == BARCODE_CODE128) || (symbol->symbology == BARCODE_CODE128B)) {
+ for (i = 0; i < in_length; i++) {
+ if (local_source[i] == '\0') {
+ symbol->text[i] = ' ';
+ } else {
+ symbol->text[i] = local_source[i];
+ }
+ }
+ }
+ error_number = error_buffer;
+ }
+ error_tag(symbol->errtxt, error_number);
+
+ if (error_number < 5) {
+ check_row_heights(symbol);
+ }
+
+ return error_number;
+}
+
+int ZBarcode_Print(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, "223: Invalid rotation angle");
+ error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION);
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ if (symbol->output_options & BARCODE_DOTTY_MODE) {
+ if (!(is_matrix(symbol->symbology))) {
+ strcpy(symbol->errtxt, "224: Selected symbology cannot be rendered as dots");
+ error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION);
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+ }
+
+ if (strlen(symbol->outfile) > 3) {
+ char output[4];
+ 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);
+
+ if (!(strcmp(output, "PNG"))) {
+ if (symbol->scale < 1.0) {
+ symbol->text[0] = '\0';
+ }
+ error_number = plot_raster(symbol, rotate_angle, OUT_PNG_FILE);
+ } else
+ if (!(strcmp(output, "BMP"))) {
+ if (symbol->scale < 1.0) {
+ symbol->text[0] = '\0';
+ }
+ error_number = plot_raster(symbol, rotate_angle, OUT_BMP_FILE);
+ } else
+ if (!(strcmp(output, "PCX"))) {
+ if (symbol->scale < 1.0) {
+ symbol->text[0] = '\0';
+ }
+ error_number = plot_raster(symbol, rotate_angle, OUT_PCX_FILE);
+ } else
+ if (!(strcmp(output, "GIF"))) {
+ if (symbol->scale < 1.0) {
+ symbol->text[0] = '\0';
+ }
+ error_number = plot_raster(symbol, rotate_angle, OUT_GIF_FILE);
+ } else
+ if (!(strcmp(output, "TIF"))) {
+ if (symbol->scale < 1.0) {
+ symbol->text[0] = '\0';
+ }
+ error_number = plot_raster(symbol, rotate_angle, OUT_TIF_FILE);
+ } else
+ if (!(strcmp(output, "TXT"))) {
+ error_number = dump_plot(symbol);
+ } else
+ if (!(strcmp(output, "EPS"))) {
+ error_number = plot_vector(symbol, rotate_angle, OUT_EPS_FILE);
+ } else
+ if (!(strcmp(output, "SVG"))) {
+ error_number = plot_vector(symbol, rotate_angle, OUT_SVG_FILE);
+ } else
+ if (!(strcmp(output, "EMF"))) {
+ error_number = plot_vector(symbol, rotate_angle, OUT_EMF_FILE);
+ } else {
+ strcpy(symbol->errtxt, "225: Unknown output format");
+ error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION);
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+ } else {
+ strcpy(symbol->errtxt, "226: Unknown output format");
+ error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION);
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ error_tag(symbol->errtxt, error_number);
+ return error_number;
}
-int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle)
-{
- return ERROR_INVALID_OPTION;
+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, "228: Invalid rotation angle");
+ error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION);
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ if (symbol->output_options & BARCODE_DOTTY_MODE) {
+ if (!(is_matrix(symbol->symbology))) {
+ strcpy(symbol->errtxt, "237: Selected symbology cannot be rendered as dots");
+ error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION);
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+ }
+
+ error_number = plot_raster(symbol, rotate_angle, OUT_BUFFER);
+ 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_Buffer_Vector(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, "228: Invalid rotation angle");
+ error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION);
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ if (symbol->output_options & BARCODE_DOTTY_MODE) {
+ if (!(is_matrix(symbol->symbology))) {
+ strcpy(symbol->errtxt, "238: Selected symbology cannot be rendered as dots");
+ error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION);
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+ }
+
+ error_number = plot_vector(symbol, rotate_angle, OUT_BUFFER);
+ error_tag(symbol->errtxt, error_number);
+ return error_number;
}
-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_Print(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle) {
+ int error_number;
+ int first_err;
+
+ error_number = ZBarcode_Encode(symbol, input, length);
+ if (error_number >= 5) {
+ return error_number;
+ }
+
+ first_err = error_number;
+ error_number = ZBarcode_Print(symbol, rotate_angle);
+ if (error_number == 0) {
+ error_number = first_err;
+ }
+ 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_Buffer(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle) {
+ int error_number;
+ int first_err;
+
+ error_number = ZBarcode_Encode(symbol, input, length);
+ if (error_number >= 5) {
+ return error_number;
+ }
+
+ first_err = error_number;
+ error_number = ZBarcode_Buffer(symbol, rotate_angle);
+ if (error_number == 0) {
+ error_number = first_err;
+ }
+
+ return error_number;
}
-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;
-
- if (!strcmp(filename, "-")) {
- file = stdin;
- fileLen = 7100;
- } else {
- 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");
- if (strcmp(filename, "-"))
- 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));
-
- if (strcmp(filename, "-"))
- fclose(file);
-
- ret = ZBarcode_Encode(symbol, buffer, nRead);
- free(buffer);
- return ret;
+int ZBarcode_Encode_and_Buffer_Vector(struct zint_symbol *symbol, unsigned char *input, int length, int rotate_angle) {
+ int error_number;
+ int first_err;
+
+ error_number = ZBarcode_Encode(symbol, input, length);
+ if (error_number >= 5) {
+ return error_number;
+ }
+
+ first_err = error_number;
+ error_number = ZBarcode_Buffer_Vector(symbol, rotate_angle);
+ if (error_number == 0) {
+ error_number = first_err;
+ }
+
+ return error_number;
}
-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(struct zint_symbol *symbol, char *filename) {
+ FILE *file;
+ unsigned char *buffer;
+ long fileLen;
+ size_t n;
+ int nRead = 0;
+ int ret;
+
+ if (!strcmp(filename, "-")) {
+ file = stdin;
+ fileLen = 7900;
+ } else {
+ file = fopen(filename, "rb");
+ if (!file) {
+ strcpy(symbol->errtxt, "229: Unable to read input file");
+ error_tag(symbol->errtxt, ZINT_ERROR_INVALID_OPTION);
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ /* Get file length */
+ fseek(file, 0, SEEK_END);
+ fileLen = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ if (fileLen > 7900) {
+ /* The largest amount of data that can be encoded is 7827 numeric digits in Han Xin Code */
+ strcpy(symbol->errtxt, "230: Input file too long");
+ error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA);
+ fclose(file);
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ if (fileLen <= 0) {
+ strcpy(symbol->errtxt, "235: Input file empty or unseekable");
+ error_tag(symbol->errtxt, ZINT_ERROR_INVALID_DATA);
+ fclose(file);
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ }
+
+ /* Allocate memory */
+ buffer = (unsigned char *) malloc(fileLen * sizeof (unsigned char));
+ if (!buffer) {
+ strcpy(symbol->errtxt, "231: Internal memory error");
+ error_tag(symbol->errtxt, ZINT_ERROR_MEMORY);
+ if (strcmp(filename, "-")) {
+ fclose(file);
+ }
+ return ZINT_ERROR_MEMORY;
+ }
+
+ /* Read file contents into buffer */
+
+ do {
+ n = fread(buffer + nRead, 1, fileLen - nRead, file);
+ if (ferror(file)) {
+ strcpy(symbol->errtxt, strerror(errno));
+ if (strcmp(filename, "-")) {
+ fclose(file);
+ }
+ free(buffer);
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ nRead += n;
+ } while (!feof(file) && (0 < n) && (nRead < fileLen));
+
+ if (strcmp(filename, "-")) {
+ fclose(file);
+ }
+ ret = ZBarcode_Encode(symbol, buffer, nRead);
+ free(buffer);
+ return ret;
}
-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);
+int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, char *filename, int rotate_angle) {
+ int error_number;
+ int first_err;
+
+ error_number = ZBarcode_Encode_File(symbol, filename);
+ if (error_number >= 5) {
+ return error_number;
+ }
+
+ first_err = error_number;
+ error_number = ZBarcode_Print(symbol, rotate_angle);
+ if (error_number == 0) {
+ error_number = first_err;
+ }
+
+ return error_number;
}
-/*
- * Rendering support, initially added by Sam Lown.
- *
- * Converts encoded data into an intermediate format to be interpreted
- * in other applications using this library.
- *
- * If the width and height are not set to zero, the barcode will be resized to those
- * dimensions. The symbol->scale and symbol->height values are totally ignored in this case.
- *
- */
-int ZBarcode_Render(struct zint_symbol *symbol, float width, float height)
-{
- // Send the request to the render_plot method
- return render_plot(symbol, width, height);
+int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, char *filename, int rotate_angle) {
+ int error_number;
+ int first_err;
+
+ error_number = ZBarcode_Encode_File(symbol, filename);
+ if (error_number >= 5) {
+ return error_number;
+ }
+
+ first_err = error_number;
+ error_number = ZBarcode_Buffer(symbol, rotate_angle);
+ if (error_number == 0) {
+ error_number = first_err;
+ }
+
+ return error_number;
+}
+
+int ZBarcode_Encode_File_and_Buffer_Vector(struct zint_symbol *symbol, char *filename, int rotate_angle) {
+ int error_number;
+ int first_err;
+
+ error_number = ZBarcode_Encode_File(symbol, filename);
+ if (error_number >= 5) {
+ return error_number;
+ }
+
+ first_err = error_number;
+ error_number = ZBarcode_Buffer_Vector(symbol, rotate_angle);
+ if (error_number == 0) {
+ error_number = first_err;
+ }
+
+ return error_number;
+}
+
+int ZBarcode_Version() {
+ return (ZINT_VERSION_MAJOR * 10000) + (ZINT_VERSION_MINOR * 100) + ZINT_VERSION_RELEASE;
}
diff --git a/backend/libzint.rc b/backend/libzint.rc
index 1930f69..ba08f73 100644
--- a/backend/libzint.rc
+++ b/backend/libzint.rc
@@ -1,12 +1,14 @@
+#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#include <winver.h>
#ifdef GCC_WINDRES
VS_VERSION_INFO VERSIONINFO
#else
VS_VERSION_INFO VERSIONINFO
#endif
- FILEVERSION 2,3,0,0
- PRODUCTVERSION 2,3,0,0
+ FILEVERSION 2,8,1,0
+ PRODUCTVERSION 2,8,1,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
@@ -23,14 +25,14 @@ BEGIN
//language ID = U.S. English, char set = Windows, Multilingual
BEGIN
VALUE "FileDescription", "libzint barcode library\0"
- VALUE "FileVersion", "2.3.0.0\0"
+ VALUE "FileVersion", "2.8.1.0\0"
VALUE "InternalName", "zint.dll\0"
- VALUE "LegalCopyright", "Copyright © 2009 Robin Stuart & BogDan Vatra\0"
+ VALUE "LegalCopyright", "Copyright © 2020 Robin Stuart & BogDan Vatra\0"
VALUE "OriginalFilename", "zint.dll\0"
VALUE "ProductName", "libzint\0"
- VALUE "ProductVersion", "2.3.0.0\0"
+ VALUE "ProductVersion", "2.8.1.0\0"
VALUE "License", "BSD License version 3\0"
- VALUE "WWW", "http://www.sourceforge.net/projects/zint\0"
+ VALUE "WWW", "http://www.sourceforge.net/projects/zint"
END
END
BLOCK "VarFileInfo"
diff --git a/backend/mailmark.c b/backend/mailmark.c
new file mode 100644
index 0000000..6e0588f
--- /dev/null
+++ b/backend/mailmark.c
@@ -0,0 +1,498 @@
+/* mailmark.c - Royal Mail 4-state Mailmark barcodes */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/*
+ * Developed in accordance with "Royal Mail Mailmark barcode C encoding and deconding instructions"
+ * (https://www.royalmail.com/sites/default/files/Mailmark-4-state-barcode-C-encoding-and-decoding-instructions-Sept-2015.pdf)
+ * and "Royal Mail Mailmark barcode L encoding and decoding"
+ * (https://www.royalmail.com/sites/default/files/Mailmark-4-state-barcode-L-encoding-and-decoding-instructions-Sept-2015.pdf)
+ *
+ */
+
+#include <string.h>
+#include <stdio.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+#include "common.h"
+#include "large.h"
+#include "reedsol.h"
+
+#define RUBIDIUM "01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ "
+
+// Allowed character values from Table 3
+#define SET_F "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+#define SET_L "ABDEFGHJLNPQRSTUWXYZ"
+#define SET_N "0123456789"
+#define SET_S " "
+
+static const char *postcode_format[6] = {
+ "FNFNLLNLS", "FFNNLLNLS", "FFNNNLLNL", "FFNFNLLNL", "FNNLLNLSS", "FNNNLLNLS"
+};
+
+// Data/Check Symbols from Table 5
+static const unsigned short data_symbol_odd[32] = {
+ 0x01, 0x02, 0x04, 0x07, 0x08, 0x0B, 0x0D, 0x0E, 0x10, 0x13, 0x15, 0x16,
+ 0x19, 0x1A, 0x1C, 0x1F, 0x20, 0x23, 0x25, 0x26, 0x29, 0x2A, 0x2C, 0x2F,
+ 0x31, 0x32, 0x34, 0x37, 0x38, 0x3B, 0x3D, 0x3E
+};
+
+static const unsigned short data_symbol_even[30] = {
+ 0x03, 0x05, 0x06, 0x09, 0x0A, 0x0C, 0x0F, 0x11, 0x12, 0x14, 0x17, 0x18,
+ 0x1B, 0x1D, 0x1E, 0x21, 0x22, 0x24, 0x27, 0x28, 0x2B, 0x2D, 0x2E, 0x30,
+ 0x33, 0x35, 0x36, 0x39, 0x3A, 0x3C
+};
+
+static const unsigned short extender_group_c[22] = {
+ 3, 5, 7, 11, 13, 14, 16, 17, 19, 0, 1, 2, 4, 6, 8, 9, 10, 12, 15, 18, 20, 21
+};
+
+static const unsigned short extender_group_l[26] = {
+ 2, 5, 7, 8, 13, 14, 15, 16, 21, 22, 23, 0, 1, 3, 4, 6, 9, 10, 11, 12, 17, 18, 19, 20, 24, 25
+};
+
+static int verify_character(char input, char type) {
+ int val = 0;
+
+ switch (type) {
+ case 'F':
+ val = posn(SET_F, input);
+ break;
+ case 'L':
+ val = posn(SET_L, input);
+ break;
+ case 'N':
+ val = posn(SET_N, input);
+ break;
+ case 'S':
+ val = posn(SET_S, input);
+ break;
+ }
+
+ if (val == -1) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+static int verify_postcode(char* postcode, int type) {
+ int i;
+ char pattern[11];
+
+ strcpy(pattern, postcode_format[type - 1]);
+
+ for (i = 0; i < 9; i++) {
+ if (!(verify_character(postcode[i], pattern[i]))) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* Royal Mail Mailmark */
+INTERNAL int mailmark(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length) {
+
+ char local_source[28];
+ int format;
+ int version_id;
+ int mail_class;
+ int supply_chain_id;
+ long item_id;
+ char postcode[10];
+ int postcode_type;
+ char pattern[10];
+ large_int destination_postcode;
+ large_int b;
+ large_int cdv;
+ unsigned char data[26];
+ int data_top, data_step;
+ unsigned char check[7];
+ short int extender[27];
+ char bar[80];
+ int check_count;
+ int i, j, len;
+ int length = (int) in_length;
+
+ if (length > 26) {
+ strcpy(symbol->errtxt, "580: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ strcpy(local_source, (char*) source);
+
+ if (length < 22) {
+ for (i = length; i <= 22; i++) {
+ strcat(local_source, " ");
+ }
+ length = 22;
+ }
+
+ if ((length > 22) && (length < 26)) {
+ for (i = length; i <= 26; i++) {
+ strcat(local_source, " ");
+ }
+ length = 26;
+ }
+
+ to_upper((unsigned char*) local_source);
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Producing Mailmark %s\n", local_source);
+ }
+
+ if (is_sane(RUBIDIUM, (unsigned char *) local_source, length) != 0) {
+ strcpy(symbol->errtxt, "581: Invalid characters in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ // Format is in the range 0-4
+ format = ctoi(local_source[0]);
+ if ((format < 0) || (format > 4)) {
+ strcpy(symbol->errtxt, "582: Invalid format");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ // Version ID is in the range 1-4
+ version_id = ctoi(local_source[1]) - 1;
+ if ((version_id < 0) || (version_id > 3)) {
+ strcpy(symbol->errtxt, "583: Invalid Version ID");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ // Class is in the range 0-9,A-E
+ mail_class = ctoi(local_source[2]);
+ if ((mail_class < 0) || (mail_class > 14)) {
+ strcpy(symbol->errtxt, "584: Invalid Class");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ // Supply Chain ID is 2 digits for barcode C and 6 digits for barcode L
+ supply_chain_id = 0;
+ for (i = 3; i < (length - 17); i++) {
+ if ((local_source[i] >= '0') && (local_source[i] <= '9')) {
+ supply_chain_id *= 10;
+ supply_chain_id += ctoi(local_source[i]);
+ } else {
+ strcpy(symbol->errtxt, "585: Invalid Supply Chain ID");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ }
+
+ // Item ID is 8 digits
+ item_id = 0;
+ for (i = length - 17; i < (length - 9); i++) {
+ if ((local_source[i] >= '0') && (local_source[i] <= '9')) {
+ item_id *= 10;
+ item_id += (long) ctoi(local_source[i]);
+ } else {
+ strcpy(symbol->errtxt, "586: Invalid Item ID");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ }
+
+ // Separate Destination Post Code plus DPS field
+ for (i = 0; i < 9; i++) {
+ postcode[i] = local_source[(length - 9) + i];
+ }
+ postcode[9] = '\0';
+
+ // Detect postcode type
+ /* postcode_type is used to select which format of postcode
+ *
+ * 1 = FNFNLLNLS
+ * 2 = FFNNLLNLS
+ * 3 = FFNNNLLNL
+ * 4 = FFNFNLLNL
+ * 5 = FNNLLNLSS
+ * 6 = FNNNLLNLS
+ * 7 = International designation
+ */
+
+ if (strcmp(postcode, "XY11 ") == 0) {
+ postcode_type = 7;
+ } else {
+ if (postcode[7] == ' ') {
+ postcode_type = 5;
+ } else {
+ if (postcode[8] == ' ') {
+ // Types 1, 2 and 6
+ if ((postcode[1] >= '0') && (postcode[1] <= '9')) {
+ if ((postcode[2] >= '0') && (postcode[2] <= '9')) {
+ postcode_type = 6;
+ } else {
+ postcode_type = 1;
+ }
+ } else {
+ postcode_type = 2;
+ }
+ } else {
+ // Types 3 and 4
+ if ((postcode[3] >= '0') && (postcode[3] <= '9')) {
+ postcode_type = 3;
+ } else {
+ postcode_type = 4;
+ }
+ }
+ }
+ }
+
+ // Verify postcode type
+ if (postcode_type != 7) {
+ if (verify_postcode(postcode, postcode_type) != 0) {
+ strcpy(symbol->errtxt, "587: Invalid postcode");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ }
+
+ // Convert postcode to internal user field
+
+ large_load_u64(&destination_postcode, 0);
+
+ if (postcode_type != 7) {
+ strcpy(pattern, postcode_format[postcode_type - 1]);
+
+ large_load_u64(&b, 0);
+
+ for (i = 0; i < 9; i++) {
+ switch (pattern[i]) {
+ case 'F':
+ large_mul_u64(&b, 26);
+ large_add_u64(&b, posn(SET_F, postcode[i]));
+ break;
+ case 'L':
+ large_mul_u64(&b, 20);
+ large_add_u64(&b, posn(SET_L, postcode[i]));
+ break;
+ case 'N':
+ large_mul_u64(&b, 10);
+ large_add_u64(&b, posn(SET_N, postcode[i]));
+ break;
+ // case 'S' ignored as value is 0
+ }
+ }
+
+ large_load(&destination_postcode, &b);
+
+ // destination_postcode = a + b
+ large_load_u64(&b, 1);
+ if (postcode_type == 1) {
+ large_add(&destination_postcode, &b);
+ }
+ large_add_u64(&b, 5408000000);
+ if (postcode_type == 2) {
+ large_add(&destination_postcode, &b);
+ }
+ large_add_u64(&b, 5408000000);
+ if (postcode_type == 3) {
+ large_add(&destination_postcode, &b);
+ }
+ large_add_u64(&b, 54080000000);
+ if (postcode_type == 4) {
+ large_add(&destination_postcode, &b);
+ }
+ large_add_u64(&b, 140608000000);
+ if (postcode_type == 5) {
+ large_add(&destination_postcode, &b);
+ }
+ large_add_u64(&b, 208000000);
+ if (postcode_type == 6) {
+ large_add(&destination_postcode, &b);
+ }
+ }
+
+ // Conversion from Internal User Fields to Consolidated Data Value
+ // Set CDV to 0
+ large_load_u64(&cdv, 0);
+
+ // Add Destination Post Code plus DPS
+ large_add(&cdv, &destination_postcode);
+
+ // Multiply by 100,000,000
+ large_mul_u64(&cdv, 100000000);
+
+ // Add Item ID
+ large_add_u64(&cdv, item_id);
+
+ if (length == 22) {
+ // Barcode C - Multiply by 100
+ large_mul_u64(&cdv, 100);
+ } else {
+ // Barcode L - Multiply by 1,000,000
+ large_mul_u64(&cdv, 1000000);
+ }
+
+ // Add Supply Chain ID
+ large_add_u64(&cdv, supply_chain_id);
+
+ // Multiply by 15
+ large_mul_u64(&cdv, 15);
+
+ // Add Class
+ large_add_u64(&cdv, mail_class);
+
+ // Multiply by 5
+ large_mul_u64(&cdv, 5);
+
+ // Add Format
+ large_add_u64(&cdv, format);
+
+ // Multiply by 4
+ large_mul_u64(&cdv, 4);
+
+ // Add Version ID
+ large_add_u64(&cdv, version_id);
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("DPC type %d\n", postcode_type);
+ printf("CDV: ");
+ large_print(&cdv);
+ }
+
+
+ if (length == 22) {
+ data_top = 15;
+ data_step = 8;
+ check_count = 6;
+ } else {
+ data_top = 18;
+ data_step = 10;
+ check_count = 7;
+ }
+
+ // Conversion from Consolidated Data Value to Data Numbers
+
+ for (j = data_top; j >= (data_step + 1); j--) {
+ data[j] = large_div_u64(&cdv, 32);
+ }
+
+ for (j = data_step; j >= 0; j--) {
+ data[j] = large_div_u64(&cdv, 30);
+ }
+
+ // Generation of Reed-Solomon Check Numbers
+ rs_init_gf(0x25);
+ rs_init_code(check_count, 1);
+ rs_encode((data_top + 1), data, check);
+ rs_free();
+
+ // Append check digits to data
+ for (i = 1; i <= check_count; i++) {
+ data[data_top + i] = check[check_count - i];
+ }
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Codewords: ");
+ for (i = 0; i <= data_top + check_count; i++) {
+ printf("%d ", (int) data[i]);
+ }
+ printf("\n");
+ }
+
+ // Conversion from Data Numbers and Check Numbers to Data Symbols and Check Symbols
+ for (i = 0; i <= data_step; i++) {
+ data[i] = data_symbol_even[data[i]];
+ }
+ for (i = data_step + 1; i <= (data_top + check_count); i++) {
+ data[i] = data_symbol_odd[data[i]];
+ }
+
+ // Conversion from Data Symbols and Check Symbols to Extender Groups
+ for (i = 0; i < length; i++) {
+ if (length == 22) {
+ extender[extender_group_c[i]] = data[i];
+ } else {
+ extender[extender_group_l[i]] = data[i];
+ }
+ }
+
+ // Conversion from Extender Groups to Bar Identifiers
+ strcpy(bar, "");
+
+ for (i = 0; i < length; i++) {
+ for (j = 0; j < 3; j++) {
+ switch(extender[i] & 0x24) {
+ case 0x24:
+ strcat(bar, "F");
+ break;
+ case 0x20:
+ if (i % 2) {
+ strcat(bar, "D");
+ } else {
+ strcat(bar, "A");
+ }
+ break;
+ case 0x04:
+ if (i % 2) {
+ strcat(bar, "A");
+ } else {
+ strcat(bar, "D");
+ }
+ break;
+ default:
+ strcat(bar, "T");
+ break;
+ }
+ extender[i] = extender[i] << 1;
+ }
+ }
+
+ bar[(length * 3)] = '\0';
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Bar pattern: %s\n", bar);
+ }
+
+ /* Translate 4-state data pattern to symbol */
+ j = 0;
+ for (i = 0, len = strlen(bar); i < len; i++) {
+ if ((bar[i] == 'F') || (bar[i] == 'A')) {
+ set_module(symbol, 0, j);
+ }
+ set_module(symbol, 1, j);
+ if ((bar[i] == 'F') || (bar[i] == 'D')) {
+ set_module(symbol, 2, j);
+ }
+ j += 2;
+ }
+
+ symbol->row_height[0] = 4;
+ symbol->row_height[1] = 2;
+ symbol->row_height[2] = 4;
+
+ symbol->rows = 3;
+ symbol->width = j - 1;
+
+ return 0;
+}
diff --git a/backend/maxicode.c b/backend/maxicode.c
new file mode 100644
index 0000000..cf7200f
--- /dev/null
+++ b/backend/maxicode.c
@@ -0,0 +1,736 @@
+/* maxicode.c - Handles Maxicode */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2010-2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/* Includes corrections thanks to Monica Swanson @ Source Technologies */
+#include "common.h"
+#include "maxicode.h"
+#include "reedsol.h"
+#include <string.h>
+
+static int maxi_codeword[144];
+
+/* Handles error correction of primary message */
+static void maxi_do_primary_check() {
+ 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();
+}
+
+/* Handles error correction of odd characters in secondary */
+static void maxi_do_secondary_chk_odd(int ecclen) {
+ 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 & 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();
+}
+
+/* Handles error correction of even characters in secondary */
+static void maxi_do_secondary_chk_even(int ecclen) {
+ 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 & 1)) // 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();
+}
+
+/* Moves everything up so that a shift or latch can be inserted */
+static void maxi_bump(int set[], int character[], int bump_posn) {
+ int i;
+
+ for (i = 143; i > bump_posn; i--) {
+ set[i] = set[i - 1];
+ character[i] = character[i - 1];
+ }
+}
+
+/* If the value is present in array, return the value, else return badvalue */
+static int value_in_array(int val, int arr[], int badvalue, int arrLength) {
+ int i;
+ for(i = 0; i < arrLength; i++){
+ if(arr[i] == val) return val;
+ }
+ return badvalue;
+}
+
+/* Choose the best set from previous and next set in the range of the setval array, if no value can be found we return setval[0] */
+static int bestSurroundingSet(int index, int length, int set[], int setval[], int setLength) {
+ int badValue = -1;
+ int option1 = value_in_array(set[index - 1], setval, badValue, setLength);
+ if (index + 1 < length) {
+ // we have two options to check (previous & next)
+ int option2 = value_in_array(set[index + 1], setval, badValue, setLength);
+ if (option2 != badValue && option1 > option2) {
+ return option2;
+ }
+ }
+ //
+ if (option1 != badValue) {
+ return option1;
+ }
+ return setval[0];
+}
+
+/* Format text according to Appendix A */
+static int maxi_text_process(int mode, unsigned char source[], int length, int eci) {
+ /* 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;
+
+ int set15[2] = { 1, 5 };
+ int set12[2] = { 1, 2 };
+ int set12345[5] = { 1, 2, 3, 4, 5 };
+
+ if (length > 138) {
+ return ZINT_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 */
+ set[i] = bestSurroundingSet(i, length, set, set15, 2);
+ if (set[i] == 5) {
+ character[i] = 13;
+ } else {
+ character[i] = 0;
+ }
+ done = 1;
+ }
+
+ if ((done == 0) && (character[i] == 28)) {
+ /* FS */
+ set[i] = bestSurroundingSet(i, length, set, set12345, 5);
+ if (set[i] == 5) {
+ character[i] = 32;
+ }
+ done = 1;
+ }
+
+ if ((done == 0) && (character[i] == 29)) {
+ /* GS */
+ set[i] = bestSurroundingSet(i, length, set, set12345, 5);
+ if (set[i] == 5) {
+ character[i] = 33;
+ }
+ done = 1;
+ }
+
+ if ((done == 0) && (character[i] == 30)) {
+ /* RS */
+ set[i] = bestSurroundingSet(i, length, set, set12345, 5);
+ if (set[i] == 5) {
+ character[i] = 34;
+ }
+ done = 1;
+ }
+
+ if ((done == 0) && (character[i] == 32)) {
+ /* Space */
+ set[i] = bestSurroundingSet(i, length, set, set12345, 5);
+ if (set[i] == 1) {
+ character[i] = 32;
+ } else if (set[i] == 2) {
+ character[i] = 47;
+ } else {
+ character[i] = 59;
+ }
+ done = 1;
+ }
+
+ if ((done == 0) && (character[i] == 44)) {
+ /* Comma */
+ set[i] = bestSurroundingSet(i, length, set, set12, 2);
+ if (set[i] == 2) {
+ character[i] = 48;
+ }
+ done = 1;
+ }
+
+ if ((done == 0) && (character[i] == 46)) {
+ /* Full Stop */
+ set[i] = bestSurroundingSet(i, length, set, set12, 2);
+ if (set[i] == 2) {
+ character[i] = 49;
+ }
+ done = 1;
+ }
+
+ if ((done == 0) && (character[i] == 47)) {
+ /* Slash */
+ set[i] = bestSurroundingSet(i, length, set, set12, 2);
+ if (set[i] == 2) {
+ character[i] = 50;
+ }
+ done = 1;
+ }
+
+ if ((done == 0) && (character[i] == 58)) {
+ /* Colon */
+ set[i] = bestSurroundingSet(i, length, set, set12, 2);
+ if (set[i] == 2) {
+ character[i] = 51;
+ }
+ 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 < 144; 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) && (set[i] != 6)) {
+ switch (set[i]) {
+ case 1:
+ if (i+1 < 144 && set[i + 1] == 1) {
+ if (i+2 < 144 && set[i + 2] == 1) {
+ if (i+3 < 144 && 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 (i+1 < 144 && 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:
+ if (i + 3 < 144 && set[i + 1] == 3 && set[i + 2] == 3 && set[i + 3] == 3) {
+ maxi_bump(set, character, i);
+ character[i] = 60;
+ maxi_bump(set, character, i);
+ character[i] = 60;
+ current_set = 3;
+ length++;
+ i += 3;
+ } else {
+ /* Shift C */
+ maxi_bump(set, character, i);
+ character[i] = 60;
+ length++;
+ }
+ break;
+ case 4:
+ /* Shift D */
+ if (i + 3 < 144 && set[i + 1] == 4 && set[i + 2] == 4 && set[i + 3] == 4) {
+ maxi_bump(set, character, i);
+ character[i] = 61;
+ maxi_bump(set, character, i);
+ character[i] = 61;
+ current_set = 4;
+ length++;
+ i += 3;
+ } else {
+ maxi_bump(set, character, i);
+ character[i] = 61;
+ length++;
+ }
+ break;
+ case 5:
+ /* Shift E */
+ if (i + 3 < 144 && set[i + 1] == 5 && set[i + 2] == 5 && set[i + 3] == 5) {
+ maxi_bump(set, character, i);
+ character[i] = 62;
+ maxi_bump(set, character, i);
+ character[i] = 62;
+ current_set = 5;
+ length++;
+ i += 3;
+ } else {
+ maxi_bump(set, character, i);
+ character[i] = 62;
+ length++;
+ }
+ break;
+ }
+ i++;
+ }
+ i++;
+ } while (i < 144);
+
+ /* Number compression has not been forgotten! - It's handled below */
+ i = 0;
+ do {
+ if (set[i] == 6) {
+ /* Number compression */
+ char substring[10];
+ int value;
+
+ for (j = 0; j < 9; j++) {
+ substring[j] = character[i + j];
+ }
+ substring[9] = '\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 < 141; j++) {
+ set[j] = set[j + 3];
+ character[j] = character[j + 3];
+ }
+ length -= 3;
+ } else {
+ i++;
+ }
+ } while (i <= 135); /* 144 - 9 */
+
+ /* Insert ECI at the beginning of message if needed */
+ /* Encode ECI assignment numbers according to table 3 */
+ if (eci != 0) {
+ maxi_bump(set, character, 0);
+ character[0] = 27; // ECI
+ if (eci <= 31) {
+ maxi_bump(set, character, 1);
+ character[1] = eci;
+ length += 2;
+ }
+ if ((eci >= 32) && (eci <= 1023)) {
+ maxi_bump(set, character, 1);
+ maxi_bump(set, character, 1);
+ character[1] = 0x20 + ((eci >> 6) & 0x0F);
+ character[2] = eci & 0x3F;
+ length += 3;
+ }
+ if ((eci >= 1024) && (eci <= 32767)) {
+ maxi_bump(set, character, 1);
+ maxi_bump(set, character, 1);
+ maxi_bump(set, character, 1);
+ character[1] = 0x30 + ((eci >> 12) & 0x03);
+ character[2] = (eci >> 6) & 0x3F;
+ character[3] = eci & 0x3F;
+ length += 4;
+ }
+ if (eci >= 32768) {
+ maxi_bump(set, character, 1);
+ maxi_bump(set, character, 1);
+ maxi_bump(set, character, 1);
+ maxi_bump(set, character, 1);
+ character[1] = 0x38 + ((eci >> 18) & 0x02);
+ character[2] = (eci >> 12) & 0x3F;
+ character[3] = (eci >> 6) & 0x3F;
+ character[4] = eci & 0x3F;
+ length += 5;
+ }
+ }
+
+ if (((mode == 2) || (mode == 3)) && (length > 84)) {
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ if (((mode == 4) || (mode == 6)) && (length > 93)) {
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ if ((mode == 5) && (length > 77)) {
+ return ZINT_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;
+}
+
+/* Format structured primary for Mode 2 */
+static void maxi_do_primary_2(char postcode[], int country, int service) {
+ size_t postcode_length;
+ int 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);
+}
+
+/* Format structured primary for Mode 3 */
+static void maxi_do_primary_3(char postcode[], int country, int service) {
+ 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);
+}
+
+INTERNAL int maxicode(struct zint_symbol *symbol, unsigned char local_source[], const int length) {
+ int i, j, block, bit, mode, lp = 0;
+ int bit_pattern[7], internal_error = 0, eclen;
+ char postcode[12], countrystr[4], servicestr[4];
+
+ mode = symbol->option_1;
+ strcpy(postcode, "");
+ strcpy(countrystr, "");
+ strcpy(servicestr, "");
+
+ 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, "550: Invalid Maxicode Mode");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ if ((mode == 2) || (mode == 3)) { /* Modes 2 and 3 need data in symbol->primary */
+ int countrycode;
+ int service;
+ if (lp == 0) { /* Mode set manually means lp doesn't get set */
+ lp = strlen(symbol->primary);
+ }
+ if (lp != 15) {
+ strcpy(symbol->errtxt, "551: Invalid Primary String");
+ return ZINT_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, "552: Invalid Primary String");
+ return ZINT_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, symbol->eci);
+ if (i == ZINT_ERROR_TOO_LONG) {
+ strcpy(symbol->errtxt, "553: 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 0000000..2d22459
--- /dev/null
+++ b/backend/maxicode.h
@@ -0,0 +1,104 @@
+/* maxicode.h - Handles Maxicode */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+
+static const unsigned short 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
+};
+
+static const char 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
+};
+
+static const char 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
deleted file mode 100644
index f39c51e..0000000
--- a/backend/maxipng.h
+++ /dev/null
@@ -1,149 +0,0 @@
-/* maxipng.h - Shapes for Maxicode output to PNG file */
-
-/*
- libzint - the open source barcode library
- Copyright (C) 2008 Robin Stuart <robin@zint.org.uk>
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the project nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-*/
-
-/* 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 const 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 const 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 0000000..51e77eb
--- /dev/null
+++ b/backend/medical.c
@@ -0,0 +1,334 @@
+/* medical.c - Handles 1 track and 2 track pharmacode and Codabar */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <stdio.h>
+#include "common.h"
+
+INTERNAL int c39(struct zint_symbol *symbol, unsigned char source[], const size_t length);
+
+/* Codabar table checked against EN 798:1995 */
+
+#define CALCIUM "0123456789-$:/.+ABCD"
+#define CALCIUM_INNER "0123456789-$:/.+"
+
+static const char *CodaTable[20] = {
+ "11111221", "11112211", "11121121", "22111111", "11211211", "21111211",
+ "12111121", "12112111", "12211111", "21121111", "11122111", "11221111", "21112121", "21211121",
+ "21212111", "11212121", "11221211", "12121121", "11121221", "11122211"
+};
+
+INTERNAL 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 */
+
+ if (length > 6) {
+ strcpy(symbol->errtxt, "350: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "351: Invalid characters in data");
+ return error_number;
+ }
+
+ tester = atoi((char*) source);
+
+ if ((tester < 3) || (tester > 131070)) {
+ strcpy(symbol->errtxt, "352: Data out of range");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ do {
+ if (!(tester & 1)) {
+ strcat(inter, "W");
+ tester = (tester - 2) / 2;
+ } else {
+ strcat(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') {
+ strcat(dest, "32");
+ } else {
+ strcat(dest, "12");
+ }
+ }
+
+ expand(symbol, dest);
+
+ return error_number;
+}
+
+static 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, "353: Data out of range");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ error_number = 0;
+ strcpy(inter, "");
+ do {
+ switch (tester % 3) {
+ case 0:
+ strcat(inter, "3");
+ tester = (tester - 3) / 3;
+ break;
+ case 1:
+ strcat(inter, "1");
+ tester = (tester - 1) / 3;
+ break;
+ case 2:
+ strcat(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;
+}
+
+INTERNAL 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, "354: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "355: 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;
+}
+
+/* The Codabar system consisting of simple substitution */
+INTERNAL int codabar(struct zint_symbol *symbol, unsigned char source[], int length) {
+
+ int i, error_number;
+ char dest[512];
+ int add_checksum, count, checksum;
+
+ strcpy(dest, "");
+
+ if (length > 60) { /* No stack smashing please */
+ strcpy(symbol->errtxt, "356: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ /* BS EN 798:1995 4.2 "'Codabar' symbols shall consist of ... b) start character;
+ * c) one or more symbol characters representing data ... d) stop character ..." */
+ if (length < 3) {
+ strcpy(symbol->errtxt, "362: Input too short");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ to_upper(source);
+
+ /* 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, "358: Does not begin with \"A\", \"B\", \"C\" or \"D\"");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ if ((source[length - 1] != 'A') && (source[length - 1] != 'B') &&
+ (source[length - 1] != 'C') && (source[length - 1] != 'D')) {
+ strcpy(symbol->errtxt, "359: Does not end with \"A\", \"B\", \"C\" or \"D\"");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ /* And must not use A, B, C or D otherwise (BS EN 798:1995 4.3.2) */
+ error_number = is_sane(CALCIUM_INNER, source + 1, length - 2);
+ if (error_number) {
+ strcpy(symbol->errtxt, "363: Cannot contain \"A\", \"B\", \"C\" or \"D\"");
+ return error_number;
+ }
+
+ add_checksum = symbol->option_2 == 1;
+ if (add_checksum) {
+ count = 0;
+ }
+
+ for (i = 0; i < length; i++) {
+ if (add_checksum) {
+ count += strchr(CALCIUM, source[i]) - CALCIUM;
+ if (i + 1 == length) {
+ checksum = count % 16;
+ if (checksum) {
+ checksum = 16 - checksum;
+ }
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Codabar: %s, count %d, checksum %d\n", source, count, checksum);
+ }
+ strcat(dest, CodaTable[checksum]);
+ }
+ }
+ lookup(CALCIUM, CodaTable, source[i], dest);
+ }
+
+ expand(symbol, dest);
+ ustrcpy(symbol->text, source);
+ return error_number;
+}
+
+/* Italian Pharmacode */
+INTERNAL int code32(struct zint_symbol *symbol, unsigned char source[], int length) {
+ int i, zeroes, error_number, checksum, checkpart, checkdigit;
+ char localstr[10], risultante[7];
+ long int pharmacode, devisor;
+ int codeword[6];
+ char tabella[34];
+
+ /* Validate the input */
+ if (length > 8) {
+ strcpy(symbol->errtxt, "360: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "361: Invalid characters in data");
+ return error_number;
+ }
+
+ /* Add leading zeros as required */
+ zeroes = 8 - length;
+ memset(localstr, '0', zeroes);
+ ustrcpy(localstr + zeroes, source);
+
+ /* Calculate the check digit */
+ checksum = 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--) {
+ long int remainder;
+ 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, "A");
+ ustrcat(symbol->text, localstr);
+
+ return error_number;
+}
diff --git a/backend/ms_stdint.h b/backend/ms_stdint.h
new file mode 100644
index 0000000..f137450
--- /dev/null
+++ b/backend/ms_stdint.h
@@ -0,0 +1,235 @@
+// 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 <limits.h>
+
+// For Visual Studio 6 in C++ mode wrap <wchar.h> 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 <wchar.h>
+#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 <wchar.h>
+#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/output.c b/backend/output.c
new file mode 100644
index 0000000..07c9885
--- /dev/null
+++ b/backend/output.c
@@ -0,0 +1,114 @@
+/* output.c - Common routines for raster/vector
+
+ libzint - the open source barcode library
+ Copyright (C) 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <string.h>
+#include "common.h"
+#include "output.h"
+
+#define SSET "0123456789ABCDEF"
+
+/* Check colour options are good. Note: using raster.c error nos 651-654 */
+INTERNAL int check_colour_options(struct zint_symbol *symbol) {
+ int error_number;
+
+ if (strlen(symbol->fgcolour) != 6) {
+ strcpy(symbol->errtxt, "651: Malformed foreground colour target");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+ if (strlen(symbol->bgcolour) != 6) {
+ strcpy(symbol->errtxt, "652: Malformed background colour target");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ to_upper((unsigned char *) symbol->fgcolour);
+ to_upper((unsigned char *) symbol->bgcolour);
+
+ error_number = is_sane(SSET, (unsigned char *) symbol->fgcolour, strlen(symbol->fgcolour));
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "653: Malformed foreground colour target");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ error_number = is_sane(SSET, (unsigned char *) symbol->bgcolour, strlen(symbol->fgcolour));
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "654: Malformed background colour target");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ return 0;
+}
+
+/* Return minimum quiet zones for each symbology */
+static void quiet_zones(struct zint_symbol *symbol, int *left, int *right, int *top, int *bottom) {
+ *left = *right = *top = *bottom = 0;
+
+ switch (symbol->symbology) {
+ case BARCODE_CODE16K:
+ /* BS EN 12323:2005 Section 4.5 c) */
+ *left = 10;
+ *right = 1;
+ break;
+ case BARCODE_CODE49:
+ /* ANSI/AIM BC6-2000 Section 2.4 */
+ *left = 10;
+ *right = 1;
+ break;
+ case BARCODE_CODABLOCKF:
+ case BARCODE_HIBC_BLOCKF:
+ /* AIM ISS-X-24 Section 4.6.1 */
+ *left = 10;
+ *right = 10;
+ break;
+ /* TODO: others */
+ }
+}
+
+/* Set left (x), top (y), right and bottom offsets for whitespace */
+INTERNAL void set_whitespace_offsets(struct zint_symbol *symbol, int *xoffset, int *yoffset, int *roffset, int *boffset) {
+ int qz_left, qz_right, qz_top, qz_bottom;
+
+ quiet_zones(symbol, &qz_left, &qz_right, &qz_top, &qz_bottom);
+
+ *xoffset = symbol->whitespace_width + qz_left;
+ *roffset = symbol->whitespace_width + qz_right;
+ if (symbol->output_options & BARCODE_BOX) {
+ *xoffset += symbol->border_width;
+ *roffset += symbol->border_width;
+ }
+
+ *yoffset = qz_top;
+ *boffset = qz_bottom;
+ if (symbol->output_options & (BARCODE_BOX | BARCODE_BIND)) {
+ *yoffset += symbol->border_width;
+ *boffset += symbol->border_width;
+ }
+}
diff --git a/backend/output.h b/backend/output.h
new file mode 100644
index 0000000..7e5ecd6
--- /dev/null
+++ b/backend/output.h
@@ -0,0 +1,47 @@
+/* output.h - Common routines for raster/vector
+
+ libzint - the open source barcode library
+ Copyright (C) 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#ifndef OUTPUT_H
+#define OUTPUT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+INTERNAL int check_colour_options(struct zint_symbol *symbol);
+INTERNAL void set_whitespace_offsets(struct zint_symbol *symbol, int *xoffset, int *yoffset, int *roffset, int *boffset);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OUTPUT_H */
diff --git a/backend/pcx.c b/backend/pcx.c
new file mode 100644
index 0000000..22bd3bd
--- /dev/null
+++ b/backend/pcx.c
@@ -0,0 +1,222 @@
+/* pcx.c - Handles output to ZSoft PCX file */
+/* ZSoft PCX File Format Technical Reference Manual http://bespin.org/~qz/pc-gpe/pcx.txt */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <stdio.h>
+#include <string.h>
+#include "common.h"
+#include "pcx.h" /* PCX header structure */
+#include <math.h>
+#ifdef _MSC_VER
+#include <io.h>
+#include <fcntl.h>
+#include <malloc.h>
+#endif
+
+INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
+ int fgred, fggrn, fgblu, bgred, bggrn, bgblu;
+ int row, column, i, colour;
+ int run_count;
+ FILE *pcx_file;
+ pcx_header_t header;
+ int bytes_per_line = symbol->bitmap_width + (symbol->bitmap_width & 1); // Must be even
+ unsigned char previous;
+#ifdef _MSC_VER
+ unsigned char* rle_row;
+#endif
+
+#ifndef _MSC_VER
+ unsigned char rle_row[bytes_per_line];
+#else
+ rle_row = (unsigned char *) _alloca(bytes_per_line);
+#endif /* _MSC_VER */
+
+ rle_row[bytes_per_line - 1] = 0; // Will remain zero if bitmap_width odd
+
+ 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]);
+
+
+ header.manufacturer = 10; // ZSoft
+ header.version = 5; // Version 3.0
+ header.encoding = 1; // Run length encoding
+ header.bits_per_pixel = 8;
+ header.window_xmin = 0;
+ header.window_ymin = 0;
+ header.window_xmax = symbol->bitmap_width - 1;
+ header.window_ymax = symbol->bitmap_height - 1;
+ header.horiz_dpi = 300;
+ header.vert_dpi = 300;
+
+ for (i = 0; i < 48; i++) {
+ header.colourmap[i] = 0x00;
+ }
+
+ header.reserved = 0;
+ header.number_of_planes = 3;
+
+ header.bytes_per_line = bytes_per_line;
+
+ header.palette_info = 1; // Colour
+ header.horiz_screen_size = 0;
+ header.vert_screen_size = 0;
+
+ for (i = 0; i < 54; i++) {
+ header.filler[i] = 0x00;
+ }
+
+ /* Open output file in binary mode */
+ if (symbol->output_options & BARCODE_STDOUT) {
+#ifdef _MSC_VER
+ if (-1 == _setmode(_fileno(stdout), _O_BINARY)) {
+ strcpy(symbol->errtxt, "620: Can't open output file");
+ return ZINT_ERROR_FILE_ACCESS;
+ }
+#endif
+ pcx_file = stdout;
+ } else {
+ if (!(pcx_file = fopen(symbol->outfile, "wb"))) {
+ strcpy(symbol->errtxt, "621: Can't open output file");
+ return ZINT_ERROR_FILE_ACCESS;
+ }
+ }
+
+ fwrite(&header, sizeof (pcx_header_t), 1, pcx_file);
+
+ for (row = 0; row < symbol->bitmap_height; row++) {
+ for (colour = 0; colour < 3; colour++) {
+ for (column = 0; column < symbol->bitmap_width; column++) {
+ switch (colour) {
+ case 0:
+ switch(pixelbuf[(row * symbol->bitmap_width) + column]) {
+ case 'W': // White
+ case 'M': // Magenta
+ case 'R': // Red
+ case 'Y': // Yellow
+ rle_row[column] = 255;
+ break;
+ case 'C': // Cyan
+ case 'B': // Blue
+ case 'G': // Green
+ case 'K': // Black
+ rle_row[column] = 0;
+ break;
+ case '1':
+ rle_row[column] = fgred;
+ break;
+ default:
+ rle_row[column] = bgred;
+ break;
+ }
+ break;
+ case 1:
+ switch(pixelbuf[(row * symbol->bitmap_width) + column]) {
+ case 'W': // White
+ case 'C': // Cyan
+ case 'Y': // Yellow
+ case 'G': // Green
+ rle_row[column] = 255;
+ break;
+ case 'B': // Blue
+ case 'M': // Magenta
+ case 'R': // Red
+ case 'K': // Black
+ rle_row[column] = 0;
+ break;
+ case '1':
+ rle_row[column] = fggrn;
+ break;
+ default:
+ rle_row[column] = bggrn;
+ break;
+ }
+ break;
+ case 2:
+ switch(pixelbuf[(row * symbol->bitmap_width) + column]) {
+ case 'W': // White
+ case 'C': // Cyan
+ case 'B': // Blue
+ case 'M': // Magenta
+ rle_row[column] = 255;
+ break;
+ case 'R': // Red
+ case 'Y': // Yellow
+ case 'G': // Green
+ case 'K': // Black
+ rle_row[column] = 0;
+ break;
+ case '1':
+ rle_row[column] = fgblu;
+ break;
+ default:
+ rle_row[column] = bgblu;
+ break;
+ }
+ break;
+ }
+ }
+
+ /* Based on ImageMagick/coders/pcx.c PCXWritePixels()
+ * Copyright 1999-2020 ImageMagick Studio LLC */
+ previous = rle_row[0];
+ run_count = 1;
+ for (column = 1; column < bytes_per_line; column++) { // Note going up to bytes_per_line
+ if ((previous == rle_row[column]) && (run_count < 63)) {
+ run_count++;
+ } else {
+ if (run_count > 1 || (previous & 0xc0) == 0xc0) {
+ run_count += 0xc0;
+ fputc(run_count, pcx_file);
+ }
+ fputc(previous, pcx_file);
+ previous = rle_row[column];
+ run_count = 1;
+ }
+ }
+
+ if (run_count > 1 || (previous & 0xc0) == 0xc0) {
+ run_count += 0xc0;
+ fputc(run_count, pcx_file);
+ }
+ fputc(previous, pcx_file);
+ }
+ }
+
+ fclose(pcx_file);
+
+ return 0;
+}
diff --git a/backend/pcx.h b/backend/pcx.h
new file mode 100644
index 0000000..9915e83
--- /dev/null
+++ b/backend/pcx.h
@@ -0,0 +1,77 @@
+/* pcx.h - header structure for ZSoft PCX files
+
+ libzint - the open source barcode library
+ Copyright (C) 2016-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+
+#ifndef PCX_H
+#define PCX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _MSC_VER
+#include <windows.h>
+#include "stdint_msvc.h"
+#else
+#include <stdint.h>
+#endif
+
+#pragma pack (1)
+
+ typedef struct pcx_header {
+ uint8_t manufacturer;
+ uint8_t version;
+ uint8_t encoding;
+ uint8_t bits_per_pixel;
+ uint16_t window_xmin;
+ uint16_t window_ymin;
+ uint16_t window_xmax;
+ uint16_t window_ymax;
+ uint16_t horiz_dpi;
+ uint16_t vert_dpi;
+ uint8_t colourmap[48];
+ uint8_t reserved;
+ uint8_t number_of_planes;
+ uint16_t bytes_per_line;
+ uint16_t palette_info;
+ uint16_t horiz_screen_size;
+ uint16_t vert_screen_size;
+ uint8_t filler[54];
+ } pcx_header_t;
+
+#pragma pack ()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PCX_H */
+
+
diff --git a/backend/pdf417.c b/backend/pdf417.c
new file mode 100644
index 0000000..eb39741
--- /dev/null
+++ b/backend/pdf417.c
@@ -0,0 +1,1327 @@
+/* pdf417.c - Handles PDF417 stacked symbology */
+
+/* Zint - A barcode generating program using libpng
+ Copyright (C) 2008-2020 Robin Stuart <rstuart114@gmail.com>
+ Portions Copyright (C) 2004 Grandzebu
+ Bug Fixes thanks to KL Chin <klchin@users.sourceforge.net>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/* 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) */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#ifndef _MSC_VER
+#include <stdint.h>
+#else
+#include <malloc.h>
+#include "ms_stdint.h"
+#endif
+#include "pdf417.h"
+#include "common.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 const char 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 const char 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 const char 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
+};
+
+#define PDF417_MAX_LEN 2710 /* ISO/IEC 15438:2015 5.1.1 c) 3) Max possible number of characters at error correction level 0 (Numeric Compaction mode) */
+#define MICRO_PDF417_MAX_LEN 366 /* ISO/IEC 24728:2006 5.1.1 c) 3) Max possible number of characters (Numeric Compaction mode) */
+
+static int liste[2][PDF417_MAX_LEN]; /* global */
+
+/* 866 */
+
+static int quelmode(char codeascii) {
+ int mode = BYT;
+ if ((codeascii == '\t') || (codeascii == '\n') || (codeascii == '\r') || ((codeascii >= ' ') && (codeascii <= '~'))) {
+ mode = TEX;
+ }
+ if ((codeascii >= '0') && (codeascii <= '9')) {
+ mode = NUM;
+ }
+ /* 876 */
+
+ return mode;
+}
+
+/* 844 */
+static void regroupe(int *indexliste) {
+
+ /* bring together same type blocks */
+ if (*(indexliste) > 1) {
+ int i = 1;
+ while (i < *(indexliste)) {
+ if (liste[1][i - 1] == liste[1][i]) {
+ int j;
+ /* 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 */
+static 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 */
+static void textprocess(int *chainemc, int *mclength, char chaine[], int start, int length) {
+ int j, indexlistet, curtable, listet[2][PDF417_MAX_LEN], chainet[PDF417_MAX_LEN], wnet;
+
+ wnet = 0;
+
+ for (j = 0; j < PDF417_MAX_LEN; j++) {
+ listet[0][j] = 0;
+ }
+ /* listet will contain the table numbers and the value of each characters */
+ for (indexlistet = 0; indexlistet < length; indexlistet++) {
+ char codeascii = chaine[start + indexlistet];
+ switch (codeascii) {
+ case '\t': listet[0][indexlistet] = 12;
+ listet[1][indexlistet] = 12;
+ break;
+ case '\n': listet[0][indexlistet] = 8;
+ listet[1][indexlistet] = 15;
+ break;
+ case 13: listet[0][indexlistet] = 12;
+ listet[1][indexlistet] = 11;
+ break;
+ default: listet[0][indexlistet] = asciix[codeascii - 32];
+ listet[1][indexlistet] = asciiy[codeascii - 32];
+ break;
+ }
+ }
+
+ /* 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 & 1) {
+ 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 */
+INTERNAL void byteprocess(int *chainemc, int *mclength, unsigned char chaine[], int start, int length) {
+ int debug = 0;
+
+ 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 {
+ int len;
+ /* 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 ");
+ }
+
+ len = 0;
+
+ while (len < length) {
+ uint64_t total;
+ unsigned int chunkLen = length - len;
+ if (6 <= chunkLen) /* Take groups of 6 */ {
+ chunkLen = 6;
+ len += chunkLen;
+#if defined(_MSC_VER) && _MSC_VER == 1200
+ total = 0;
+#else
+ total = 0ULL;
+#endif
+
+ while (chunkLen--) {
+ uint64_t mantisa = chaine[start++];
+#if defined(_MSC_VER) && _MSC_VER == 1200
+ total |= mantisa << (uint64_t) (chunkLen * 8);
+#else
+ total |= mantisa << (uint64_t) (chunkLen * 8ULL);
+#endif
+ }
+
+ chunkLen = 5;
+
+ while (chunkLen--) {
+#if defined(_MSC_VER) && _MSC_VER == 1200
+ chainemc[*mclength + chunkLen] = (int) (total % 900);
+ total /= 900;
+#else
+ chainemc[*mclength + chunkLen] = (int) (total % 900ULL);
+ total /= 900ULL;
+#endif
+ }
+ *mclength += 5;
+ } else /* If it remain a group of less than 6 bytes */ {
+ len += chunkLen;
+ while (chunkLen--) {
+ chainemc[(*mclength)++] = chaine[start++];
+ }
+ }
+ }
+ }
+}
+
+/* 712 */
+static void numbprocess(int *chainemc, int *mclength, char chaine[], int start, int length) {
+ int j, loop, dummy[100], 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) {
+ int longueur;
+ int dumlength = 0;
+ strcpy(chainemod, "");
+ longueur = length - j;
+ if (longueur > 44) {
+ longueur = 44;
+ }
+ strcat(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 < (int)strlen(chainemod); loop++) {
+ chainemod[loop] = chainemod[loop + 1];
+ }
+ if (nombre < diviseur) {
+ if (strlen(chainemult) != 0) {
+ strcat(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 */
+static int pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size_t length) {
+ int i, k, j, indexchaine, indexliste, mode, longueur, loop, mccorrection[520], offset;
+ int total, chainemc[PDF417_MAX_LEN], mclength, c1, c2, c3, dummy[35], calcheight;
+ char pattern[580];
+ int debug = symbol->debug;
+
+ if (length > PDF417_MAX_LEN) {
+ return 2;
+ }
+
+ /* 456 */
+ indexliste = 0;
+ indexchaine = 0;
+
+ mode = quelmode(chaine[indexchaine]);
+
+ for (i = 0; i < PDF417_MAX_LEN; i++) {
+ liste[0][i] = 0;
+ }
+
+ /* 463 */
+ do {
+ liste[1][indexliste] = mode;
+ while ((liste[1][indexliste] == mode) && (indexchaine < (int)length)) {
+ liste[0][indexliste]++;
+ indexchaine++;
+ mode = quelmode(chaine[indexchaine]);
+ }
+ indexliste++;
+ } while (indexchaine < (int)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++;
+ }
+
+ if (symbol->eci != 0) {
+ /* Encoding ECI assignment number, according to Table 8 */
+ if (symbol->eci <= 899) {
+ chainemc[mclength] = 927; /* ECI */
+ mclength++;
+ chainemc[mclength] = symbol->eci;
+ mclength++;
+ }
+ if ((symbol->eci >= 900) && (symbol->eci <= 810899)) {
+ chainemc[mclength] = 926; /* ECI */
+ mclength++;
+ chainemc[mclength] = (symbol->eci / 900) - 1;
+ mclength++;
+ chainemc[mclength] = symbol->eci % 900;
+ mclength++;
+ }
+ if (symbol->eci >= 810900) {
+ chainemc[mclength] = 925; /* ECI */
+ mclength++;
+ chainemc[mclength] = symbol->eci - 810900;
+ mclength++;
+ }
+ }
+
+ if (symbol->eci > 811799) {
+ strcpy(symbol->errtxt, "472: Invalid ECI");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ for (i = 0; i < indexliste; i++) {
+ switch (liste[1][i]) {
+ case TEX: /* 547 - text mode */
+ textprocess(chainemc, &mclength, (char*) chaine, indexchaine, liste[0][i]);
+ break;
+ case BYT: /* 670 - octet stream mode */
+ byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i]);
+ break;
+ case NUM: /* 712 - numeric mode */
+ numbprocess(chainemc, &mclength, (char*) chaine, indexchaine, liste[0][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) {
+ symbol->option_1 = 6;
+ if (mclength <= 863) {
+ symbol->option_1 = 5;
+ }
+ if (mclength <= 320) {
+ symbol->option_1 = 4;
+ }
+ if (mclength <= 160) {
+ symbol->option_1 = 3;
+ }
+ if (mclength <= 40) {
+ symbol->option_1 = 2;
+ }
+ }
+ 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) {
+ symbol->option_2 =(int)(0.5 + sqrt((longueur + k) / 3.0));
+ }
+ if (((longueur + k) / symbol->option_2) > 90) {
+ /* stop the symbol from becoming too high */
+ symbol->option_2 = symbol->option_2 + 1;
+ }
+
+ if (longueur + k > 928) {
+ /* Enforce maximum codeword limit */
+ 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;
+ }
+
+ if (debug) {
+ printf("Complete CW string:\n");
+ for (i = 0; i < mclength; i++) {
+ printf("%d ", chainemc[i]);
+ }
+ printf("\n");
+ }
+
+ /* 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) {
+ case 0:
+ dummy[0] = k + c1;
+ dummy[symbol->option_2 + 1] = k + c3;
+ offset = 0; /* cluster(0) */
+ break;
+ case 1:
+ dummy[0] = k + c2;
+ dummy[symbol->option_2 + 1] = k + c1;
+ offset = 929; /* cluster(3) */
+ break;
+ case 2:
+ dummy[0] = k + c3;
+ dummy[symbol->option_2 + 1] = k + c2;
+ offset = 1858; /* cluster(6) */
+ break;
+ }
+ strcpy(pattern, "");
+ bin_append(0x1FEA8, 17, pattern); /* Row start */
+
+ for (j = 0; j <= symbol->option_2; j++) {
+ bin_append(pdf_bitpattern[offset + dummy[j]], 16, pattern);
+ strcat(pattern, "0");
+ }
+
+ if (symbol->symbology != BARCODE_PDF417TRUNC) {
+ bin_append(pdf_bitpattern[offset + dummy[j]], 16, pattern);
+ strcat(pattern, "0");
+ bin_append(0x3FA29, 18, pattern); /* Row Stop */
+ }
+
+ for (loop = 0; loop < (int)strlen(pattern); loop++) {
+ if (pattern[loop] == '1') {
+ set_module(symbol, i, loop);
+ }
+ }
+ }
+
+ /* Allow user to adjust height of symbol, but enforce minimum row height of 3X */
+ calcheight = (int)(symbol->height / i);
+ if (calcheight < 3) {
+ calcheight = 3;
+ }
+
+ for (j = 0; j < i; j++) {
+ symbol->row_height[j] = calcheight;
+ }
+
+ symbol->rows = (mclength / symbol->option_2);
+ symbol->width =(int)strlen(pattern);
+
+ /* 843 */
+ return 0;
+}
+
+/* 345 */
+INTERNAL int pdf417enc(struct zint_symbol *symbol, unsigned char source[], const size_t length) {
+ int codeerr, error_number;
+
+ error_number = 0;
+
+ if ((symbol->option_1 < -1) || (symbol->option_1 > 8)) {
+ strcpy(symbol->errtxt, "460: Security value out of range");
+ symbol->option_1 = -1;
+ error_number = ZINT_WARN_INVALID_OPTION;
+ }
+ if ((symbol->option_2 < 0) || (symbol->option_2 > 30)) {
+ strcpy(symbol->errtxt, "461: Number of columns out of range");
+ symbol->option_2 = 0;
+ error_number = ZINT_WARN_INVALID_OPTION;
+ }
+
+ /* 349 */
+ codeerr = pdf417(symbol, source, length);
+
+ /* 352 */
+ if (codeerr != 0) {
+ switch (codeerr) {
+ case 1:
+ strcpy(symbol->errtxt, "462: No such file or file unreadable");
+ error_number = ZINT_ERROR_INVALID_OPTION;
+ break;
+ case 2:
+ strcpy(symbol->errtxt, "463: Input string too long");
+ error_number = ZINT_ERROR_TOO_LONG;
+ break;
+ case 3:
+ strcpy(symbol->errtxt, "464: Number of codewords per row too small");
+ error_number = ZINT_WARN_INVALID_OPTION;
+ break;
+ case 4:
+ strcpy(symbol->errtxt, "465: Data too long for specified number of columns");
+ error_number = ZINT_ERROR_TOO_LONG;
+ break;
+ case ZINT_ERROR_INVALID_OPTION:
+ error_number = codeerr;
+ break;
+ default:
+ strcpy(symbol->errtxt, "466: Something strange happened");
+ error_number = ZINT_ERROR_ENCODING_PROBLEM;
+ break;
+ }
+ }
+
+ /* 364 */
+ return error_number;
+}
+
+/* like PDF417 only much smaller! */
+INTERNAL int micro_pdf417(struct zint_symbol *symbol, unsigned char chaine[], const size_t length) {
+ int i, k, j, indexchaine, indexliste, mode, longueur, mccorrection[50], offset;
+ int total, chainemc[PDF417_MAX_LEN], mclength, dummy[5], codeerr;
+ char pattern[580];
+ int variant, LeftRAPStart, CentreRAPStart, RightRAPStart, StartCluster;
+ int LeftRAP, CentreRAP, RightRAP, Cluster, loop, calcheight;
+ int debug = 0;
+
+ if (length > MICRO_PDF417_MAX_LEN) {
+ strcpy(symbol->errtxt, "474: Input data too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ /* 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 < PDF417_MAX_LEN; i++) {
+ liste[0][i] = 0;
+ }
+
+ /* 463 */
+ do {
+ liste[1][indexliste] = mode;
+ while ((liste[1][indexliste] == mode) && (indexchaine < (int)length)) {
+ liste[0][indexliste]++;
+ indexchaine++;
+ mode = quelmode(chaine[indexchaine]);
+ }
+ indexliste++;
+ } while (indexchaine < (int)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++;
+ }
+
+ if (symbol->eci > 811799) {
+ strcpy(symbol->errtxt, "473: Invalid ECI");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ if (symbol->eci != 0) {
+ /* Encoding ECI assignment number, according to Table 8 */
+ if (symbol->eci <= 899) {
+ chainemc[mclength] = 927; /* ECI */
+ mclength++;
+ chainemc[mclength] = symbol->eci;
+ mclength++;
+ }
+ if ((symbol->eci >= 900) && (symbol->eci <= 810899)) {
+ chainemc[mclength] = 926; /* ECI */
+ mclength++;
+ chainemc[mclength] = (symbol->eci / 900) - 1;
+ mclength++;
+ chainemc[mclength] = symbol->eci % 900;
+ mclength++;
+ }
+ if (symbol->eci >= 810900) {
+ chainemc[mclength] = 925; /* ECI */
+ mclength++;
+ chainemc[mclength] = symbol->eci - 810900;
+ 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]);
+ break;
+ case BYT: /* 670 - octet stream mode */
+ byteprocess(chainemc, &mclength, chaine, indexchaine, liste[0][i]);
+ break;
+ case NUM: /* 712 - numeric mode */
+ numbprocess(chainemc, &mclength, (char*) chaine, indexchaine, liste[0][i]);
+ break;
+ }
+ indexchaine = indexchaine + liste[0][i];
+ }
+
+ /* This is where it all changes! */
+
+ if (mclength > 126) {
+ strcpy(symbol->errtxt, "467: Input data too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ if (symbol->option_2 > 4) {
+ strcpy(symbol->errtxt, "468: Specified width out of range");
+ symbol->option_2 = 0;
+ codeerr = ZINT_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, "469: Specified symbol size too small for data");
+ codeerr = ZINT_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, "470: Specified symbol size too small for data");
+ codeerr = ZINT_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, "471: Specified symbol size too small for data");
+ codeerr = ZINT_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(pattern, "");
+ 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 */
+ bin_append(rap_side[LeftRAP - 1], 10, pattern);
+ bin_append(pdf_bitpattern[offset + dummy[1]], 16, pattern);
+ strcat(pattern, "0");
+ if (symbol->option_2 == 3) {
+ bin_append(rap_centre[CentreRAP - 1], 10, pattern);
+ }
+ if (symbol->option_2 >= 2) {
+ bin_append(pdf_bitpattern[offset + dummy[2]], 16, pattern);
+ strcat(pattern, "0");
+ }
+ if (symbol->option_2 == 4) {
+ bin_append(rap_centre[CentreRAP - 1], 10, pattern);
+ }
+ if (symbol->option_2 >= 3) {
+ bin_append(pdf_bitpattern[offset + dummy[3]], 16, pattern);
+ strcat(pattern, "0");
+ }
+ if (symbol->option_2 == 4) {
+ bin_append(pdf_bitpattern[offset + dummy[4]], 16, pattern);
+ strcat(pattern, "0");
+ }
+ bin_append(rap_side[RightRAP - 1], 10, pattern);
+ strcat(pattern, "1"); /* stop */
+ if (debug) printf("%s\n", pattern);
+
+ /* so now pattern[] holds the string of '1's and '0's. - copy this to the symbol */
+ for (loop = 0; loop < (int)strlen(pattern); loop++) {
+ if (pattern[loop] == '1') {
+ set_module(symbol, i, loop);
+ }
+ }
+ symbol->row_height[i] = 2;
+ symbol->width = strlen(pattern);
+
+ /* 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;
+ }
+ }
+
+ /* Allow user to adjust height of symbol, but enforce minimum row height of 2X */
+ calcheight = (int)(symbol->height / i);
+ if (calcheight < 2) {
+ calcheight = 2;
+ }
+
+ for (j = 0; j < i; j++) {
+ symbol->row_height[j] = calcheight;
+ }
+
+ return codeerr;
+}
diff --git a/backend/pdf417.h b/backend/pdf417.h
new file mode 100644
index 0000000..90e8b4a
--- /dev/null
+++ b/backend/pdf417.h
@@ -0,0 +1,514 @@
+/* pdf417.h - PDF417 tables and coefficients */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008-2017 Robin Stuart <rstuart114@gmail.com>
+ Portions Copyright (C) 2004 Grandzebu
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+
+/* 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
+
+/* PDF417 error correction coefficients from Grand Zebu */
+static const unsigned short 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 const unsigned short int pdf_bitpattern[2787] = {
+ 0xEAE0, 0xF578, 0xFABE, 0xEA70, 0xF53C, 0xFA9F, 0xD460, 0xEA38, 0xD430, 0xA820,
+ 0xD418, 0xA810, 0xD6E0, 0xEB78, 0xF5BE, 0xD670, 0xEB3C, 0xF59F, 0xAC60, 0xD638,
+ 0xAC30, 0xAEE0, 0xD778, 0xEBBE, 0xAE70, 0xD73C, 0xEB9F, 0xAE38, 0xD71E, 0xAF78,
+ 0xD7BE, 0xAF3C, 0xD79F, 0xAFBE, 0xFAFD, 0xE970, 0xF4BC, 0xFA5F, 0xD260, 0xE938,
+ 0xF49E, 0xD230, 0xE91C, 0xA420, 0xD218, 0xE90E, 0xA410, 0xD20C, 0xA408, 0xD370,
+ 0xE9BC, 0xF4DF, 0xA660, 0xD338, 0xE99E, 0xA630, 0xD31C, 0xE98F, 0xA618, 0xD30E,
+ 0xA770, 0xD3BC, 0xE9DF, 0xA738, 0xD39E, 0xA71C, 0xD38F, 0xA7BC, 0xD3DF, 0xA79E,
+ 0xA78F, 0xD160, 0xE8B8, 0xF45E, 0xD130, 0xE89C, 0xF44F, 0xA220, 0xD118, 0xE88E,
+ 0xA210, 0xD10C, 0xA208, 0xA204, 0xA360, 0xD1B8, 0xE8DE, 0xA330, 0xD19C, 0xE8CF,
+ 0xA318, 0xD18E, 0xA30C, 0xA306, 0xA3B8, 0xD1DE, 0xA39C, 0xD1CF, 0xA38E, 0xA3DE,
+ 0xD0B0, 0xE85C, 0xF42F, 0xA120, 0xD098, 0xE84E, 0xA110, 0xD08C, 0xE847, 0xA108,
+ 0xD086, 0xA104, 0xD083, 0xA1B0, 0xD0DC, 0xE86F, 0xA198, 0xD0CE, 0xA18C, 0xD0C7,
+ 0xA186, 0xA183, 0xD0EF, 0xA1C7, 0xA0A0, 0xD058, 0xE82E, 0xA090, 0xD04C, 0xE827,
+ 0xA088, 0xD046, 0xA084, 0xD043, 0xA082, 0xA0D8, 0xA0CC, 0xA0C6, 0xA050, 0xE817,
+ 0xD026, 0xD023, 0xA041, 0xE570, 0xF2BC, 0xF95F, 0xCA60, 0xE538, 0xF29E, 0xCA30,
+ 0xE51C, 0xF28F, 0x9420, 0xCA18, 0x9410, 0xCB70, 0xE5BC, 0xF2DF, 0x9660, 0xCB38,
+ 0xE59E, 0x9630, 0xCB1C, 0x9618, 0x960C, 0x9770, 0xCBBC, 0xE5DF, 0x9738, 0xCB9E,
+ 0x971C, 0x970E, 0x97BC, 0xCBDF, 0x979E, 0x97DF, 0xED60, 0xF6B8, 0xFB5E, 0xED30,
+ 0xF69C, 0xFB4F, 0xDA20, 0xED18, 0xF68E, 0xDA10, 0xED0C, 0xF687, 0xDA08, 0xED06,
+ 0xC960, 0xE4B8, 0xF25E, 0xDB60, 0xC930, 0xE49C, 0xF24F, 0xDB30, 0xED9C, 0xF6CF,
+ 0xB620, 0x9210, 0xC90C, 0xE487, 0xB610, 0xDB0C, 0xB608, 0x9360, 0xC9B8, 0xE4DE,
+ 0xB760, 0x9330, 0xC99C, 0xE4CF, 0xB730, 0xDB9C, 0xEDCF, 0xB718, 0x930C, 0xB70C,
+ 0x93B8, 0xC9DE, 0xB7B8, 0x939C, 0xC9CF, 0xB79C, 0xDBCF, 0xB78E, 0x93DE, 0xB7DE,
+ 0x93CF, 0xB7CF, 0xECB0, 0xF65C, 0xFB2F, 0xD920, 0xEC98, 0xF64E, 0xD910, 0xEC8C,
+ 0xF647, 0xD908, 0xEC86, 0xD904, 0xD902, 0xC8B0, 0xE45C, 0xF22F, 0xD9B0, 0xC898,
+ 0xE44E, 0xB320, 0x9110, 0xECCE, 0xE447, 0xB310, 0x9108, 0xC886, 0xB308, 0xD986,
+ 0xC883, 0x9102, 0x91B0, 0xC8DC, 0xE46F, 0xB3B0, 0x9198, 0xC8CE, 0xB398, 0xD9CE,
+ 0xC8C7, 0xB38C, 0x9186, 0x9183, 0x91DC, 0xC8EF, 0xB3DC, 0x91CE, 0xB3CE, 0x91C7,
+ 0xB3C7, 0xB3EF, 0xD8A0, 0xEC58, 0xF62E, 0xD890, 0xEC4C, 0xF627, 0xD888, 0xEC46,
+ 0xD884, 0xEC43, 0xD882, 0xD881, 0x90A0, 0xC858, 0xE42E, 0xB1A0, 0x9090, 0xC84C,
+ 0xE427, 0xB190, 0xD8CC, 0xEC67, 0xB188, 0x9084, 0xC843, 0xB184, 0xD8C3, 0xB182,
+ 0x90D8, 0xC86E, 0xB1D8, 0x90CC, 0xC867, 0xB1CC, 0xD8E7, 0xB1C6, 0x90C3, 0xB1C3,
+ 0xB1EE, 0xB1E7, 0xD850, 0xEC2C, 0xF617, 0xD848, 0xEC26, 0xD844, 0xEC23, 0xD842,
+ 0xD841, 0x9050, 0xC82C, 0xE417, 0xB0D0, 0x9048, 0xC826, 0xB0C8, 0xD866, 0xC823,
+ 0xB0C4, 0x9042, 0xB0C2, 0x9041, 0x906C, 0xB0EC, 0xB0E6, 0xB0E3, 0xEC16, 0xEC13,
+ 0xD821, 0xC816, 0x9024, 0xB064, 0xB062, 0xB061, 0xC560, 0xE2B8, 0xF15E, 0xC530,
+ 0xE29C, 0x8A20, 0xC518, 0xE28E, 0x8A10, 0xC50C, 0x8A08, 0x8A04, 0x8B60, 0xC5B8,
+ 0xE2DE, 0x8B30, 0xC59C, 0xE2CF, 0x8B18, 0xC58E, 0x8B0C, 0x8B06, 0x8BB8, 0xC5DE,
+ 0x8B9C, 0xC5CF, 0x8B8E, 0x8BDE, 0x8BCF, 0xE6B0, 0xF35C, 0xF9AF, 0xCD20, 0xE698,
+ 0xF34E, 0xCD10, 0xE68C, 0xF347, 0xCD08, 0xE686, 0xCD04, 0xE683, 0xC4B0, 0xE25C,
+ 0xF12F, 0xCDB0, 0xC498, 0xE24E, 0x9B20, 0x8910, 0xE6CE, 0xE247, 0x9B10, 0xCD8C,
+ 0xC486, 0x9B08, 0x8904, 0x9B04, 0x89B0, 0xC4DC, 0xE26F, 0x9BB0, 0x8998, 0xE6EF,
+ 0x9B98, 0xCDCE, 0xC4C7, 0x9B8C, 0x8986, 0x9B86, 0x89DC, 0xC4EF, 0x9BDC, 0x89CE,
+ 0x9BCE, 0x89C7, 0x89EF, 0x9BEF, 0xEEA0, 0xF758, 0xFBAE, 0xEE90, 0xF74C, 0xFBA7,
+ 0xEE88, 0xF746, 0xEE84, 0xF743, 0xEE82, 0xCCA0, 0xE658, 0xF32E, 0xDDA0, 0xCC90,
+ 0xF76E, 0xF327, 0xDD90, 0xEECC, 0xF767, 0xDD88, 0xCC84, 0xE643, 0xDD84, 0xEEC3,
+ 0xCC81, 0x88A0, 0xC458, 0xE22E, 0x99A0, 0x8890, 0xC44C, 0xE227, 0xBBA0, 0x9990,
+ 0xCCCC, 0xE667, 0xBB90, 0xDDCC, 0xEEE7, 0xC443, 0xBB88, 0x9984, 0xCCC3, 0xBB84,
+ 0x8881, 0x88D8, 0xC46E, 0x99D8, 0x88CC, 0xC467, 0xBBD8, 0x99CC, 0xCCE7, 0xBBCC,
+ 0xDDE7, 0x88C3, 0x99C3, 0x88EE, 0x99EE, 0x88E7, 0xBBEE, 0x99E7, 0xEE50, 0xF72C,
+ 0xFB97, 0xEE48, 0xF726, 0xEE44, 0xF723, 0xEE42, 0xEE41, 0xCC50, 0xE62C, 0xF317,
+ 0xDCD0, 0xCC48, 0xF737, 0xDCC8, 0xEE66, 0xE623, 0xDCC4, 0xCC42, 0xDCC2, 0xCC41,
+ 0xDCC1, 0x8850, 0xC42C, 0xE217, 0x98D0, 0x8848, 0xC426, 0xB9D0, 0x98C8, 0xCC66,
+ 0xC423, 0xB9C8, 0xDCE6, 0x8842, 0xB9C4, 0x98C2, 0x8841, 0x98C1, 0x886C, 0xC437,
+ 0x98EC, 0x8866, 0xB9EC, 0x98E6, 0x8863, 0xB9E6, 0x98E3, 0x8877, 0xB9F7, 0xEE28,
+ 0xF716, 0xEE24, 0xF713, 0xEE22, 0xEE21, 0xCC28, 0xE616, 0xDC68, 0xCC24, 0xE613,
+ 0xDC64, 0xEE33, 0xDC62, 0xCC21, 0xDC61, 0x8828, 0xC416, 0x9868, 0x8824, 0xC413,
+ 0xB8E8, 0x9864, 0xCC33, 0xB8E4, 0xDC73, 0x8821, 0xB8E2, 0x9861, 0xB8E1, 0x9876,
+ 0xB8F6, 0xB8F3, 0xF70B, 0xEE11, 0xE60B, 0xCC12, 0xCC11, 0x8814, 0x9834, 0xB874,
+ 0x8811, 0x9831, 0xC2B0, 0x8520, 0xC298, 0x8510, 0xC28C, 0xE147, 0x8508, 0xC286,
+ 0x8504, 0xC283, 0x85B0, 0xC2DC, 0xE16F, 0x8598, 0xC2CE, 0x858C, 0xC2C7, 0x8586,
+ 0x8583, 0x85DC, 0xC2EF, 0x85CE, 0x85C7, 0x85EF, 0xC6A0, 0xE358, 0xF1AE, 0xC690,
+ 0xE34C, 0xC688, 0xE346, 0xC684, 0xE343, 0xC682, 0x84A0, 0xC258, 0xE12E, 0x8DA0,
+ 0x8490, 0xE36E, 0xE127, 0x8D90, 0xC6CC, 0xE367, 0x8D88, 0x8484, 0xC243, 0x8D84,
+ 0xC6C3, 0x8481, 0x84D8, 0xC26E, 0x8DD8, 0x84CC, 0xC267, 0x8DCC, 0xC6E7, 0x8DC6,
+ 0x84C3, 0x84EE, 0x8DEE, 0x84E7, 0x8DE7, 0xE750, 0xF3AC, 0xF9D7, 0xE748, 0xF3A6,
+ 0xE744, 0xF3A3, 0xE742, 0xE741, 0xC650, 0xE32C, 0xCED0, 0xC648, 0xE326, 0xCEC8,
+ 0xE766, 0xE323, 0xCEC4, 0xC642, 0xCEC2, 0xC641, 0xCEC1, 0x8450, 0xC22C, 0x8CD0,
+ 0x8448, 0xE337, 0x9DD0, 0x8CC8, 0xC666, 0xC223, 0x9DC8, 0xCEE6, 0x8442, 0x9DC4,
+ 0x8CC2, 0x8441, 0x8CC1, 0x846C, 0xC237, 0x8CEC, 0x8466, 0x9DEC, 0x8CE6, 0x8463,
+ 0x9DE6, 0x8CE3, 0x8477, 0x8CF7, 0x9DF7, 0xF7A8, 0xFBD6, 0xF7A4, 0xFBD3, 0xF7A2,
+ 0xF7A1, 0xE728, 0xF396, 0xEF68, 0xF7B6, 0xF393, 0xEF64, 0xF7B3, 0xEF62, 0xE721,
+ 0xEF61, 0xC628, 0xE316, 0xCE68, 0xC624, 0xE313, 0xDEE8, 0xCE64, 0xE733, 0xDEE4,
+ 0xEF73, 0xC621, 0xDEE2, 0xCE61, 0xDEE1, 0x8428, 0xC216, 0x8C68, 0x8424, 0xC213,
+ 0x9CE8, 0x8C64, 0xC633, 0xBDE8, 0x9CE4, 0xCE73, 0x8421, 0xBDE4, 0xDEF3, 0x8C61,
+ 0xBDE2, 0x8436, 0x8C76, 0x8433, 0x9CF6, 0x8C73, 0xBDF6, 0x9CF3, 0xBDF3, 0xF794,
+ 0xFBCB, 0xF792, 0xF791, 0xE714, 0xF38B, 0xEF34, 0xF79B, 0xEF32, 0xE711, 0xEF31,
+ 0xC614, 0xE30B, 0xCE34, 0xC612, 0xDE74, 0xCE32, 0xC611, 0xDE72, 0xCE31, 0xDE71,
+ 0x8414, 0xC20B, 0x8C34, 0xC61B, 0x9C74, 0x8C32, 0x8411, 0xBCF4, 0x9C72, 0x8C31,
+ 0xBCF2, 0x9C71, 0xBCF1, 0x8C3B, 0xBCFB, 0xF789, 0xEF1A, 0xEF19, 0xCE1A, 0xDE3A,
+ 0xDE39, 0x8C1A, 0x9C3A, 0xBC7A, 0xBC79, 0x82A0, 0x8290, 0xC14C, 0x8288, 0x8284,
+ 0x8282, 0x82D8, 0x82CC, 0x82C6, 0x82C3, 0x82EE, 0x82E7, 0xC350, 0xC348, 0xE1A6,
+ 0xC344, 0xE1A3, 0xC342, 0xC341, 0x8250, 0xC12C, 0x86D0, 0xC36C, 0xC126, 0x86C8,
+ 0xC366, 0x86C4, 0xC363, 0x86C2, 0x8241, 0x86C1, 0x826C, 0xC137, 0x86EC, 0xC377,
+ 0x86E6, 0x8263, 0x86E3, 0x8277, 0x86F7, 0xE3A8, 0xE3A4, 0xE3A2, 0xE3A1, 0xC328,
+ 0xC768, 0xE3B6, 0xE193, 0xC764, 0xE3B3, 0xC762, 0xC321, 0xC761, 0x8228, 0x8668,
+ 0x8224, 0xC113, 0x8EE8, 0x8664, 0x8222, 0x8EE4, 0x8662, 0x8221, 0x8EE2, 0x8661,
+ 0x8236, 0x8676, 0x8233, 0x8EF6, 0x8673, 0x8EF3, 0xF3D4, 0xF3D2, 0xF3D1, 0xE394,
+ 0xE7B4, 0xF3DB, 0xE7B2, 0xE391, 0xE7B1, 0xC314, 0xE18B, 0xC734, 0xE39B, 0xCF74,
+ 0xC732, 0xC311, 0xCF72, 0xC731, 0xCF71, 0x8214, 0xC10B, 0x8634, 0xC31B, 0x8E74,
+ 0x8632, 0x8211, 0x9EF4, 0x8E72, 0x8631, 0x9EF2, 0x8E71, 0x821B, 0x863B, 0x8E7B,
+ 0x9EFB, 0xFBEA, 0xFBE9, 0xF3CA, 0xF7DA, 0xF3C9, 0xF7D9, 0xE38A, 0xE79A, 0xE389,
+ 0xEFBA, 0xE799, 0xEFB9, 0xC30A, 0xC71A, 0xC309, 0xCF3A, 0xC719, 0xDF7A, 0xFAB0,
+ 0xFD5C, 0xF520, 0xFA98, 0xFD4E, 0xF510, 0xFA8C, 0xFD47, 0xF508, 0xFA86, 0xF504,
+ 0xFA83, 0xF502, 0xF5B0, 0xFADC, 0xFD6F, 0xEB20, 0xF598, 0xFACE, 0xEB10, 0xF58C,
+ 0xFAC7, 0xEB08, 0xF586, 0xEB04, 0xF583, 0xEB02, 0xEBB0, 0xF5DC, 0xFAEF, 0xD720,
+ 0xEB98, 0xF5CE, 0xD710, 0xEB8C, 0xF5C7, 0xD708, 0xEB86, 0xD704, 0xEB83, 0xD702,
+ 0xD7B0, 0xEBDC, 0xF5EF, 0xAF20, 0xD798, 0xEBCE, 0xAF10, 0xD78C, 0xEBC7, 0xAF08,
+ 0xD786, 0xAF04, 0xD783, 0xAFB0, 0xD7DC, 0xEBEF, 0xAF98, 0xD7CE, 0xAF8C, 0xD7C7,
+ 0xAF86, 0xAFDC, 0xD7EF, 0xAFCE, 0xAFC7, 0xF4A0, 0xFA58, 0xFD2E, 0xF490, 0xFA4C,
+ 0xFD27, 0xF488, 0xFA46, 0xF484, 0xFA43, 0xF482, 0xF481, 0xE9A0, 0xF4D8, 0xFA6E,
+ 0xE990, 0xF4CC, 0xFA67, 0xE988, 0xF4C6, 0xE984, 0xF4C3, 0xE982, 0xE981, 0xD3A0,
+ 0xE9D8, 0xF4EE, 0xD390, 0xE9CC, 0xF4E7, 0xD388, 0xE9C6, 0xD384, 0xE9C3, 0xD382,
+ 0xD381, 0xA7A0, 0xD3D8, 0xE9EE, 0xA790, 0xD3CC, 0xE9E7, 0xA788, 0xD3C6, 0xA784,
+ 0xD3C3, 0xA782, 0xA7D8, 0xD3EE, 0xA7CC, 0xD3E7, 0xA7C6, 0xA7C3, 0xA7EE, 0xA7E7,
+ 0xF450, 0xFA2C, 0xFD17, 0xF448, 0xFA26, 0xF444, 0xFA23, 0xF442, 0xF441, 0xE8D0,
+ 0xF46C, 0xFA37, 0xE8C8, 0xF466, 0xE8C4, 0xF463, 0xE8C2, 0xE8C1, 0xD1D0, 0xE8EC,
+ 0xF477, 0xD1C8, 0xE8E6, 0xD1C4, 0xE8E3, 0xD1C2, 0xD1C1, 0xA3D0, 0xD1EC, 0xE8F7,
+ 0xA3C8, 0xD1E6, 0xA3C4, 0xD1E3, 0xA3C2, 0xA3C1, 0xA3EC, 0xD1F7, 0xA3E6, 0xA3E3,
+ 0xA3F7, 0xF428, 0xFA16, 0xF424, 0xFA13, 0xF422, 0xF421, 0xE868, 0xF436, 0xE864,
+ 0xF433, 0xE862, 0xE861, 0xD0E8, 0xE876, 0xD0E4, 0xE873, 0xD0E2, 0xD0E1, 0xA1E8,
+ 0xD0F6, 0xA1E4, 0xD0F3, 0xA1E2, 0xA1E1, 0xA1F6, 0xA1F3, 0xF414, 0xFA0B, 0xF412,
+ 0xF411, 0xE834, 0xF41B, 0xE832, 0xE831, 0xD074, 0xE83B, 0xD072, 0xD071, 0xA0F4,
+ 0xD07B, 0xA0F2, 0xA0F1, 0xF40A, 0xF409, 0xE81A, 0xE819, 0xD03A, 0xD039, 0xF2A0,
+ 0xF958, 0xFCAE, 0xF290, 0xF94C, 0xFCA7, 0xF288, 0xF946, 0xF284, 0xF943, 0xF282,
+ 0xF281, 0xE5A0, 0xF2D8, 0xF96E, 0xE590, 0xF2CC, 0xF967, 0xE588, 0xF2C6, 0xE584,
+ 0xF2C3, 0xE582, 0xE581, 0xCBA0, 0xE5D8, 0xF2EE, 0xCB90, 0xE5CC, 0xF2E7, 0xCB88,
+ 0xE5C6, 0xCB84, 0xE5C3, 0xCB82, 0xCB81, 0x97A0, 0xCBD8, 0xE5EE, 0x9790, 0xCBCC,
+ 0xE5E7, 0x9788, 0xCBC6, 0x9784, 0xCBC3, 0x9782, 0x97D8, 0xCBEE, 0x97CC, 0xCBE7,
+ 0x97C6, 0x97C3, 0x97EE, 0x97E7, 0xFB50, 0xFDAC, 0xB5F8, 0xFB48, 0xFDA6, 0xB4FC,
+ 0xFB44, 0xFDA3, 0xB47E, 0xFB42, 0xFB41, 0xF250, 0xF92C, 0xFC97, 0xF6D0, 0xF248,
+ 0xFDB7, 0xF6C8, 0xFB66, 0xF923, 0xF6C4, 0xF242, 0xF6C2, 0xF241, 0xF6C1, 0xE4D0,
+ 0xF26C, 0xF937, 0xEDD0, 0xE4C8, 0xF266, 0xEDC8, 0xF6E6, 0xF263, 0xEDC4, 0xE4C2,
+ 0xEDC2, 0xE4C1, 0xEDC1, 0xC9D0, 0xE4EC, 0xF277, 0xDBD0, 0xC9C8, 0xE4E6, 0xDBC8,
+ 0xEDE6, 0xE4E3, 0xDBC4, 0xC9C2, 0xDBC2, 0xC9C1, 0xDBC1, 0x93D0, 0xC9EC, 0xE4F7,
+ 0xB7D0, 0x93C8, 0xC9E6, 0xB7C8, 0xDBE6, 0xC9E3, 0xB7C4, 0x93C2, 0xB7C2, 0x93C1,
+ 0x93EC, 0xC9F7, 0xB7EC, 0x93E6, 0xB7E6, 0x93E3, 0xB7E3, 0x93F7, 0xFB28, 0xFD96,
+ 0xB2FC, 0xFB24, 0xFD93, 0xB27E, 0xFB22, 0xB23F, 0xFB21, 0xF228, 0xF916, 0xF668,
+ 0xF224, 0xF913, 0xF664, 0xFB33, 0xF662, 0xF221, 0xF661, 0xE468, 0xF236, 0xECE8,
+ 0xE464, 0xF233, 0xECE4, 0xF673, 0xECE2, 0xE461, 0xECE1, 0xC8E8, 0xE476, 0xD9E8,
+ 0xC8E4, 0xE473, 0xD9E4, 0xECF3, 0xD9E2, 0xC8E1, 0xD9E1, 0x91E8, 0xC8F6, 0xB3E8,
+ 0x91E4, 0xC8F3, 0xB3E4, 0xD9F3, 0xB3E2, 0x91E1, 0xB3E1, 0x91F6, 0xB3F6, 0x91F3,
+ 0xB3F3, 0xFB14, 0xFD8B, 0xB17E, 0xFB12, 0xB13F, 0xFB11, 0xF214, 0xF90B, 0xF634,
+ 0xFB1B, 0xF632, 0xF211, 0xF631, 0xE434, 0xF21B, 0xEC74, 0xE432, 0xEC72, 0xE431,
+ 0xEC71, 0xC874, 0xE43B, 0xD8F4, 0xEC7B, 0xD8F2, 0xC871, 0xD8F1, 0x90F4, 0xC87B,
+ 0xB1F4, 0x90F2, 0xB1F2, 0x90F1, 0xB1F1, 0x90FB, 0xB1FB, 0xFB0A, 0xB0BF, 0xFB09,
+ 0xF20A, 0xF61A, 0xF209, 0xF619, 0xE41A, 0xEC3A, 0xE419, 0xEC39, 0xC83A, 0xD87A,
+ 0xC839, 0xD879, 0x907A, 0xB0FA, 0x9079, 0xB0F9, 0xFB05, 0xF205, 0xF60D, 0xE40D,
+ 0xEC1D, 0xC81D, 0xD83D, 0xF150, 0xF8AC, 0xFC57, 0xF148, 0xF8A6, 0xF144, 0xF8A3,
+ 0xF142, 0xF141, 0xE2D0, 0xF16C, 0xF8B7, 0xE2C8, 0xF166, 0xE2C4, 0xF163, 0xE2C2,
+ 0xE2C1, 0xC5D0, 0xE2EC, 0xF177, 0xC5C8, 0xE2E6, 0xC5C4, 0xE2E3, 0xC5C2, 0xC5C1,
+ 0x8BD0, 0xC5EC, 0xE2F7, 0x8BC8, 0xC5E6, 0x8BC4, 0xC5E3, 0x8BC2, 0x8BC1, 0x8BEC,
+ 0xC5F7, 0x8BE6, 0x8BE3, 0x8BF7, 0xF9A8, 0xFCD6, 0x9AFC, 0xF9A4, 0xFCD3, 0x9A7E,
+ 0xF9A2, 0x9A3F, 0xF9A1, 0xF128, 0xF896, 0xF368, 0xF124, 0xF893, 0xF364, 0xF9B3,
+ 0xF362, 0xF121, 0xF361, 0xE268, 0xF136, 0xE6E8, 0xE264, 0xF133, 0xE6E4, 0xF373,
+ 0xE6E2, 0xE261, 0xE6E1, 0xC4E8, 0xE276, 0xCDE8, 0xC4E4, 0xE273, 0xCDE4, 0xE6F3,
+ 0xCDE2, 0xC4E1, 0xCDE1, 0x89E8, 0xC4F6, 0x9BE8, 0x89E4, 0xC4F3, 0x9BE4, 0xCDF3,
+ 0x9BE2, 0x89E1, 0x9BE1, 0x89F6, 0x9BF6, 0x89F3, 0x9BF3, 0xFDD4, 0xBAF8, 0xDD7E,
+ 0xFDD2, 0xBA7C, 0xDD3F, 0xFDD1, 0xBA3E, 0xBA1F, 0xF994, 0xFCCB, 0x997E, 0xFBB4,
+ 0xFDDB, 0xBB7E, 0x993F, 0xFBB2, 0xF991, 0xBB3F, 0xFBB1, 0xF114, 0xF88B, 0xF334,
+ 0xF112, 0xF774, 0xFBBB, 0xF111, 0xF772, 0xF331, 0xF771, 0xE234, 0xF11B, 0xE674,
+ 0xE232, 0xEEF4, 0xE672, 0xE231, 0xEEF2, 0xE671, 0xEEF1, 0xC474, 0xE23B, 0xCCF4,
+ 0xC472, 0xDDF4, 0xCCF2, 0xC471, 0xDDF2, 0xCCF1, 0xDDF1, 0x88F4, 0xC47B, 0x99F4,
+ 0x88F2, 0xBBF4, 0x99F2, 0x88F1, 0xBBF2, 0x99F1, 0xBBF1, 0x88FB, 0x99FB, 0xFDCA,
+ 0xB97C, 0xDCBF, 0xFDC9, 0xB93E, 0xB91F, 0xF98A, 0x98BF, 0xFB9A, 0xF989, 0xB9BF,
+ 0xFB99, 0xF10A, 0xF31A, 0xF109, 0xF73A, 0xF319, 0xF739, 0xE21A, 0xE63A, 0xE219,
+ 0xEE7A, 0xE639, 0xEE79, 0xC43A, 0xCC7A, 0xC439, 0xDCFA, 0xCC79, 0xDCF9, 0x887A,
+ 0x98FA, 0x8879, 0xB9FA, 0x98F9, 0xB9F9, 0xFDC5, 0xB8BE, 0xB89F, 0xF985, 0xFB8D,
+ 0xF105, 0xF30D, 0xF71D, 0xE20D, 0xE61D, 0xEE3D, 0xC41D, 0xCC3D, 0xDC7D, 0x883D,
+ 0x987D, 0xB8FD, 0xB85F, 0xF0A8, 0xF856, 0xF0A4, 0xF853, 0xF0A2, 0xF0A1, 0xE168,
+ 0xF0B6, 0xE164, 0xF0B3, 0xE162, 0xE161, 0xC2E8, 0xE176, 0xC2E4, 0xE173, 0xC2E2,
+ 0xC2E1, 0x85E8, 0xC2F6, 0x85E4, 0xC2F3, 0x85E2, 0x85E1, 0x85F6, 0x85F3, 0xF8D4,
+ 0xFC6B, 0x8D7E, 0xF8D2, 0x8D3F, 0xF8D1, 0xF094, 0xF84B, 0xF1B4, 0xF092, 0xF1B2,
+ 0xF091, 0xF1B1, 0xE134, 0xF09B, 0xE374, 0xE132, 0xE372, 0xE131, 0xE371, 0xC274,
+ 0xE13B, 0xC6F4, 0xC272, 0xC6F2, 0xC271, 0xC6F1, 0x84F4, 0xC27B, 0x8DF4, 0x84F2,
+ 0x8DF2, 0x84F1, 0x8DF1, 0x84FB, 0x8DFB, 0xFCEA, 0x9D7C, 0xCEBF, 0xFCE9, 0x9D3E,
+ 0x9D1F, 0xF8CA, 0x8CBF, 0xF9DA, 0xF8C9, 0x9DBF, 0xF9D9, 0xF08A, 0xF19A, 0xF089,
+ 0xF3BA, 0xF199, 0xF3B9, 0xE11A, 0xE33A, 0xE119, 0xE77A, 0xE339, 0xE779, 0xC23A,
+ 0xC67A, 0xC239, 0xCEFA, 0xC679, 0xCEF9, 0x847A, 0x8CFA, 0x8479, 0x9DFA, 0x8CF9,
+ 0x9DF9, 0xBD78, 0xDEBE, 0xBD3C, 0xDE9F, 0xBD1E, 0xBD0F, 0xFCE5, 0x9CBE, 0xFDED,
+ 0xBDBE, 0x9C9F, 0xBD9F, 0xF8C5, 0xF9CD, 0xFBDD, 0xF085, 0xF18D, 0xF39D, 0xF7BD,
+ 0xE10D, 0xE31D, 0xE73D, 0xEF7D, 0xC21D, 0xC63D, 0xCE7D, 0xDEFD, 0x843D, 0x8C7D,
+ 0x9CFD, 0xBCBC, 0xDE5F, 0xBC9E, 0xBC8F, 0x9C5F, 0xBCDF, 0xBC5E, 0xBC4F, 0xBC2F,
+ 0xF054, 0xF052, 0xF051, 0xE0B4, 0xF05B, 0xE0B2, 0xE0B1, 0xC174, 0xE0BB, 0xC172,
+ 0xC171, 0x82F4, 0xC17B, 0x82F2, 0x82F1, 0x82FB, 0xF86A, 0x86BF, 0xF869, 0xF04A,
+ 0xF0DA, 0xF049, 0xF0D9, 0xE09A, 0xE1BA, 0xE099, 0xE1B9, 0xC13A, 0xC37A, 0xC139,
+ 0xC379, 0x827A, 0x86FA, 0x8279, 0x86F9, 0xFC75, 0x8EBE, 0x8E9F, 0xF865, 0xF8ED,
+ 0xF045, 0xF0CD, 0xF1DD, 0xE08D, 0xE19D, 0xE3BD, 0xC11D, 0xC33D, 0xC77D, 0x823D,
+ 0x867D, 0x8EFD, 0x9EBC, 0xCF5F, 0x9E9E, 0x9E8F, 0x8E5F, 0x9EDF, 0xBEB8, 0xDF5E,
+ 0xBE9C, 0xDF4F, 0xBE8E, 0xBE87, 0x9E5E, 0xBEDE, 0x9E4F, 0xBECF, 0xBE5C, 0xDF2F,
+ 0xBE4E, 0xBE47, 0x9E2F, 0xBE6F, 0xBE2E, 0xBE27, 0xBE17, 0xE05A, 0xE059, 0xC0BA,
+ 0xC0B9, 0x817A, 0x8179, 0xF06D, 0xE04D, 0xE0DD, 0xC09D, 0xC1BD, 0x813D, 0x837D,
+ 0x875F, 0x8F5E, 0x8F4F, 0x9F5C, 0xCFAF, 0x9F4E, 0x9F47, 0x8F2F, 0x9F6F, 0xBF58,
+ 0xDFAE, 0xBF4C, 0xDFA7, 0xBF46, 0xBF43, 0x9F2E, 0xBF6E, 0x9F27, 0xBF67, 0xBF2C,
+ 0xDF97, 0xBF26, 0xBF23, 0x9F17, 0xBF37, 0xBF16, 0xBF13, 0x87AF, 0x8FAE, 0x8FA7,
+ 0x9FAC, 0xCFD7, 0x9FA6, 0x9FA3, 0x8F97, 0x9FB7, 0x9F96, 0x9F93, 0xD5F0, 0xEAFC,
+ 0xA9E0, 0xD4F8, 0xEA7E, 0xA8F0, 0xD47C, 0xEA3F, 0xA878, 0xD43E, 0xA83C, 0xFD68,
+ 0xADF0, 0xD6FC, 0xFD64, 0xACF8, 0xD67E, 0xFD62, 0xAC7C, 0xD63F, 0xFD61, 0xAC3E,
+ 0xFAE8, 0xFD76, 0xAEFC, 0xFAE4, 0xFD73, 0xAE7E, 0xFAE2, 0xAE3F, 0xFAE1, 0xF5E8,
+ 0xFAF6, 0xF5E4, 0xFAF3, 0xF5E2, 0xF5E1, 0xEBE8, 0xF5F6, 0xEBE4, 0xF5F3, 0xEBE2,
+ 0xEBE1, 0xD7E8, 0xEBF6, 0xD7E4, 0xEBF3, 0xD7E2, 0xA5E0, 0xD2F8, 0xE97E, 0xA4F0,
+ 0xD27C, 0xE93F, 0xA478, 0xD23E, 0xA43C, 0xD21F, 0xA41E, 0xFD34, 0xA6F8, 0xD37E,
+ 0xFD32, 0xA67C, 0xD33F, 0xFD31, 0xA63E, 0xA61F, 0xFA74, 0xFD3B, 0xA77E, 0xFA72,
+ 0xA73F, 0xFA71, 0xF4F4, 0xFA7B, 0xF4F2, 0xF4F1, 0xE9F4, 0xF4FB, 0xE9F2, 0xE9F1,
+ 0xD3F4, 0xE9FB, 0xD3F2, 0xD3F1, 0xA2F0, 0xD17C, 0xE8BF, 0xA278, 0xD13E, 0xA23C,
+ 0xD11F, 0xA21E, 0xA20F, 0xFD1A, 0xA37C, 0xD1BF, 0xFD19, 0xA33E, 0xA31F, 0xFA3A,
+ 0xA3BF, 0xFA39, 0xF47A, 0xF479, 0xE8FA, 0xE8F9, 0xD1FA, 0xD1F9, 0xA178, 0xD0BE,
+ 0xA13C, 0xD09F, 0xA11E, 0xA10F, 0xFD0D, 0xA1BE, 0xA19F, 0xFA1D, 0xF43D, 0xE87D,
+ 0xA0BC, 0xD05F, 0xA09E, 0xA08F, 0xA0DF, 0xA05E, 0xA04F, 0x95E0, 0xCAF8, 0xE57E,
+ 0x94F0, 0xCA7C, 0xE53F, 0x9478, 0xCA3E, 0x943C, 0xCA1F, 0x941E, 0xFCB4, 0x96F8,
+ 0xCB7E, 0xFCB2, 0x967C, 0xCB3F, 0xFCB1, 0x963E, 0x961F, 0xF974, 0xFCBB, 0x977E,
+ 0xF972, 0x973F, 0xF971, 0xF2F4, 0xF97B, 0xF2F2, 0xF2F1, 0xE5F4, 0xF2FB, 0xE5F2,
+ 0xE5F1, 0xCBF4, 0xE5FB, 0xCBF2, 0xCBF1, 0xDAF0, 0xED7C, 0xF6BF, 0xB4E0, 0xDA78,
+ 0xED3E, 0xB470, 0xDA3C, 0xED1F, 0xB438, 0xDA1E, 0xB41C, 0xDA0F, 0xB40E, 0x92F0,
+ 0xC97C, 0xE4BF, 0xB6F0, 0x9278, 0xC93E, 0xB678, 0xDB3E, 0xC91F, 0xB63C, 0x921E,
+ 0xB61E, 0x920F, 0xB60F, 0xFC9A, 0x937C, 0xC9BF, 0xFDBA, 0xFC99, 0xB77C, 0x933E,
+ 0xFDB9, 0xB73E, 0x931F, 0xB71F, 0xF93A, 0x93BF, 0xFB7A, 0xF939, 0xB7BF, 0xFB79,
+ 0xF27A, 0xF6FA, 0xF279, 0xF6F9, 0xE4FA, 0xEDFA, 0xE4F9, 0xEDF9, 0xC9FA, 0xC9F9,
+ 0xB2E0, 0xD978, 0xECBE, 0xB270, 0xD93C, 0xEC9F, 0xB238, 0xD91E, 0xB21C, 0xD90F,
+ 0xB20E, 0xB207, 0x9178, 0xC8BE, 0xB378, 0x913C, 0xC89F, 0xB33C, 0xD99F, 0xB31E,
+ 0x910F, 0xB30F, 0xFC8D, 0x91BE, 0xFD9D, 0xB3BE, 0x919F, 0xB39F, 0xF91D, 0xFB3D,
+ 0xF23D, 0xF67D, 0xE47D, 0xECFD, 0xC8FD, 0xB170, 0xD8BC, 0xEC5F, 0xB138, 0xD89E,
+ 0xB11C, 0xD88F, 0xB10E, 0xB107, 0x90BC, 0xC85F, 0xB1BC, 0x909E, 0xB19E, 0x908F,
+ 0xB18F, 0x90DF, 0xB1DF, 0xB0B8, 0xD85E, 0xB09C, 0xD84F, 0xB08E, 0xB087, 0x905E,
+ 0xB0DE, 0x904F, 0xB0CF, 0xB05C, 0xD82F, 0xB04E, 0xB047, 0x902F, 0xB06F, 0xB02E,
+ 0xB027, 0x8AF0, 0xC57C, 0xE2BF, 0x8A78, 0xC53E, 0x8A3C, 0xC51F, 0x8A1E, 0x8A0F,
+ 0xFC5A, 0x8B7C, 0xC5BF, 0xFC59, 0x8B3E, 0x8B1F, 0xF8BA, 0x8BBF, 0xF8B9, 0xF17A,
+ 0xF179, 0xE2FA, 0xE2F9, 0xC5FA, 0xC5F9, 0x9AE0, 0xCD78, 0xE6BE, 0x9A70, 0xCD3C,
+ 0xE69F, 0x9A38, 0xCD1E, 0x9A1C, 0xCD0F, 0x9A0E, 0x9A07, 0x8978, 0xC4BE, 0x9B78,
+ 0x893C, 0xC49F, 0x9B3C, 0xCD9F, 0x9B1E, 0x890F, 0x9B0F, 0xFC4D, 0x89BE, 0xFCDD,
+ 0x9BBE, 0x899F, 0x9B9F, 0xF89D, 0xF9BD, 0xF13D, 0xF37D, 0xE27D, 0xE6FD, 0xC4FD,
+ 0xDD70, 0xEEBC, 0xF75F, 0xBA60, 0xDD38, 0xEE9E, 0xBA30, 0xDD1C, 0xEE8F, 0xBA18,
+ 0xDD0E, 0xBA0C, 0xDD07, 0xBA06, 0x9970, 0xCCBC, 0xE65F, 0xBB70, 0x9938, 0xCC9E,
+ 0xBB38, 0xDD9E, 0xCC8F, 0xBB1C, 0x990E, 0xBB0E, 0x9907, 0xBB07, 0x88BC, 0xC45F,
+ 0x99BC, 0x889E, 0xBBBC, 0x999E, 0x888F, 0xBB9E, 0x998F, 0xBB8F, 0x88DF, 0x99DF,
+ 0xBBDF, 0xB960, 0xDCB8, 0xEE5E, 0xB930, 0xDC9C, 0xEE4F, 0xB918, 0xDC8E, 0xB90C,
+ 0xDC87, 0xB906, 0xB903, 0x98B8, 0xCC5E, 0xB9B8, 0x989C, 0xCC4F, 0xB99C, 0xDCCF,
+ 0xB98E, 0x9887, 0xB987, 0x885E, 0x98DE, 0x884F, 0xB9DE, 0x98CF, 0xB9CF, 0xB8B0,
+ 0xDC5C, 0xEE2F, 0xB898, 0xDC4E, 0xB88C, 0xDC47, 0xB886, 0xB883, 0x985C, 0xCC2F,
+ 0xB8DC, 0x984E, 0xB8CE, 0x9847, 0xB8C7, 0x882F, 0x986F, 0xB8EF, 0xB858, 0xDC2E,
+ 0xB84C, 0xDC27, 0xB846, 0xB843, 0x982E, 0xB86E, 0x9827, 0xB867, 0xB82C, 0xDC17,
+ 0xB826, 0xB823, 0x9817, 0xB837, 0xB816, 0xB813, 0x8578, 0xC2BE, 0x853C, 0xC29F,
+ 0x851E, 0x850F, 0x85BE, 0x859F, 0xF85D, 0xF0BD, 0xE17D, 0xC2FD, 0x8D70, 0xC6BC,
+ 0xE35F, 0x8D38, 0xC69E, 0x8D1C, 0xC68F, 0x8D0E, 0x8D07, 0x84BC, 0xC25F, 0x8DBC,
+ 0x849E, 0x8D9E, 0x848F, 0x8D8F, 0x84DF, 0x8DDF, 0x9D60, 0xCEB8, 0xE75E, 0x9D30,
+ 0xCE9C, 0xE74F, 0x9D18, 0xCE8E, 0x9D0C, 0xCE87, 0x9D06, 0x9D03, 0x8CB8, 0xC65E,
+ 0x9DB8, 0x8C9C, 0xC64F, 0x9D9C, 0x8C8E, 0x9D8E, 0x8C87, 0x9D87, 0x845E, 0x8CDE,
+ 0x844F, 0x9DDE, 0x8CCF, 0x9DCF, 0xDEB0, 0xEF5C, 0xF7AF, 0xBD20, 0xDE98, 0xEF4E,
+ 0xBD10, 0xDE8C, 0xEF47, 0xBD08, 0xDE86, 0xBD04, 0xDE83, 0xBD02, 0x9CB0, 0xCE5C,
+ 0xE72F, 0xBDB0, 0x9C98, 0xCE4E, 0xBD98, 0xDECE, 0xCE47, 0xBD8C, 0x9C86, 0xBD86,
+ 0x9C83, 0xBD83, 0x8C5C, 0xC62F, 0x9CDC, 0x8C4E, 0xBDDC, 0x9CCE, 0x8C47, 0xBDCE,
+ 0x9CC7, 0xBDC7, 0x842F, 0x8C6F, 0x9CEF, 0xBDEF, 0xBCA0, 0xDE58, 0xEF2E, 0xBC90,
+ 0xDE4C, 0xEF27, 0xBC88, 0xDE46, 0xBC84, 0xDE43, 0xBC82, 0xBC81, 0x9C58, 0xCE2E,
+ 0xBCD8, 0x9C4C, 0xCE27, 0xBCCC, 0xDE67, 0xBCC6, 0x9C43, 0xBCC3, 0x8C2E, 0x9C6E,
+ 0x8C27, 0xBCEE, 0x9C67, 0xBCE7, 0xBC50, 0xDE2C, 0xEF17, 0xBC48, 0xDE26, 0xBC44,
+ 0xDE23, 0xBC42, 0xBC41, 0x9C2C, 0xCE17, 0xBC6C, 0x9C26, 0xBC66, 0x9C23, 0xBC63,
+ 0x8C17, 0x9C37, 0xBC77, 0xBC28, 0xDE16, 0xBC24, 0xDE13, 0xBC22, 0xBC21, 0x9C16,
+ 0xBC36, 0x9C13, 0xBC33, 0xBC14, 0xDE0B, 0xBC12, 0xBC11, 0x9C0B, 0xBC1B, 0x82BC,
+ 0xC15F, 0x829E, 0x828F, 0x82DF, 0x86B8, 0xC35E, 0x869C, 0xC34F, 0x868E, 0x8687,
+ 0x825E, 0x86DE, 0x824F, 0x86CF, 0x8EB0, 0xC75C, 0xE3AF, 0x8E98, 0xC74E, 0x8E8C,
+ 0xC747, 0x8E86, 0x8E83, 0x865C, 0xC32F, 0x8EDC, 0x864E, 0x8ECE, 0x8647, 0x8EC7,
+ 0x822F, 0x866F, 0x8EEF, 0x9EA0, 0xCF58, 0xE7AE, 0x9E90, 0xCF4C, 0xE7A7, 0x9E88,
+ 0xCF46, 0x9E84, 0xCF43, 0x9E82, 0x9E81, 0x8E58, 0xC72E, 0x9ED8, 0x8E4C, 0xC727,
+ 0x9ECC, 0xCF67, 0x9EC6, 0x8E43, 0x9EC3, 0x862E, 0x8E6E, 0x8627, 0x9EEE, 0x8E67,
+ 0x9EE7, 0xDF50, 0xEFAC, 0xF7D7, 0xDF48, 0xEFA6, 0xDF44, 0xEFA3, 0xDF42, 0xDF41,
+ 0x9E50, 0xCF2C, 0xE797, 0xBED0, 0x9E48, 0xCF26, 0xBEC8, 0xDF66, 0xCF23, 0xBEC4,
+ 0x9E42, 0xBEC2, 0x9E41, 0xBEC1, 0x8E2C, 0xC717, 0x9E6C, 0x8E26, 0xBEEC, 0x9E66,
+ 0x8E23, 0xBEE6, 0x9E63, 0xBEE3, 0x8617, 0x8E37, 0x9E77, 0xBEF7, 0xDF28, 0xEF96,
+ 0xDF24, 0xEF93, 0xDF22, 0xDF21, 0x9E28, 0xCF16, 0xBE68, 0x9E24, 0xCF13, 0xBE64,
+ 0xDF33, 0xBE62, 0x9E21, 0xBE61, 0x8E16, 0x9E36, 0x8E13, 0xBE76, 0x9E33, 0xBE73,
+ 0xDF14, 0xEF8B, 0xDF12, 0xDF11, 0x9E14, 0xCF0B, 0xBE34, 0x9E12, 0xBE32, 0x9E11,
+ 0xBE31, 0x8E0B, 0x9E1B, 0xBE3B, 0xDF0A, 0xDF09, 0x9E0A, 0xBE1A, 0x9E09, 0xBE19,
+ 0x815E, 0x814F, 0x835C, 0xC1AF, 0x834E, 0x8347, 0x812F, 0x836F, 0x8758, 0xC3AE,
+ 0x874C, 0xC3A7, 0x8746, 0x8743, 0x832E, 0x876E, 0x8327, 0x8767, 0x8F50, 0xC7AC,
+ 0xE3D7, 0x8F48, 0xC7A6, 0x8F44, 0xC7A3, 0x8F42, 0x8F41, 0x872C, 0xC397, 0x8F6C,
+ 0xC7B7, 0x8F66, 0x8723, 0x8F63, 0x8317, 0x8737, 0x8F77, 0xCFA8, 0xE7D6, 0xCFA4,
+ 0xE7D3, 0xCFA2, 0xCFA1, 0x8F28, 0xC796, 0x9F68, 0xCFB6, 0xC793, 0x9F64, 0x8F22,
+ 0x9F62, 0x8F21, 0x9F61, 0x8716, 0x8F36, 0x8713, 0x9F76, 0x8F33, 0x9F73, 0xEFD4,
+ 0xF7EB, 0xEFD2, 0xEFD1, 0xCF94, 0xE7CB, 0xDFB4, 0xCF92, 0xDFB2, 0xCF91, 0xDFB1,
+ 0x8F14, 0xC78B, 0x9F34, 0x8F12, 0xBF74, 0x9F32, 0x8F11, 0xBF72, 0x9F31, 0xBF71,
+ 0x870B, 0x8F1B, 0x9F3B, 0xBF7B, 0xEFCA, 0xEFC9, 0xCF8A, 0xDF9A, 0xCF89, 0xDF99,
+ 0x8F0A, 0x9F1A, 0x8F09, 0xBF3A, 0x9F19, 0xBF39, 0xEFC5, 0xCF85, 0xDF8D, 0x8F05,
+ 0x9F0D, 0xBF1D, 0x81AE, 0x81A7, 0x83AC, 0xC1D7, 0x83A6, 0x83A3, 0x8197, 0x83B7,
+ 0x87A8, 0xC3D6, 0x87A4, 0xC3D3, 0x87A2, 0x87A1, 0x8396, 0x87B6, 0x8393, 0x87B3,
+ 0xC7D4, 0xE3EB, 0xC7D2, 0xC7D1, 0x8794, 0xC3CB, 0x8FB4, 0xC7DB, 0x8FB2, 0x8791,
+ 0x8FB1, 0x838B, 0x879B, 0x8FBB, 0xE7EA, 0xE7E9, 0xC7CA, 0xCFDA, 0xC7C9, 0xCFD9,
+ 0x878A, 0x8F9A, 0x8789, 0x9FBA, 0x8F99, 0x9FB9, 0xE7E5, 0xC7C5, 0xCFCD, 0x8785,
+ 0x8F8D, 0x9F9D, 0x81D6, 0x81D3, 0x83D4, 0xC1EB, 0x83D2, 0x83D1, 0x81CB, 0x83DB,
+ 0xC3EA, 0xC3E9, 0x83CA, 0x87DA, 0x83C9, 0x87D9, 0xE3F5
+};
+
+/* MicroPDF417 coefficients from ISO/IEC 24728:2006 Annex F */
+static const unsigned short 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 const unsigned short 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 const char 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 const unsigned short int rap_side[52] = {
+ 0x322, 0x3A2, 0x3B2, 0x332, 0x372, 0x37A, 0x33A, 0x3BA, 0x39A, 0x3DA,
+ 0x3CA, 0x38A, 0x30A, 0x31A, 0x312, 0x392, 0x3D2, 0x3D6, 0x3D4, 0x394,
+ 0x3B4, 0x3A4, 0x3A6, 0x3AE, 0x3AC, 0x3A8, 0x328, 0x32C, 0x32E, 0x326,
+ 0x336, 0x3B6, 0x396, 0x316, 0x314, 0x334, 0x374, 0x364, 0x366, 0x36E,
+ 0x36C, 0x368, 0x348, 0x358, 0x35C, 0x35E, 0x34E, 0x34C, 0x344, 0x346,
+ 0x342, 0x362
+};
+
+/* Centre Row Address Pattern from Table 2 */
+static const unsigned short int rap_centre[52] = {
+ 0x2CE, 0x24E, 0x26E, 0x22E, 0x226, 0x236, 0x216, 0x212, 0x21A, 0x23A,
+ 0x232, 0x222, 0x262, 0x272, 0x27A, 0x2FA, 0x2F2, 0x2F6, 0x276, 0x274,
+ 0x264, 0x266, 0x246, 0x242, 0x2C2, 0x2E2, 0x2E6, 0x2E4, 0x2EC, 0x26C,
+ 0x22C, 0x228, 0x268, 0x2E8, 0x2C8, 0x2CC, 0x2C4, 0x2C6, 0x286, 0x28E,
+ 0x28C, 0x29C, 0x298, 0x2B8, 0x2B0, 0x290, 0x2D0, 0x250, 0x258, 0x25C,
+ 0x2DC, 0x2DE
+};
+
+void byteprocess(int *chainemc, int *mclength, unsigned char chaine[], int start, int length); \ No newline at end of file
diff --git a/backend/plessey.c b/backend/plessey.c
new file mode 100644
index 0000000..dcc7eaf
--- /dev/null
+++ b/backend/plessey.c
@@ -0,0 +1,494 @@
+/* plessey.c - Handles Plessey and MSI Plessey */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <stdio.h>
+#include "common.h"
+
+#define SSET "0123456789ABCDEF"
+
+static const char *PlessTable[16] = {
+ "13131313", "31131313", "13311313", "31311313", "13133113", "31133113",
+ "13313113", "31313113", "13131331", "31131331", "13311331", "31311331", "13133131",
+ "31133131", "13313131", "31313131"
+};
+
+static const char *MSITable[10] = {
+ "12121212", "12121221", "12122112", "12122121", "12211212", "12211221",
+ "12212112", "12212121", "21121212", "21121221"
+};
+
+/* Not MSI/Plessey but the older Plessey standard */
+INTERNAL int plessey(struct zint_symbol *symbol, unsigned char source[], const size_t length) {
+
+ unsigned int i;
+ unsigned char *checkptr;
+ static const 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;
+
+ if (length > 65) {
+ strcpy(symbol->errtxt, "370: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(SSET, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "371: 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++) {
+ unsigned int 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++) {
+ if (checkptr[i]) {
+ int j;
+ for (j = 0; j < 9; j++)
+ checkptr[i + j] ^= grid[j];
+ }
+ }
+
+ for (i = 0; i < 8; i++) {
+ switch (checkptr[length * 4 + i]) {
+ case 0: strcat(dest, "13");
+ break;
+ case 1: strcat(dest, "31");
+ break;
+ }
+ }
+
+ /* Stop character */
+ strcat(dest, "331311313");
+
+ expand(symbol, dest);
+ ustrcpy(symbol->text, source);
+ free(checkptr);
+ return error_number;
+}
+
+/* Plain MSI Plessey - does not calculate any check character */
+static int msi_plessey(struct zint_symbol *symbol, unsigned char source[], const int length) {
+
+ int i;
+ char dest[512]; /* 2 + 55 * 8 + 3 + 1 ~ 512 */
+
+ if (length > 55) {
+ strcpy(symbol->errtxt, "372: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ /* start character */
+ strcpy(dest, "21");
+
+ for (i = 0; i < length; i++) {
+ lookup(NEON, MSITable, source[i], dest);
+ }
+
+ /* Stop character */
+ strcat(dest, "121");
+
+ expand(symbol, dest);
+ ustrcpy(symbol->text, source);
+ return 0;
+}
+
+/* MSI Plessey with Modulo 10 check digit - algorithm from Barcode Island
+ * http://www.barcodeisland.com/ */
+static int msi_plessey_mod10(struct zint_symbol *symbol, unsigned char source[], int length) {
+
+ int i, wright, pump, n;
+ unsigned long dau, pedwar;
+ char un[200], tri[32];
+ int error_number, h;
+ char dest[1000];
+
+ error_number = 0;
+
+ if (length > 18) {
+ strcpy(symbol->errtxt, "373: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ /* start character */
+ strcpy(dest, "21");
+
+ /* draw data section */
+ for (i = 0; i < length; i++) {
+ lookup(NEON, MSITable, source[i], dest);
+ }
+
+ /* calculate check digit */
+ wright = 0;
+ n = !(length & 1);
+ for (i = n; i < length; i += 2) {
+ un[wright++] = source[i];
+ }
+ un[wright] = '\0';
+
+ dau = strtoul(un, NULL, 10);
+ dau *= 2;
+
+ sprintf(tri, "%lu", dau);
+
+ pedwar = 0;
+ h = strlen(tri);
+ for (i = 0; i < h; i++) {
+ pedwar += ctoi(tri[i]);
+ }
+
+ n = length & 1;
+ 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 */
+ strcat(dest, "121");
+ expand(symbol, dest);
+
+ ustrcpy(symbol->text, source);
+ symbol->text[length] = itoc(pump);
+ symbol->text[length + 1] = '\0';
+ return error_number;
+}
+
+/* MSI Plessey with two Modulo 10 check digits - algorithm from
+ * Barcode Island http://www.barcodeisland.com/ */
+static int msi_plessey_mod1010(struct zint_symbol *symbol, unsigned char source[], const int src_len) {
+
+ int i, n, wright, pump;
+ unsigned long dau, pedwar, 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, "374: Input too long");
+ return ZINT_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 & 1);
+ for (i = n; i < src_len; i += 2) {
+ un[wright++] = source[i];
+ }
+ un[wright] = '\0';
+
+ dau = strtoul(un, NULL, 10);
+ dau *= 2;
+
+ sprintf(tri, "%lu", dau);
+
+ pedwar = 0;
+ h = strlen(tri);
+ for (i = 0; i < h; i++) {
+ pedwar += ctoi(tri[i]);
+ }
+
+ n = src_len & 1;
+ 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 & 1;
+ 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, "%lu", dau);
+
+ pedwar = 0;
+ h = strlen(tri);
+ for (i = 0; i < h; i++) {
+ pedwar += ctoi(tri[i]);
+ }
+
+
+ i = !(src_len & 1);
+ 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 */
+ strcat(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;
+}
+
+/* Calculate a Modulo 11 check digit using the system discussed on Wikipedia -
+ see http://en.wikipedia.org/wiki/Talk:MSI_Barcode */
+static int msi_plessey_mod11(struct zint_symbol *symbol, unsigned char source[], const int src_len) {
+ /* uses the IBM weight system */
+ int i, weight, check;
+ unsigned long x;
+ int error_number;
+ char dest[1000];
+
+ error_number = 0;
+
+ if (src_len > 55) {
+ strcpy(symbol->errtxt, "375: Input too long");
+ return ZINT_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 */
+ strcat(dest, "121");
+
+ expand(symbol, dest);
+
+ ustrcpy(symbol->text, source);
+ if (check == 10) {
+ strcat((char*) symbol->text, "10");
+ } else {
+ symbol->text[src_len] = itoc(check);
+ symbol->text[src_len + 1] = '\0';
+ }
+
+ return error_number;
+}
+
+/* Combining the Barcode Island and Wikipedia code
+ * Verified against http://www.bokai.com/BarcodeJSP/applet/BarcodeSampleApplet.htm */
+static int msi_plessey_mod1110(struct zint_symbol *symbol, unsigned char source[], const int src_len) {
+ /* Weighted using the IBM system */
+ int i, weight, check, wright, pump;
+ unsigned long x, dau, pedwar;
+ int h;
+ int si;
+ char un[16], tri[16];
+ int error_number;
+ char dest[1000];
+ unsigned char temp[32];
+ int temp_len;
+
+ error_number = 0;
+
+ if (src_len > 18) {
+ strcpy(symbol->errtxt, "376: Input too long");
+ return ZINT_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 (si = src_len - 1; si >= 0; si--) {
+ x += weight * ctoi(source[si]);
+ 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);
+ strcat((char*) temp, "10");
+ temp_len += 2;
+ } else {
+ lookup(NEON, MSITable, itoc(check), dest);
+ temp[temp_len++] = itoc(check);
+ temp[temp_len] = '\0';
+ }
+
+ /* calculate second (mod 10) check digit */
+ wright = 0;
+ i = !(temp_len & 1);
+ for (; i < temp_len; i += 2) {
+ un[wright++] = temp[i];
+ }
+ un[wright] = '\0';
+
+ dau = strtoul(un, NULL, 10);
+ dau *= 2;
+
+ sprintf(tri, "%lu", dau);
+
+ pedwar = 0;
+ h = strlen(tri);
+ for (i = 0; i < h; i++) {
+ pedwar += ctoi(tri[i]);
+ }
+
+ i = temp_len & 1;
+ 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 */
+ strcat(dest, "121");
+ expand(symbol, dest);
+
+ temp[temp_len++] = itoc(pump);
+ temp[temp_len] = '\0';
+
+
+ ustrcpy(symbol->text, temp);
+ return error_number;
+}
+
+INTERNAL 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, "377: Invalid characters in input data");
+ return ZINT_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
index 085bbec..f2e41f1 100644
--- a/backend/png.c
+++ b/backend/png.c
@@ -2,7 +2,7 @@
/*
libzint - the open source barcode library
- Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2009-2017 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -28,34 +28,26 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
#include <stdio.h>
#ifdef _MSC_VER
#include <fcntl.h>
#include <io.h>
+#include <malloc.h>
#endif
#include <stdlib.h>
#include <string.h>
#include "common.h"
-#ifdef _MSC_VER
-#include <malloc.h>
-#endif /* _MSC_VER */
-
#ifndef NO_PNG
-#include "png.h" /* libpng header; includes zlib.h and setjmp.h */
-#endif /* NO_PNG */
-#include "maxipng.h" /* Maxicode shapes */
-
-#include "font.h" /* Font for human readable text */
+#include <png.h>
+#include <zlib.h>
+#include <setjmp.h>
#define SSET "0123456789ABCDEF"
-#define PNG_DATA 100
-#define BMP_DATA 200
-
-#ifndef NO_PNG
struct mainprog_info_type {
long width;
long height;
@@ -63,1093 +55,178 @@ struct mainprog_info_type {
jmp_buf jmpbuf;
};
-static void writepng_error_handler(png_structp png_ptr, png_const_charp msg)
-{
- struct mainprog_info_type *graphic;
+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);
+ fprintf(stderr, "writepng libpng error: %s (F30)\n", msg);
fflush(stderr);
- graphic = (struct mainprog_info_type*)png_get_error_ptr(png_ptr);
- if (graphic == NULL) { /* we are completely hosed now */
+ 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");
+ "writepng severe error: jmpbuf not recoverable; terminating. (F31)\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 char *image_data;
- int i, row, column, err_no;
- 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;
- }
- err_no = is_sane(SSET, (unsigned char*)symbol->fgcolour, strlen(symbol->fgcolour));
- if (err_no == ERROR_INVALID_DATA) {
- strcpy(symbol->errtxt, "Malformed foreground colour target");
- return ERROR_INVALID_OPTION;
- }
- err_no = is_sane(SSET, (unsigned char*)symbol->bgcolour, strlen(symbol->bgcolour));
- if (err_no == 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,9);
-
- /* 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);
-
- /* 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)
-{
- int i, row, column, err_no;
- 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;
- }
- err_no = is_sane(SSET, (unsigned char*)symbol->fgcolour, strlen(symbol->fgcolour));
- if (err_no == ERROR_INVALID_DATA) {
- strcpy(symbol->errtxt, "Malformed foreground colour target");
- return ERROR_INVALID_OPTION;
- }
- err_no = is_sane(SSET, (unsigned char*)symbol->bgcolour, strlen(symbol->fgcolour));
- if (err_no == 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]);
-
- /* 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;
- 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)) == NULL) {
- printf("Insufficient memory for pixel buffer");
- return ERROR_ENCODING_PROBLEM;
- }
- memset(scaled_pixelbuf, '0', scale_width * scale_height);
-
- 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
- error_number = 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';
- }
- }
- }
-}
+INTERNAL int png_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
+ struct mainprog_info_type wpng_info;
+ struct mainprog_info_type *graphic;
+ png_structp png_ptr;
+ png_infop info_ptr;
+ int i, row, column;
+ int fgred, fggrn, fgblu, bgred, bggrn, bgblu;
-void draw_letter(char *pixelbuf, unsigned char letter, int xposn, int yposn, int smalltext, 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;
- }
-
- if(smalltext) {
- for(i = 0; i <= 8; i++) {
- for(j = 0; j < 5; j++) {
- if(alphabet == 0) {
- if(small_font[(glyph_no * 5) + (i * 475) + j - 1] == 1) {
- *(pixelbuf + (i * image_width) + (yposn * image_width) + xposn + j) = '1';
- }
- } else {
- if(small_font_extended[(glyph_no * 5) + (i * 475) + j - 1] == 1) {
- *(pixelbuf + (i * image_width) + (yposn * image_width) + xposn + j) = '1';
- }
- }
- }
- }
- } else {
- 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 smalltext, 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, smalltext, 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 & 1) {
- /* Odd (reduced) row */
- xposn += 5;
- draw_hexagon(pixelbuf, image_width, xposn + (2 * xoffset), yposn + (2 * yoffset));
- } else {
- /* Even (full) row */
- 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 = NULL;
- int addon_latch = 0, smalltext = 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;
- int tlen = ustrlen(symbol->text);
#ifndef _MSC_VER
- unsigned char local_text[tlen + 1];
+ unsigned char outdata[symbol->bitmap_width * 3];
#else
- unsigned char* local_text = (unsigned char*)_alloca(tlen+ 1);
+ unsigned char* outdata = (unsigned char*) _alloca(symbol->bitmap_width * 3);
#endif
- if(symbol->show_hrt != 0) {
- to_latin1(symbol->text, local_text);
- } else {
- local_text[0] = '\0';
- }
-
- textdone = (symbol->show_hrt != 0) ? 0 : 1;
- main_width = symbol->width;
- strcpy(addon, "");
- comp_offset = 0;
- addon_text_posn = 0.0;
- row_height = 0;
- if(symbol->output_options & SMALL_TEXT) {
- smalltext = 1;
- }
-
- 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(tlen) {
- 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 < tlen; i++) {
- if (latch == 1) {
- addon[r] = local_text[i];
- r++;
- }
- if (symbol->text[i] == '+') {
- latch = 1;
- }
- }
- }
- addon[r] = '\0';
-
- if((symbol->show_hrt != 0) && tlen) {
- 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;
+ graphic = &wpng_info;
- /* 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;
+ graphic->width = symbol->bitmap_width;
+ graphic->height = symbol->bitmap_height;
- 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(tlen) {
- 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);
+ 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]);
- if(symbol->show_hrt != 0) {
- 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, smalltext, 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, smalltext, 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, smalltext, image_width, image_height);
- break;
- case 5:
- textpos = 2 * (xoffset + 100);
- draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, 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);
-
- if (symbol->show_hrt != 0) {
- textpart[0] = symbol->text[0];
- textpart[1] = '\0';
- textpos = 2 * (-7 + xoffset);
- draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, 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, smalltext, 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, smalltext, 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, smalltext, image_width, image_height);
- break;
- case 5:
- textpos = 2 * (xoffset + 128);
- draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, 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);
-
- if(symbol->show_hrt != 0) {
- textpart[0] = symbol->text[0];
- textpart[1] = '\0';
- textpos = 2 * (-5 + xoffset);
- draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, 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, smalltext, 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, smalltext, image_width, image_height);
- textpart[0] = symbol->text[11];
- textpart[1] = '\0';
- textpos = 2 * (100 + xoffset);
- draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, 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, smalltext, image_width, image_height);
- break;
- case 5:
- textpos = 2 * (xoffset + 130);
- draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, 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);
+ /* Open output file in binary mode */
+ if (symbol->output_options & BARCODE_STDOUT) {
+#ifdef _MSC_VER
+ if (-1 == _setmode(_fileno(stdout), _O_BINARY)) {
+ strcpy(symbol->errtxt, "631: Can't open output file");
+ return ZINT_ERROR_FILE_ACCESS;
+ }
+#endif
+ graphic->outfile = stdout;
+ } else {
+ if (!(graphic->outfile = fopen(symbol->outfile, "wb"))) {
+ strcpy(symbol->errtxt, "632: Can't open output file");
+ return ZINT_ERROR_FILE_ACCESS;
+ }
+ }
- if (symbol->show_hrt != 0) {
- textpart[0] = symbol->text[0];
- textpart[1] = '\0';
- textpos = 2 * (-5 + xoffset);
- draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, 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, smalltext, image_width, image_height);
- textpart[0] = symbol->text[7];
- textpart[1] = '\0';
- textpos = 2 * (55 + xoffset);
- draw_string(pixelbuf, textpart, textpos, default_text_posn, smalltext, 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, smalltext, image_width, image_height);
- break;
- case 5:
- textpos = 2 * (xoffset + 84);
- draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, smalltext, image_width, image_height);
- break;
- }
- }
+ /* 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, "633: Out of memory");
+ return ZINT_ERROR_MEMORY;
+ }
- }
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ png_destroy_write_struct(&png_ptr, NULL);
+ strcpy(symbol->errtxt, "634: Out of memory");
+ return ZINT_ERROR_MEMORY;
+ }
- xoffset -= comp_offset;
+ /* catch jumping here */
+ if (setjmp(graphic->jmpbuf)) {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ strcpy(symbol->errtxt, "635: libpng error occurred");
+ return ZINT_ERROR_MEMORY;
+ }
- /* Put boundary bars or box around symbol */
- if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {
- /* 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);
- }
- }
- }
- }
-
- 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) && tlen) {
- textpos = (image_width / 2);
- draw_string(pixelbuf, (char*)local_text, textpos, default_text_posn, smalltext, image_width, image_height);
- }
+ /* open output file with libpng */
+ png_init_io(png_ptr, graphic->outfile);
+
+ /* set compression */
+ png_set_compression_level(png_ptr, 9);
+
+ /* 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);
+
+ /* Pixel Plotting */
+ for (row = 0; row < symbol->bitmap_height; row++) {
+ unsigned char *image_data;
+ for (column = 0; column < symbol->bitmap_width; column++) {
+ i = column * 3;
+ switch (*(pixelbuf + (symbol->bitmap_width * row) + column)) {
+ case 'W': // White
+ outdata[i] = 255;
+ outdata[i + 1] = 255;
+ outdata[i + 2] = 255;
+ break;
+ case 'C': // Cyan
+ outdata[i] = 0;
+ outdata[i + 1] = 255;
+ outdata[i + 2] = 255;
+ break;
+ case 'B': // Blue
+ outdata[i] = 0;
+ outdata[i + 1] = 0;
+ outdata[i + 2] = 255;
+ break;
+ case 'M': // Magenta
+ outdata[i] = 255;
+ outdata[i + 1] = 0;
+ outdata[i + 2] = 255;
+ break;
+ case 'R': // Red
+ outdata[i] = 255;
+ outdata[i + 1] = 0;
+ outdata[i + 2] = 0;
+ break;
+ case 'Y': // Yellow
+ outdata[i] = 255;
+ outdata[i + 1] = 255;
+ outdata[i + 2] = 0;
+ break;
+ case 'G': // Green
+ outdata[i] = 0;
+ outdata[i + 1] = 255;
+ outdata[i + 2] = 0;
+ break;
+ case 'K': // Black
+ outdata[i] = 0;
+ outdata[i + 1] = 0;
+ outdata[i + 2] = 0;
+ break;
+ 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);
+ }
- error_number=png_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type);
- free(pixelbuf);
- return error_number;
-}
+ /* End the file */
+ png_write_end(png_ptr, NULL);
-#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;
+ /* make sure we have disengaged */
+ if (png_ptr && info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr);
+ if (symbol->output_options & BARCODE_STDOUT) {
+ fflush(wpng_info.outfile);
+ } else {
+ fclose(wpng_info.outfile);
+ }
+ return 0;
}
#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 0000000..b90743d
--- /dev/null
+++ b/backend/postal.c
@@ -0,0 +1,596 @@
+/* postal.c - Handles PostNet, PLANET, FIM. RM4SCC and Flattermarken */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008 - 2020 Robin Stuart <rstuart114@gmail.com>
+ Including bug fixes by Bryan Hatton
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <stdio.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#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 const char *PNTable[10] = {
+ "LLSSS", "SSSLL", "SSLSL", "SSLLS", "SLSSL", "SLSLS", "SLLSS", "LSSSL",
+ "LSSLS", "LSLSS"
+};
+
+static const char *PLTable[10] = {
+ "SSLLL", "LLLSS", "LLSLS", "LLSSL", "LSLLS", "LSLSL", "LSSLL", "SLLLS",
+ "SLLSL", "SLSLL"
+};
+
+static const 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 const 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 const char *FlatTable[10] = {
+ "0504", "18", "0117", "0216", "0315", "0414", "0513", "0612", "0711", "0810"
+};
+
+static const char *KoreaTable[10] = {
+ "1313150613", "0713131313", "0417131313", "1506131313",
+ "0413171313", "17171313", "1315061313", "0413131713", "17131713", "13171713"
+};
+
+static const char *JapanTable[19] = {
+ "114", "132", "312", "123", "141", "321", "213", "231", "411", "144",
+ "414", "324", "342", "234", "432", "243", "423", "441", "111"
+};
+
+/* Handles the PostNet system used for Zip codes in the US */
+static int postnet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) {
+ int i, sum, check_digit;
+ int error_number;
+
+ if (length != 5 && length != 9 && length != 11) {
+ strcpy(symbol->errtxt, "480: Input wrong length");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "481: 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;
+ strcat(dest, PNTable[check_digit]);
+
+ /* stop character */
+ strcat(dest, "L");
+
+ return error_number;
+}
+
+/* Puts PostNet barcodes into the pattern matrix */
+INTERNAL int post_plot(struct zint_symbol *symbol, unsigned char source[], int length) {
+ char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */
+ unsigned int loopey, h;
+ int writer;
+ int error_number;
+
+ 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;
+}
+
+/* Handles the PLANET system used for item tracking in the US */
+static int planet(struct zint_symbol *symbol, unsigned char source[], char dest[], int length) {
+ int i, sum, check_digit;
+ int error_number;
+
+ if (length != 11 && length != 13) {
+ strcpy(symbol->errtxt, "482: Input wrong length");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "483: 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;
+ strcat(dest, PLTable[check_digit]);
+
+ /* stop character */
+ strcat(dest, "L");
+
+ return error_number;
+}
+
+/* Puts PLANET barcodes into the pattern matrix */
+INTERNAL int planet_plot(struct zint_symbol *symbol, unsigned char source[], int length) {
+ char height_pattern[256]; /* 5 + 38 * 5 + 5 + 5 + 1 ~ 256 */
+ unsigned int loopey, h;
+ int writer;
+ int error_number;
+
+ 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;
+}
+
+/* Korean Postal Authority */
+INTERNAL int korea_post(struct zint_symbol *symbol, unsigned char source[], int length) {
+ int total, loop, check, zeroes, error_number;
+ char localstr[8], dest[80];
+
+ if (length > 6) {
+ strcpy(symbol->errtxt, "484: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "485: 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;
+}
+
+/* The simplest barcode symbology ever! Supported by MS Word, so here it is!
+ glyphs from http://en.wikipedia.org/wiki/Facing_Identification_Mark */
+INTERNAL int fim(struct zint_symbol *symbol, unsigned char source[], int length) {
+
+ char dest[16] = {0};
+
+ if (length > 1) {
+ strcpy(symbol->errtxt, "486: Input too long");
+ return ZINT_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, "487: Invalid characters in data");
+ return ZINT_ERROR_INVALID_DATA;
+ break;
+ }
+
+ expand(symbol, dest);
+ return 0;
+}
+
+/* Handles the 4 State barcodes used in the UK by Royal Mail */
+static char rm4scc(char source[], unsigned char dest[], int length) {
+ 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;
+ strcat((char*) dest, RoyalTable[check_digit]);
+
+ /* stop character */
+ strcat((char*) dest, "0");
+
+ return set_copy[check_digit];
+}
+
+/* Puts RM4SCC into the data matrix */
+INTERNAL int royal_plot(struct zint_symbol *symbol, unsigned char source[], int length) {
+ char height_pattern[210];
+ int loopey, h;
+ int writer;
+ int error_number;
+ strcpy(height_pattern, "");
+
+ if (length > 50) {
+ strcpy(symbol->errtxt, "488: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ to_upper(source);
+ error_number = is_sane(KRSET, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "489: 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] = 3;
+ symbol->row_height[1] = 2;
+ symbol->row_height[2] = 3;
+ symbol->rows = 3;
+ symbol->width = writer - 1;
+
+ return error_number;
+}
+
+/* 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 */
+INTERNAL int kix_code(struct zint_symbol *symbol, unsigned char source[], int length) {
+ char height_pattern[75], localstr[20];
+ int loopey;
+ int writer, i, h;
+ int error_number;
+ strcpy(height_pattern, "");
+
+ if (length > 18) {
+ strcpy(symbol->errtxt, "490: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ to_upper(source);
+ error_number = is_sane(KRSET, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "491: Invalid characters in data");
+ return error_number;
+ }
+
+ strcpy(localstr, (char *) source);
+
+ /* Encode data */
+ for (i = 0; i < length; 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] = 3;
+ symbol->row_height[1] = 2;
+ symbol->row_height[2] = 3;
+ symbol->rows = 3;
+ symbol->width = writer - 1;
+
+ return error_number;
+}
+
+/* Handles DAFT Code symbols */
+INTERNAL int daft_code(struct zint_symbol *symbol, unsigned char source[], int length) {
+ char height_pattern[100];
+ unsigned int loopey, h;
+ int writer, i, error_number;
+ strcpy(height_pattern, "");
+
+ if (length > 50) {
+ strcpy(symbol->errtxt, "492: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ to_upper((unsigned char*) source);
+ error_number = is_sane(DAFTSET, (unsigned char*) source, length);
+
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "493: Invalid characters in data");
+ return error_number;
+ }
+
+ for (i = 0; i < length; i++) {
+ if (source[i] == 'D') {
+ strcat(height_pattern, "2");
+ }
+ if (source[i] == 'A') {
+ strcat(height_pattern, "1");
+ }
+ if (source[i] == 'F') {
+ strcat(height_pattern, "0");
+ }
+ if (source[i] == 'T') {
+ strcat(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] = 3;
+ symbol->row_height[1] = 2;
+ symbol->row_height[2] = 3;
+ symbol->rows = 3;
+ symbol->width = writer - 1;
+
+ return error_number;
+}
+
+/* Flattermarken - Not really a barcode symbology! */
+INTERNAL int flattermarken(struct zint_symbol *symbol, unsigned char source[], int length) {
+ int loop, error_number;
+ char dest[512]; /* 90 * 4 + 1 ~ */
+
+ if (length > 90) {
+ strcpy(symbol->errtxt, "494: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "495: 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;
+}
+
+/* Japanese Postal Code (Kasutama Barcode) */
+INTERNAL int japan_post(struct zint_symbol *symbol, unsigned char source[], int length) {
+ 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
+
+ if (length > 20) {
+ strcpy(symbol->errtxt, "496: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ error_number = 0;
+
+ strcpy(local_source, (char*) source);
+ to_upper((unsigned char*) local_source);
+
+ if (is_sane(SHKASUTSET, (unsigned char*) local_source, length) == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "497: Invalid characters in data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ 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++) {
+ strcat(pattern, JapanTable[posn(KASUTSET, inter[i])]);
+ sum += posn(CHKASUTSET, inter[i]);
+ }
+
+ /* Calculate check digit */
+ check = 19 - (sum % 19);
+ if (check == 19) {
+ check = 0;
+ }
+ if (check <= 9) {
+ check_char = check + '0';
+ } else if (check == 10) {
+ check_char = '-';
+ } else {
+ check_char = (check - 11) + 'a';
+ }
+ strcat(pattern, JapanTable[posn(KASUTSET, check_char)]);
+
+ strcat(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] = 3;
+ symbol->row_height[1] = 2;
+ symbol->row_height[2] = 3;
+ symbol->rows = 3;
+ symbol->width = writer - 1;
+
+ return error_number;
+}
diff --git a/backend/ps.c b/backend/ps.c
index 771d186..31a2f39 100644
--- a/backend/ps.c
+++ b/backend/ps.c
@@ -2,7 +2,7 @@
/*
libzint - the open source barcode library
- Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2009-2018 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -28,750 +28,302 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
#include <locale.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
+#include <math.h>
#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;
- textdone = 1;
- }
- 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;
-
- mx = 2.46 * i + 1.23 + (r & 1 ? 1.23 : 0);
-
- 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);
-
- if(plot_text) {
- 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);
- if(plot_text) {
- 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_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");
- if((symbol->output_options & BARCODE_STDOUT) == 0)
- fclose(feps);
-
- if (locale)
- setlocale(LC_ALL, locale);
-
- return error_number;
+void colour_to_pscolor(int option, int colour, char* output) {
+ strcpy(output, "");
+ if ((option & CMYK_COLOUR) == 0) {
+ // Use RGB colour space
+ switch(colour) {
+ case 0: // White
+ strcat(output, "1.00 1.00 1.00");
+ break;
+ case 1: // Cyan
+ strcat(output, "0.00 1.00 1.00");
+ break;
+ case 2: // Blue
+ strcat(output, "0.00 0.00 1.00");
+ break;
+ case 3: // Magenta
+ strcat(output, "1.00 0.00 1.00");
+ break;
+ case 4: // Red
+ strcat(output, "1.00 0.00 0.00");
+ break;
+ case 5: // Yellow
+ strcat(output, "1.00 1.00 0.00");
+ break;
+ case 6: // Green
+ strcat(output, "0.00 1.00 0.00");
+ break;
+ default: // Black
+ strcat(output, "0.00 0.00 0.00");
+ break;
+ }
+ strcat(output, " setrgbcolor");
+ } else {
+ // Use CMYK colour space
+ switch(colour) {
+ case 0: // White
+ strcat(output, "0.00 0.00 0.00 0.00");
+ break;
+ case 1: // Cyan
+ strcat(output, "1.00 0.00 0.00 0.00");
+ break;
+ case 2: // Blue
+ strcat(output, "1.00 1.00 0.00 0.00");
+ break;
+ case 3: // Magenta
+ strcat(output, "0.00 1.00 0.00 0.00");
+ break;
+ case 4: // Red
+ strcat(output, "0.00 1.00 1.00 0.00");
+ break;
+ case 5: // Yellow
+ strcat(output, "0.00 0.00 1.00 0.00");
+ break;
+ case 6: // Green
+ strcat(output, "1.00 0.00 1.00 0.00");
+ break;
+ default: // Black
+ strcat(output, "0.00 0.00 0.00 1.00");
+ break;
+ }
+ strcat(output, " setcmykcolor");
+ }
}
+INTERNAL int ps_plot(struct zint_symbol *symbol) {
+ FILE *feps;
+ int fgred, fggrn, fgblu, bgred, bggrn, bgblu;
+ float red_ink, green_ink, blue_ink, red_paper, green_paper, blue_paper;
+ float cyan_ink, magenta_ink, yellow_ink, black_ink;
+ float cyan_paper, magenta_paper, yellow_paper, black_paper;
+ int error_number = 0;
+ float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy;
+ float radius;
+ int colour_index, colour_rect_counter;
+ char ps_color[30];
+
+ struct zint_vector_rect *rect;
+ struct zint_vector_hexagon *hex;
+ struct zint_vector_circle *circle;
+ struct zint_vector_string *string;
+ const char *locale = NULL;
+
+ if (symbol->output_options & BARCODE_STDOUT) {
+ feps = stdout;
+ } else {
+ feps = fopen(symbol->outfile, "w");
+ }
+ if (feps == NULL) {
+ strcpy(symbol->errtxt, "645: Could not open output file");
+ return ZINT_ERROR_FILE_ACCESS;
+ }
+
+ 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;
+
+ /* Convert RGB to CMYK */
+ if (red_ink > green_ink) {
+ if (blue_ink > red_ink) {
+ black_ink = 1 - blue_ink;
+ } else {
+ black_ink = 1 - red_ink;
+ }
+ } else {
+ if (blue_ink > red_ink) {
+ black_ink = 1 - blue_ink;
+ } else {
+ black_ink = 1 - green_ink;
+ }
+ }
+ if (black_ink < 1.0) {
+ cyan_ink = (1 - red_ink - black_ink) / (1 - black_ink);
+ magenta_ink = (1 - green_ink - black_ink) / (1 - black_ink);
+ yellow_ink = (1 - blue_ink - black_ink) / (1 - black_ink);
+ } else {
+ cyan_ink = 0.0;
+ magenta_ink = 0.0;
+ yellow_ink = 0.0;
+ }
+
+ if (red_paper > green_paper) {
+ if (blue_paper > red_paper) {
+ black_paper = 1 - blue_paper;
+ } else {
+ black_paper = 1 - red_paper;
+ }
+ } else {
+ if (blue_paper > red_paper) {
+ black_paper = 1 - blue_paper;
+ } else {
+ black_paper = 1 - green_paper;
+ }
+ }
+ if (black_paper < 1.0) {
+ cyan_paper = (1 - red_paper - black_paper) / (1 - black_paper);
+ magenta_paper = (1 - green_paper - black_paper) / (1 - black_paper);
+ yellow_paper = (1 - blue_paper - black_paper) / (1 - black_paper);
+ } else {
+ cyan_paper = 0.0;
+ magenta_paper = 0.0;
+ yellow_paper = 0.0;
+ }
+
+ /* Start writing the header */
+ fprintf(feps, "%%!PS-Adobe-3.0 EPSF-3.0\n");
+ fprintf(feps, "%%%%Creator: Zint %d.%d.%d\n", ZINT_VERSION_MAJOR, ZINT_VERSION_MINOR, ZINT_VERSION_RELEASE);
+ fprintf(feps, "%%%%Title: Zint Generated Symbol\n");
+ fprintf(feps, "%%%%Pages: 0\n");
+ fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", (int) ceil(symbol->vector->width), (int) ceil(symbol->vector->height));
+ fprintf(feps, "%%%%EndComments\n");
+
+ /* Definitions */
+ fprintf(feps, "/TL { setlinewidth moveto lineto stroke } bind def\n");
+ fprintf(feps, "/TD { newpath 0 360 arc 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 */
+ if ((symbol->output_options & CMYK_COLOUR) == 0) {
+ fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_paper, green_paper, blue_paper);
+ } else {
+ fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_paper, magenta_paper, yellow_paper, black_paper);
+ }
+ fprintf(feps, "%.2f 0.00 TB 0.00 %.2f TR\n", symbol->vector->height, symbol->vector->width);
+
+ fprintf(feps, "TE\n");
+ if (symbol->symbology != BARCODE_ULTRA) {
+ if ((symbol->output_options & CMYK_COLOUR) == 0) {
+ fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
+ } else {
+ fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
+ }
+ }
+
+ // Rectangles
+ if (symbol->symbology == BARCODE_ULTRA) {
+ for (colour_index = 0; colour_index <= 7; colour_index++) {
+ colour_rect_counter = 0;
+ rect = symbol->vector->rectangles;
+ while (rect) {
+ if (rect->colour == colour_index) {
+ if (colour_rect_counter == 0) {
+ //Set new colour
+ colour_to_pscolor(symbol->output_options, colour_index, ps_color);
+ fprintf(feps, "%s\n", ps_color);
+ }
+ colour_rect_counter++;
+ fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", rect->height, (symbol->vector->height - rect->y) - rect->height, rect->x, rect->width);
+ fprintf(feps, "TE\n");
+ }
+ rect = rect->next;
+ }
+ }
+ } else {
+ rect = symbol->vector->rectangles;
+ while (rect) {
+ fprintf(feps, "%.2f %.2f TB %.2f %.2f TR\n", rect->height, (symbol->vector->height - rect->y) - rect->height, rect->x, rect->width);
+ fprintf(feps, "TE\n");
+ rect = rect->next;
+ }
+ }
+
+ // Hexagons
+ hex = symbol->vector->hexagons;
+ while (hex) {
+ radius = hex->diameter / 2.0;
+ ay = (symbol->vector->height - hex->y) + (1.0 * radius);
+ by = (symbol->vector->height - hex->y) + (0.5 * radius);
+ cy = (symbol->vector->height - hex->y) - (0.5 * radius);
+ dy = (symbol->vector->height - hex->y) - (1.0 * radius);
+ ey = (symbol->vector->height - hex->y) - (0.5 * radius);
+ fy = (symbol->vector->height - hex->y) + (0.5 * radius);
+ ax = hex->x;
+ bx = hex->x + (0.86 * radius);
+ cx = hex->x + (0.86 * radius);
+ dx = hex->x;
+ ex = hex->x - (0.86 * radius);
+ fx = hex->x - (0.86 * radius);
+ fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TH\n", ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy);
+ hex = hex->next;
+ }
+
+ // Circles
+ circle = symbol->vector->circles;
+ while (circle) {
+ if (circle->colour) {
+ // A 'white' circle
+ if ((symbol->output_options & CMYK_COLOUR) == 0) {
+ fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_paper, green_paper, blue_paper);
+ } else {
+ fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_paper, magenta_paper, yellow_paper, black_paper);
+ }
+ fprintf(feps, "%.2f %.2f %.2f TD\n", circle->x, (symbol->vector->height - circle->y), circle->diameter / 2.0);
+ if (circle->next) {
+ if ((symbol->output_options & CMYK_COLOUR) == 0) {
+ fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
+ } else {
+ fprintf(feps, "%.2f %.2f %.2f %.2f setcmykcolor\n", cyan_ink, magenta_ink, yellow_ink, black_ink);
+ }
+ }
+ } else {
+ // A 'black' circle
+ fprintf(feps, "%.2f %.2f %.2f TD\n", circle->x, (symbol->vector->height - circle->y), circle->diameter / 2.0);
+ }
+ circle = circle->next;
+ }
+
+ // Text
+ string = symbol->vector->strings;
+ while (string) {
+ fprintf(feps, "matrix currentmatrix\n");
+ fprintf(feps, "/Helvetica findfont\n");
+ fprintf(feps, "%.2f scalefont setfont\n", string->fsize);
+ fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", string->x, (symbol->vector->height - string->y));
+ fprintf(feps, " (%s) stringwidth\n", string->text);
+ fprintf(feps, "pop\n");
+ fprintf(feps, "-2 div 0 rmoveto\n");
+ fprintf(feps, " (%s) show\n", string->text);
+ fprintf(feps, "setmatrix\n");
+ string = string->next;
+ }
+
+ //fprintf(feps, "\nshowpage\n");
+
+ if (symbol->output_options & BARCODE_STDOUT) {
+ fflush(feps);
+ } else {
+ fclose(feps);
+ }
+
+ if (locale)
+ setlocale(LC_ALL, locale);
+
+ return error_number;
+}
diff --git a/backend/qr.c b/backend/qr.c
index 2fe6412..40a1c32 100644
--- a/backend/qr.c
+++ b/backend/qr.c
@@ -1,8 +1,7 @@
-/* qr.c Handles QR Code */
+/* qr.c Handles QR Code, Micro QR Code, UPNQR and rMQR
-/*
libzint - the open source barcode library
- Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -28,7 +27,8 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
#include <string.h>
#ifdef _MSC_VER
@@ -39,2334 +39,3069 @@
#include "sjis.h"
#include "qr.h"
#include "reedsol.h"
+#include <assert.h>
+
+INTERNAL int utf_to_eci(const int eci, const unsigned char source[], unsigned char dest[], size_t *length); /* Convert Unicode to other encodings */
+
+/* Returns true if input glyph is in the Alphanumeric set */
+static int is_alpha(const unsigned int glyph, const int gs1) {
+ int retval = 0;
+
+ if ((glyph >= '0') && (glyph <= '9')) {
+ retval = 1;
+ } else if ((glyph >= 'A') && (glyph <= 'Z')) {
+ retval = 1;
+ } else if (gs1 && glyph == '[') {
+ retval = 1;
+ } else {
+ switch (glyph) {
+ case ' ':
+ case '$':
+ case '%':
+ case '*':
+ case '+':
+ case '-':
+ case '.':
+ case '/':
+ case ':':
+ retval = 1;
+ break;
+ }
+ }
+
+ return retval;
+}
+
+/* Bits multiplied by this for costs, so as to be whole integer divisible by 2 and 3 */
+#define QR_MULT 6
+
+/* Whether in numeric or not. If in numeric, *p_end is set to position after numeric, and *p_cost is set to per-numeric cost */
+static int in_numeric(const unsigned int jisdata[], const size_t length, const unsigned int posn, unsigned int* p_end, unsigned int* p_cost) {
+ unsigned int i, digit_cnt;
+
+ if (posn < *p_end) {
+ return 1;
+ }
+
+ /* Attempt to calculate the average 'cost' of using numeric mode in number of bits (times QR_MULT) */
+ for (i = posn; i < length && i < posn + 4 && jisdata[i] >= '0' && jisdata[i] <= '9'; i++);
+
+ digit_cnt = i - posn;
+
+ if (digit_cnt == 0) {
+ *p_end = 0;
+ return 0;
+ }
+ *p_end = i;
+ *p_cost = digit_cnt == 1 ? 24 /* 4 * QR_MULT */ : digit_cnt == 2 ? 21 /* (7 / 2) * QR_MULT */ : 20 /* (10 / 3) * QR_MULT) */;
+ return 1;
+}
+
+/* Whether in alpha or not. If in alpha, *p_end is set to position after alpha, and *p_cost is set to per-alpha cost. For GS1, *p_pcent set if 2nd char percent */
+static int in_alpha(const unsigned int jisdata[], const size_t length, const unsigned int posn, unsigned int* p_end, unsigned int* p_cost, unsigned int* p_pcent, unsigned int gs1) {
+ int two_alphas;
+
+ if (posn < *p_end) {
+ if (gs1 && *p_pcent) {
+ /* Previous 2nd char was a percent, so allow for second half of doubled-up percent here */
+ two_alphas = posn < length - 1 && is_alpha(jisdata[posn + 1], gs1);
+ *p_cost = two_alphas ? 33 /* (11 / 2) * QR_MULT */ : 36 /* 6 * QR_MULT */;
+ *p_pcent = 0;
+ }
+ return 1;
+ }
+
+ /* Attempt to calculate the average 'cost' of using alphanumeric mode in number of bits (times QR_MULT) */
+ if (!is_alpha(jisdata[posn], gs1)) {
+ *p_end = 0;
+ *p_pcent = 0;
+ return 0;
+ }
+
+ if (gs1 && jisdata[posn] == '%') { /* Must double-up so counts as 2 chars */
+ *p_end = posn + 1;
+ *p_cost = 66; /* 11 * QR_MULT */
+ *p_pcent = 0;
+ return 1;
+ }
+
+ two_alphas = posn < length - 1 && is_alpha(jisdata[posn + 1], gs1);
+
+ *p_end = two_alphas ? posn + 2 : posn + 1;
+ *p_cost = two_alphas ? 33 /* (11 / 2) * QR_MULT */ : 36 /* 6 * QR_MULT */;
+ *p_pcent = two_alphas && gs1 && jisdata[posn + 1] == '%'; /* 2nd char is percent */
+ return 1;
+}
-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;
+/* Indexes into mode_types array (and state array) */
+#define QR_N 0 /* Numeric */
+#define QR_A 1 /* Alphanumeric */
+#define QR_B 2 /* Byte */
+#define QR_K 3 /* Kanji */
+
+static const char mode_types[] = { 'N', 'A', 'B', 'K', }; /* Must be in same order as QR_N etc */
+
+#define QR_NUM_MODES 4
+
+/* Indexes into state array (0..3 head costs) */
+#define QR_VER 4 /* Version */
+#define QR_GS1 5 /* GS1 mode (boolean) */
+#define QR_N_END 6 /* Numeric end index */
+#define QR_N_COST 7 /* Numeric cost */
+#define QR_A_END 8 /* Alpha end index */
+#define QR_A_COST 9 /* Alpha cost */
+#define QR_A_PCENT 10 /* Alpha 2nd char percent (GS1-specific) */
+
+/* Costs set to this for invalid MICROQR modes for versions M1 and M2.
+ * 128 is the max number of data bits for M4-L (ISO/IEC 18004:2015 Table 7) */
+#define QR_MICROQR_MAX 774 /* (128 + 1) * QR_MULT */
+
+/* Initial mode costs */
+static unsigned int* qr_head_costs(unsigned int state[]) {
+ static const int head_costs[7][QR_NUM_MODES] = {
+ /* N A B K */
+ { (10 + 4) * QR_MULT, (9 + 4) * QR_MULT, (8 + 4) * QR_MULT, (8 + 4) * QR_MULT, }, /* QR */
+ { (12 + 4) * QR_MULT, (11 + 4) * QR_MULT, (16 + 4) * QR_MULT, (10 + 4) * QR_MULT, },
+ { (14 + 4) * QR_MULT, (13 + 4) * QR_MULT, (16 + 4) * QR_MULT, (12 + 4) * QR_MULT, },
+ { 3 * QR_MULT, QR_MICROQR_MAX, QR_MICROQR_MAX, QR_MICROQR_MAX, }, /* MICROQR */
+ { (4 + 1) * QR_MULT, (3 + 1) * QR_MULT, QR_MICROQR_MAX, QR_MICROQR_MAX, },
+ { (5 + 2) * QR_MULT, (4 + 2) * QR_MULT, (4 + 2) * QR_MULT, (3 + 2) * QR_MULT, },
+ { (6 + 3) * QR_MULT, (5 + 3) * QR_MULT, (5 + 3) * QR_MULT, (4 + 3) * QR_MULT, }
+ };
+ int version;
+
+ /* Head costs kept in states 0..3 */
+ if (state[QR_N] != 0) { /* Numeric non-zero in all configs */
+ return state; /* Already set */
+ }
+
+ version = state[QR_VER];
+
+ if (version < RMQR_VERSION) { /* QRCODE */
+ if (version < 10) {
+ memcpy(state, head_costs, QR_NUM_MODES * sizeof(unsigned int));
+ } else if (version < 27) {
+ memcpy(state, head_costs + 1, QR_NUM_MODES * sizeof(unsigned int));
+ } else {
+ memcpy(state, head_costs + 2, QR_NUM_MODES * sizeof(unsigned int));
+ }
+ } else if (version < MICROQR_VERSION) { /* RMQR */
+ version -= RMQR_VERSION;
+ state[QR_N] = (rmqr_numeric_cci[version] + 3) * QR_MULT;
+ state[QR_A] = (rmqr_alphanum_cci[version] + 3) * QR_MULT;
+ state[QR_B] = (rmqr_byte_cci[version] + 3) * QR_MULT;
+ state[QR_K] = (rmqr_kanji_cci[version] + 3) * QR_MULT;
+ } else { /* MICROQR */
+ memcpy(state, head_costs + 3 + (version - MICROQR_VERSION), QR_NUM_MODES * sizeof(unsigned int));
+ }
+
+ return state;
}
-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';
- }
- }
- }
- }
- }
+/* Costs of switching modes from k to j */
+static unsigned int qr_switch_cost(unsigned int state[], const int k, const int j) {
+ (void)k; /* Unused */
+ return state[j]; /* Same as head cost */
}
-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 & 1) == 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 & 1) == 0)
- count += 3; // 7 in total
- else
- count += 4;
- break;
- }
- }
-
- return count;
+/* Calculate cost of encoding character */
+static void qr_cur_cost(unsigned int state[], const unsigned int jisdata[], const size_t length, const int i, char* char_modes, unsigned int prev_costs[], unsigned int cur_costs[]) {
+ int cm_i = i * QR_NUM_MODES, m1, m2;
+ unsigned int version = state[QR_VER];
+ unsigned int gs1 = state[QR_GS1];
+ unsigned int* p_numeric_end = &state[QR_N_END];
+ unsigned int* p_numeric_cost = &state[QR_N_COST];
+ unsigned int* p_alpha_end = &state[QR_A_END];
+ unsigned int* p_alpha_cost = &state[QR_A_COST];
+ unsigned int* p_alpha_pcent = &state[QR_A_PCENT];
+
+ m1 = version == MICROQR_VERSION;
+ m2 = version == MICROQR_VERSION + 1;
+
+ if (jisdata[i] > 0xFF) {
+ cur_costs[QR_B] = prev_costs[QR_B] + ((m1 || m2) ? QR_MICROQR_MAX : 96); /* 16 * QR_MULT */
+ char_modes[cm_i + QR_B] = 'B';
+ cur_costs[QR_K] = prev_costs[QR_K] + ((m1 || m2) ? QR_MICROQR_MAX : 78); /* 13 * QR_MULT */
+ char_modes[cm_i + QR_K] = 'K';
+ } else {
+ if (in_numeric(jisdata, length, i, p_numeric_end, p_numeric_cost)) {
+ cur_costs[QR_N] = prev_costs[QR_N] + *p_numeric_cost;
+ char_modes[cm_i + QR_N] = 'N';
+ }
+ if (in_alpha(jisdata, length, i, p_alpha_end, p_alpha_cost, p_alpha_pcent, gs1)) {
+ cur_costs[QR_A] = prev_costs[QR_A] + (m1 ? QR_MICROQR_MAX : *p_alpha_cost);
+ char_modes[cm_i + QR_A] = 'A';
+ }
+ cur_costs[QR_B] = prev_costs[QR_B] + ((m1 || m2) ? QR_MICROQR_MAX : 48); /* 8 * QR_MULT */
+ char_modes[cm_i + QR_B] = 'B';
+ }
}
-static inline void qr_bscan(char *binary, int data, int h)
-{
- for (; h; h>>=1) {
- concat(binary, data & h ? "1" : "0");
- }
+static void qr_define_mode(char mode[], const unsigned int jisdata[], const size_t length, const int gs1, const int version, const int debug) {
+ unsigned int state[11] = {
+ 0 /*N*/, 0 /*A*/, 0 /*B*/, 0 /*K*/,
+ (unsigned int) version, (unsigned int) gs1,
+ 0 /*numeric_end*/, 0 /*numeric_cost*/, 0 /*alpha_end*/, 0 /*alpha_cost*/, 0 /*alpha_pcent*/
+ };
+
+ pn_define_mode(mode, jisdata, length, debug, state, mode_types, QR_NUM_MODES, qr_head_costs, qr_switch_cost, NULL, qr_cur_cost);
+}
+
+/* Return mode indicator bits based on version */
+static int mode_bits(const int version) {
+ if (version < RMQR_VERSION) {
+ return 4; /* QRCODE */
+ }
+ if (version < MICROQR_VERSION) {
+ return 3; /* RMQR */
+ }
+ return version - MICROQR_VERSION; /* MICROQR */
+}
+
+/* Return character count indicator bits based on version and mode */
+static int cci_bits(const int version, const int mode) {
+ static const int cci_bits[7][QR_NUM_MODES] = {
+ /* N A B K */
+ { 10, 9, 8, 8, }, /* QRCODE */
+ { 12, 11, 16, 10, },
+ { 14, 13, 16, 12, },
+ { 3, 0, 0, 0, }, /* MICROQR */
+ { 4, 3, 0, 0, },
+ { 5, 4, 4, 3, },
+ { 6, 5, 5, 4, }
+ };
+ static const unsigned short int* rmqr_ccis[QR_NUM_MODES] = {
+ rmqr_numeric_cci, rmqr_alphanum_cci, rmqr_byte_cci, rmqr_kanji_cci,
+ };
+ int mode_index = strchr(mode_types, mode) - mode_types;
+
+ if (version < RMQR_VERSION) { /* QRCODE */
+ if (version < 10) {
+ return cci_bits[0][mode_index];
+ }
+ if (version < 27) {
+ return cci_bits[1][mode_index];
+ }
+ return cci_bits[2][mode_index];
+ }
+ if (version < MICROQR_VERSION) { /* RMQR */
+ return rmqr_ccis[mode_index][version - RMQR_VERSION];
+ }
+ return cci_bits[3 + (version - MICROQR_VERSION)][mode_index]; /* MICROQR */
}
-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;
- int short_data_block_length, i, scheme = 1;
- char data_block, padbits;
- int current_binlen, current_bytes;
- int toggle, percent;
-
+/* Returns mode indicator based on version and mode */
+static const char* mode_indicator(const int version, const int mode) {
+ static const char* mode_indicators[6][QR_NUM_MODES] = {
+ /* N A B K */
+ { "0001", "0010", "0100", "1000", }, /* QRCODE */
+ { "001", "010", "011", "100", }, /* RMQR */
+ { "", "", "", "", }, /* MICROQR */
+ { "0", "1", "", "", },
+ { "00", "01", "10", "11", },
+ { "000", "001", "010", "011", },
+ };
+
+ int mode_index = strchr(mode_types, mode) - mode_types;
+
+ if (version < RMQR_VERSION) {
+ return mode_indicators[0][mode_index]; /* QRCODE */
+ }
+ if (version < MICROQR_VERSION) {
+ return mode_indicators[1][mode_index] /* RMQR */;
+ }
+ return mode_indicators[2 + version - MICROQR_VERSION][mode_index]; /* MICROQR */
+}
+
+/* Returns terminator bits based on version */
+static int terminator_bits(const int version) {
+ if (version < RMQR_VERSION) {
+ return 4; /* QRCODE */
+ }
+ if (version < MICROQR_VERSION) {
+ return 3; /* RMQR */
+ }
+ return 3 + (version - MICROQR_VERSION) * 2; /* MICROQR (Note not actually using this at the moment) */
+}
+
+/* Convert input data to a binary stream and add padding */
+static void qr_binary(unsigned char datastream[], const int version, const int target_codewords, const char mode[], const unsigned int jisdata[], const size_t length,
+ const int gs1, const int eci, const int est_binlen, const int debug) {
+ unsigned int position = 0;
+ int i;
+ int termbits, padbits;
+ int current_binlen, current_bytes;
+ int toggle, percent;
+ int percent_count;
+
#ifndef _MSC_VER
- char binary[est_binlen + 12];
+ 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;
- } else if((version >= 10) && (version <= 26)) {
- scheme = 2;
- } else if(version >= 27) {
- scheme = 3;
- }
-
-#ifdef _DEBUG_MODE_
- for(i = 0; i < length; i++) {
- printf("%c", mode[i]);
- }
- printf("\n");
+ char* binary = (char *) _alloca(est_binlen + 12);
#endif
+ strcpy(binary, "");
+
+ if (gs1) { /* Not applicable to MICROQR */
+ if (version < RMQR_VERSION) {
+ strcat(binary, "0101"); /* FNC1 */
+ } else {
+ strcat(binary, "101");
+ }
+ }
+
+ if (eci != 0) { /* Not applicable to RMQR or MICROQR */
+ strcat(binary, "0111"); /* ECI (Table 4) */
+ if (eci <= 127) {
+ bin_append(eci, 8, binary); /* 000000 to 000127 */
+ } else if (eci <= 16383) {
+ bin_append(0x8000 + eci, 16, binary); /* 000000 to 016383 */
+ } else {
+ bin_append(0xC00000 + eci, 24, binary); /* 000000 to 999999 */
+ }
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ for (i = 0; i < (int) length; i++) {
+ printf("%c", mode[i]);
+ }
+ printf("\n");
+ }
+
+ percent = 0;
+
+ do {
+ char data_block = mode[position];
+ int short_data_block_length = 0;
+ int double_byte = 0;
+ do {
+ if (data_block == 'B' && jisdata[position + short_data_block_length] > 0xFF) {
+ double_byte++;
+ }
+ 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 */
+ strcat(binary, mode_indicator(version, data_block));
+
+ /* Character count indicator */
+ bin_append(short_data_block_length, cci_bits(version, data_block), binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Kanji block (length %d)\n\t", short_data_block_length);
+ }
+
+ /* Character representation */
+ for (i = 0; i < short_data_block_length; i++) {
+ unsigned int jis = jisdata[position + i];
+ int prod;
+
+ if (jis >= 0x8140 && jis <= 0x9ffc)
+ jis -= 0x8140;
+
+ else if (jis >= 0xe040 && jis <= 0xebbf)
+ jis -= 0xc140;
+
+ prod = ((jis >> 8) * 0xc0) + (jis & 0xff);
+
+ bin_append(prod, 13, binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("0x%04X ", prod);
+ }
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("\n");
+ }
+
+ break;
+ case 'B':
+ /* Byte mode */
+ /* Mode indicator */
+ strcat(binary, mode_indicator(version, data_block));
+
+ /* Character count indicator */
+ bin_append(short_data_block_length + double_byte, cci_bits(version, data_block), binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Byte block (length %d)\n\t", short_data_block_length + double_byte);
+ }
+
+ /* Character representation */
+ for (i = 0; i < short_data_block_length; i++) {
+ unsigned int byte = jisdata[position + i];
+
+ if (gs1 && (byte == '[')) {
+ byte = 0x1d; /* FNC1 */
+ }
+
+ bin_append(byte, byte > 0xFF ? 16 : 8, binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("0x%02X(%d) ", byte, byte);
+ }
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("\n");
+ }
+
+ break;
+ case 'A':
+ /* Alphanumeric mode */
+ /* Mode indicator */
+ strcat(binary, mode_indicator(version, data_block));
+
+ percent_count = 0;
+ if (gs1) {
+ for (i = 0; i < short_data_block_length; i++) {
+ if (jisdata[position + i] == '%') {
+ percent_count++;
+ }
+ }
+ }
+
+ /* Character count indicator */
+ bin_append(short_data_block_length + percent_count, cci_bits(version, data_block), binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Alpha block (length %d)\n\t", short_data_block_length + percent_count);
+ }
+
+ /* 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 (i < short_data_block_length && 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 (i < short_data_block_length && 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;
+ }
+ }
+ }
+
+ bin_append(prod, 1 + (5 * count), binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("0x%X ", prod);
+ }
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("\n");
+ }
+
+ break;
+ case 'N':
+ /* Numeric mode */
+ /* Mode indicator */
+ strcat(binary, mode_indicator(version, data_block));
+
+ /* Character count indicator */
+ bin_append(short_data_block_length, cci_bits(version, data_block), binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ 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, prod;
+
+ first = posn(NEON, (char) jisdata[position + i]);
+ count = 1;
+ prod = first;
+
+ if (i + 1 < short_data_block_length && mode[position + i + 1] == 'N') {
+ int second = posn(NEON, (char) jisdata[position + i + 1]);
+ count = 2;
+ prod = (prod * 10) + second;
+
+ if (i + 2 < short_data_block_length && mode[position + i + 2] == 'N') {
+ int third = posn(NEON, (char) jisdata[position + i + 2]);
+ count = 3;
+ prod = (prod * 10) + third;
+ }
+ }
+
+ bin_append(prod, 1 + (3 * count), binary);
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("0x%X(%d) ", prod, prod);
+ }
+
+ i += count;
+ };
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("\n");
+ }
+
+ break;
+ }
+
+ position += short_data_block_length;
+ } while (position < length);
+
+ if (version >= MICROQR_VERSION && version < MICROQR_VERSION + 4) {
+ /* MICROQR does its own terminating/padding */
+ strcpy((char*)datastream, binary);
+ return;
+ }
+
+ /* Terminator */
+ current_binlen = (int)strlen(binary);
+ termbits = 8 - current_binlen % 8;
+ if (termbits == 8) {
+ termbits = 0;
+ }
+ current_bytes = (current_binlen + termbits) / 8;
+ if (termbits || current_bytes < target_codewords) {
+ int max_termbits = terminator_bits(version);
+ termbits = termbits < max_termbits && current_bytes == target_codewords ? termbits : max_termbits;
+ bin_append(0, termbits, binary);
+ current_binlen += termbits;
+ }
+
+ /* Padding bits */
+ padbits = 8 - current_binlen % 8;
+ if (padbits == 8) {
+ padbits = 0;
+ }
+ if (padbits) {
+ current_bytes = (current_binlen + padbits) / 8;
+ bin_append(0, padbits, binary);
+ }
+
+ /* Put data into 8-bit codewords */
+ for (i = 0; i < current_bytes; i++) {
+ int p;
+ datastream[i] = 0x00;
+ for (p = 0; p < 8; p++) {
+ if (binary[i * 8 + p] == '1') {
+ datastream[i] += (0x80 >> p);
+ }
+ }
+ }
+
+ /* Add pad codewords */
+ toggle = 0;
+ for (i = current_bytes; i < target_codewords; i++) {
+ if (toggle == 0) {
+ datastream[i] = 0xec;
+ toggle = 1;
+ } else {
+ datastream[i] = 0x11;
+ toggle = 0;
+ }
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Resulting codewords:\n\t");
+ for (i = 0; i < target_codewords; i++) {
+ printf("0x%02X ", datastream[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 */
- qr_bscan(binary, short_data_block_length, 0x20 << (scheme*2)); /* scheme = 1..3 */
-#ifdef _DEBUG_MODE_
- printf("Kanji block (length %d)\n\t", short_data_block_length);
-#endif
-
- /* 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;
-
- qr_bscan(binary, prod, 0x1000);
-#ifdef _DEBUG_MODE_
- printf("0x%4X ", prod);
-#endif
- }
-#ifdef _DEBUG_MODE_
- printf("\n");
+/* Split data into blocks, add error correction and then interleave the blocks and error correction data */
+static void add_ecc(unsigned char fullstream[], const unsigned char datastream[], const int version, const int data_cw, const int blocks, int debug) {
+ int ecc_cw;
+ int short_data_block_length;
+ int qty_long_blocks;
+ int qty_short_blocks;
+ int ecc_block_length;
+ int i, j, length_this_block, posn;
+#ifdef _MSC_VER
+ unsigned char* data_block;
+ unsigned char* ecc_block;
+ unsigned char* interleaved_data;
+ unsigned char* interleaved_ecc;
#endif
-
- break;
- case 'B':
- /* Byte mode */
- /* Mode indicator */
- concat(binary, "0100");
-
- /* Character count indicator */
- qr_bscan(binary, short_data_block_length, scheme > 1 ? 0x8000 : 0x80); /* scheme = 1..3 */
-#ifdef _DEBUG_MODE_
- printf("Byte block (length %d)\n\t", short_data_block_length);
+
+ if (version < RMQR_VERSION) {
+ ecc_cw = qr_total_codewords[version - 1] - data_cw;
+ } else {
+ ecc_cw = rmqr_total_codewords[version - RMQR_VERSION] - data_cw;
+ }
+
+ short_data_block_length = data_cw / blocks;
+ qty_long_blocks = data_cw % blocks;
+ qty_short_blocks = blocks - qty_long_blocks;
+ ecc_block_length = ecc_cw / blocks;
+
+
+#ifndef _MSC_VER
+ unsigned char data_block[short_data_block_length + 1];
+ unsigned char ecc_block[ecc_block_length];
+ unsigned char interleaved_data[data_cw];
+ unsigned char interleaved_ecc[ecc_cw];
+#else
+ data_block = (unsigned char *) _alloca(short_data_block_length + 1);
+ ecc_block = (unsigned char *) _alloca(ecc_block_length);
+ interleaved_data = (unsigned char *) _alloca(data_cw);
+ interleaved_ecc = (unsigned char *) _alloca(ecc_cw);
#endif
- /* Character representation */
- for(i = 0; i < short_data_block_length; i++) {
- int byte = jisdata[position + i];
-
- if(gs1 && (byte == '[')) {
- byte = 0x1d; /* FNC1 */
- }
-
- qr_bscan(binary, byte, 0x80);
-#ifdef _DEBUG_MODE_
- printf("0x%2X(%d) ", byte, byte);
+
+ 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] = 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 & ZINT_DEBUG_PRINT) {
+ 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] = data_block[j];
+ }
+
+ if (i >= qty_short_blocks) {
+ /* NOLINT suppress clang-tidy warning: data_block[short_data_block_length] set for i >= qty_short_blocks */
+ interleaved_data[(short_data_block_length * blocks) + (i - qty_short_blocks)] = data_block[short_data_block_length]; // NOLINT
+ }
+
+ for (j = 0; j < ecc_block_length; j++) {
+ interleaved_ecc[(j * blocks) + i] = ecc_block[ecc_block_length - j - 1];
+ }
+
+ posn += length_this_block;
+ }
+
+ for (j = 0; j < data_cw; j++) {
+ fullstream[j] = interleaved_data[j]; // NOLINT suppress clang-tidy warning: interleaved_data[data_cw] fully set
+ }
+ for (j = 0; j < ecc_cw; j++) {
+ fullstream[j + data_cw] = interleaved_ecc[j]; // NOLINT suppress clang-tidy warning: interleaved_ecc[ecc_cw] fully set
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("\nData Stream: \n");
+ for (j = 0; j < (data_cw + ecc_cw); j++) {
+ printf("%2X ", fullstream[j]);
+ }
+ printf("\n");
+ }
+}
+
+static void place_finder(unsigned char grid[],const int size,const int x,const int y) {
+ int xp, yp;
+ char finder[] = {0x7F, 0x41, 0x5D, 0x5D, 0x5D, 0x41, 0x7F};
+
+ for (xp = 0; xp < 7; xp++) {
+ for (yp = 0; yp < 7; yp++) {
+ if (finder[yp] & 0x40 >> xp) {
+ grid[((yp + y) * size) + (xp + x)] = 0x11;
+ } else {
+ grid[((yp + y) * size) + (xp + x)] = 0x10;
+ }
+ }
+ }
+}
+
+static void place_align(unsigned char grid[],const int size,int x,int y) {
+ int xp, yp;
+ char alignment[] = {0x1F, 0x11, 0x15, 0x11, 0x1F};
+
+ x -= 2;
+ y -= 2; /* Input values represent centre of pattern */
+
+ for (xp = 0; xp < 5; xp++) {
+ for (yp = 0; yp < 5; yp++) {
+ if (alignment[yp] & 0x10 >> xp) {
+ grid[((yp + y) * size) + (xp + x)] = 0x11;
+ } else {
+ grid[((yp + y) * size) + (xp + x)] = 0x10;
+ }
+ }
+ }
+}
+
+static void setup_grid(unsigned char* grid,const int size,const int version) {
+ int i, toggle = 1;
+
+ /* 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 */
+
+ int loopsize = qr_align_loopsize[version - 1];
+ int x, y;
+ for (x = 0; x < loopsize; x++) {
+ for (y = 0; y < loopsize; y++) {
+ int xcoord = qr_table_e1[((version - 2) * 7) + x];
+ int 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] += 0x20;
+ 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;
+ }
+ }
+}
+
+static int cwbit(const unsigned char* fullstream, const int i) {
+ int resultant = 0;
+
+ if (fullstream[(i / 8)] & (0x80 >> (i % 8))) {
+ resultant = 1;
+ }
+
+ return resultant;
+}
+
+static void populate_grid(unsigned char* grid, const int h_size, const int v_size, const unsigned char* fullstream, const int cw) {
+ int direction = 1; /* up */
+ int row = 0; /* right hand side */
+
+ int i, n, y;
+
+ n = cw * 8;
+ y = v_size - 1;
+ i = 0;
+ while (i < n) {
+ int x = (h_size - 2) - (row * 2);
+
+ if ((x < 6) && (v_size == h_size))
+ x--; /* skip over vertical timing pattern */
+
+ if (!(grid[(y * h_size) + (x + 1)] & 0xf0)) {
+ if (cwbit(fullstream, i)) {
+ grid[(y * h_size) + (x + 1)] = 0x01;
+ } else {
+ grid[(y * h_size) + (x + 1)] = 0x00;
+ }
+ i++;
+ }
+
+ if (i < n) {
+ if (!(grid[(y * h_size) + x] & 0xf0)) {
+ if (cwbit(fullstream, i)) {
+ grid[(y * h_size) + x] = 0x01;
+ } else {
+ grid[(y * h_size) + x] = 0x00;
+ }
+ i++;
+ }
+ }
+
+ if (direction) {
+ y--;
+ } else {
+ y++;
+ }
+ if (y == -1) {
+ /* reached the top */
+ row++;
+ y = 0;
+ direction = 0;
+ }
+ if (y == v_size) {
+ /* reached the bottom */
+ row++;
+ y = v_size - 1;
+ direction = 1;
+ }
+ }
+}
+
+#ifdef ZINTLOG
+
+static int append_log(char log) {
+ FILE *file;
+
+ file = fopen("zintlog.txt", "a+");
+ fprintf(file, "%c", log);
+ fclose(file);
+ return 0;
+}
+
+static int write_log(char log[]) {
+ FILE *file;
+
+ file = fopen("zintlog.txt", "a+");
+ fprintf(file, log); /*writes*/
+ fprintf(file, "\r\n"); /*writes*/
+ fclose(file);
+ return 0;
+}
#endif
- }
-#ifdef _DEBUG_MODE_
- printf("\n");
+
+static int evaluate(unsigned char *eval,const int size,const int pattern) {
+ int x, y, block, weight;
+ int result = 0;
+ char state;
+ int p;
+ int dark_mods;
+ int percentage, k;
+ int a, b, afterCount, beforeCount;
+#ifdef ZINTLOG
+ int result_b = 0;
+ char str[15];
#endif
- break;
- case 'A':
- /* Alphanumeric mode */
- /* Mode indicator */
- concat(binary, "0010");
-
- /* Character count indicator */
- qr_bscan(binary, short_data_block_length, 0x40 << (2 * scheme)); /* scheme = 1..3 */
-#ifdef _DEBUG_MODE_
- printf("Alpha block (length %d)\n\t", short_data_block_length);
+
+#ifndef _MSC_VER
+ char local[size * size];
+#else
+ char* local = (char *) _alloca((size * size) * sizeof (char));
#endif
- /* 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;
- }
- }
- }
-
- qr_bscan(binary, prod, count == 2 ? 0x400 : 0x20); /* count = 1..2 */
-#ifdef _DEBUG_MODE_
- printf("0x%4X ", prod);
+
+
+#ifdef ZINTLOG
+ write_log("");
+ sprintf(str, "%d", pattern);
+ write_log(str);
#endif
- };
-#ifdef _DEBUG_MODE_
- printf("\n");
+
+ /* all eight bitmask variants have been encoded in the 8 bits of the bytes
+ * that make up the grid array. select them for evaluation according to the
+ * desired pattern.*/
+ for (x = 0; x < size; x++) {
+ for (y = 0; y < size; y++) {
+ if ((eval[(y * size) + x] & (0x01 << pattern)) != 0) {
+ local[(y * size) + x] = '1';
+ } else {
+ local[(y * size) + x] = '0';
+ }
+ }
+ }
+
+#ifdef ZINTLOG
+ //bitmask output
+ for (y = 0; y < size; y++) {
+ strcpy(str, "");
+ for (x = 0; x < size; x++) {
+ state = local[(y * size) + x];
+ append_log(state);
+ }
+ write_log("");
+ }
+ write_log("");
#endif
-
- break;
- case 'N':
- /* Numeric mode */
- /* Mode indicator */
- concat(binary, "0001");
-
- /* Character count indicator */
- qr_bscan(binary, short_data_block_length, 0x80 << (2 * scheme)); /* scheme = 1..3 */
-#ifdef _DEBUG_MODE_
- printf("Number block (length %d)\n\t", short_data_block_length);
+
+ /* 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 - 5));
+ }
+ block = 0;
+ state = local[(y * size) + x];
+ }
+ }
+ if (block > 5) {
+ result += (3 + (block - 5));
+ }
+ }
+
+ /* 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 - 5));
+ }
+ block = 0;
+ state = local[(y * size) + x];
+ }
+ }
+ if (block > 5) {
+ result += (3 + (block - 5));
+ }
+ }
+
+#ifdef ZINTLOG
+ /* output Test 1 */
+ sprintf(str, "%d", result);
+ result_b = result;
+ write_log(str);
#endif
- /* 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;
- }
- }
-
- qr_bscan(binary, prod, 1 << (3 * count)); /* count = 1..3 */
-#ifdef _DEBUG_MODE_
- printf("0x%4X (%d)", prod, prod);
+
+ /* Test 2: Block of modules in same color */
+ for (x = 0; x < size - 1; x++) {
+ for (y = 0; y < size - 1; y++) {
+ /* NOLINT suppress clang-tidy warning: local[size * size] fully set */
+ if (((local[(y * size) + x] == local[((y + 1) * size) + x]) && // NOLINT
+ (local[(y * size) + x] == local[(y * size) + (x + 1)])) &&
+ (local[(y * size) + x] == local[((y + 1) * size) + (x + 1)])) { // NOLINT
+ result += 3;
+ }
+ }
+ }
+
+#ifdef ZINTLOG
+ /* output Test 2 */
+ sprintf(str, "%d", result - result_b);
+ result_b = result;
+ write_log(str);
#endif
-
- i += count;
- };
-#ifdef _DEBUG_MODE_
- printf("\n");
+
+ /* 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;
+ for (weight = 0; weight < 7; weight++) {
+ if (local[((y + weight) * size) + x] == '1') {
+ p += (0x40 >> weight);
+ }
+ }
+ if (p == 0x5d) {
+ /* Pattern found, check before and after */
+ beforeCount = 0;
+ for (b = (y - 4); b < y; b++) {
+ if (b < 0) {
+ beforeCount++;
+ } else {
+ if (local[(b * size) + x] == '0') {
+ beforeCount++;
+ } else {
+ beforeCount = 0;
+ }
+ }
+ }
+
+ afterCount = 0;
+ for (a = (y + 7); a <= (y + 10); a++) {
+ if (a >= size) {
+ afterCount++;
+ } else {
+ if (local[(a * size) + x] == '0') {
+ afterCount++;
+ } else {
+ afterCount = 0;
+ }
+ }
+ }
+
+ if ((beforeCount == 4) || (afterCount == 4)) {
+ /* Pattern is preceeded or followed by light area
+ 4 modules wide */
+ result += 40;
+ }
+ }
+ }
+ }
+
+ /* Horizontal */
+ for (y = 0; y < size; y++) {
+ for (x = 0; x < (size - 7); x++) {
+ p = 0;
+ for (weight = 0; weight < 7; weight++) {
+ if (local[(y * size) + x + weight] == '1') {
+ p += (0x40 >> weight);
+ }
+ }
+ if (p == 0x5d) {
+ /* Pattern found, check before and after */
+ beforeCount = 0;
+ for (b = (x - 4); b < x; b++) {
+ if (b < 0) {
+ beforeCount++;
+ } else {
+ if (local[(y * size) + b] == '0') {
+ beforeCount++;
+ } else {
+ beforeCount = 0;
+ }
+ }
+ }
+
+ afterCount = 0;
+ for (a = (x + 7); a <= (x + 10); a++) {
+ if (a >= size) {
+ afterCount++;
+ } else {
+ if (local[(y * size) + a] == '0') {
+ afterCount++;
+ } else {
+ afterCount = 0;
+ }
+ }
+ }
+
+ if ((beforeCount == 4) || (afterCount == 4)) {
+ /* Pattern is preceeded or followed by light area
+ 4 modules wide */
+ result += 40;
+ }
+ }
+ }
+ }
+
+#ifdef ZINTLOG
+ /* output Test 3 */
+ sprintf(str, "%d", result - result_b);
+ result_b = result;
+ write_log(str);
#endif
-
- break;
- }
-
- position += short_data_block_length;
- } while (position < length) ;
-
- /* 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;
- }
- }
-
-#ifdef _DEBUG_MODE_
- printf("Resulting codewords:\n\t");
- for(i = 0; i < target_binlen; i++) {
- printf("0x%2X ", datastream[i]);
- }
- printf("\n");
+
+ /* 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;
+
+#ifdef ZINTLOG
+ /* output Test 4+summary */
+ sprintf(str, "%d", result - result_b);
+ write_log(str);
+ write_log("==========");
+ sprintf(str, "%d", result);
+ write_log(str);
#endif
+
+ return result;
}
-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;
-
-
+static void add_format_info_eval(unsigned char *eval,const int size,const int ecc_level,const 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++) {
+ eval[(i * size) + 8] = ((seq >> i) & 0x01) ? (0x01 >> pattern) : 0x00;
+ }
+
+ for (i = 0; i < 8; i++) {
+ eval[(8 * size) + (size - i - 1)] = ((seq >> i) & 0x01) ? (0x01 >> pattern) : 0x00;
+ }
+
+ for (i = 0; i < 6; i++) {
+ eval[(8 * size) + (5 - i)] = ((seq >> (i + 9)) & 0x01) ? (0x01 >> pattern) : 0x00;
+ }
+
+ for (i = 0; i < 7; i++) {
+ eval[(((size - 7) + i) * size) + 8] = ((seq >> (i + 8)) & 0x01) ? (0x01 >> pattern) : 0x00;
+ }
+
+ eval[(7 * size) + 8] = ((seq >> 6) & 0x01) ? (0x01 >> pattern) : 0x00;
+ eval[(8 * size) + 8] = ((seq >> 7) & 0x01) ? (0x01 >> pattern) : 0x00;
+ eval[(8 * size) + 7] = ((seq >> 8) & 0x01) ? (0x01 >> pattern) : 0x00;
+}
+
+static int apply_bitmask(unsigned char *grid,const int size,const int ecc_level) {
+ int x, y;
+ unsigned char p;
+ int pattern, penalty[8];
+ int best_val, best_pattern;
+
#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];
+ unsigned char mask[size * size];
+ unsigned char eval[size * size];
#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));
+ unsigned char* mask = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
+ unsigned char* eval = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
#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();
-
-#ifdef _DEBUG_MODE_
- 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");
+ /* Perform data masking */
+ for (x = 0; x < size; x++) {
+ for (y = 0; y < size; y++) {
+ mask[(y * size) + x] = 0x00;
+
+ // all eight bitmask variants are encoded in the 8 bits of the bytes that make up the mask array.
+ if (!(grid[(y * size) + x] & 0xf0)) { // exclude areas not to be masked.
+ if (((y + x) & 1) == 0) {
+ mask[(y * size) + x] += 0x01;
+ }
+ if ((y & 1) == 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)) & 1) == 0) {
+ mask[(y * size) + x] += 0x10;
+ }
+ if ((((y * x) & 1) + ((y * x) % 3)) == 0) {
+ mask[(y * size) + x] += 0x20;
+ }
+ if (((((y * x) & 1) + ((y * x) % 3)) & 1) == 0) {
+ mask[(y * size) + x] += 0x40;
+ }
+ if (((((y + x) & 1) + ((y * x) % 3)) & 1) == 0) {
+ mask[(y * size) + x] += 0x80;
+ }
+ }
+ }
+ }
+
+ // apply data masks to grid, result in eval
+ 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++) {
+
+ add_format_info_eval(eval, size, ecc_level, 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];
+ }
+ }
+
+#ifdef ZINTLOG
+ char str[15];
+ sprintf(str, "%d", best_val);
+ write_log("choosed pattern:");
+ write_log(str);
#endif
-
- 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];
- }
-
-#ifdef _DEBUG_MODE_
- printf("\nData Stream: \n");
- for(j = 0; j < (data_cw + ecc_cw); j++) {
- printf("%2X ", fullstream[j]);
- }
- printf("\n");
-#endif
-}
-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;
- }
- }
- }
+ /* Apply mask */
+ for (x = 0; x < size; x++) {
+ for (y = 0; y < size; y++) {
+ if (mask[(y * size) + x] & (0x01 << best_pattern)) {
+ if (grid[(y * size) + x] & 0x01) {
+ grid[(y * size) + x] = 0x00;
+ } else {
+ grid[(y * size) + x] = 0x01;
+ }
+ }
+ }
+ }
+
+ return best_pattern;
}
-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;
- }
- }
- }
+/* Add format information to grid */
+static void add_format_info(unsigned char *grid,const int size,const int ecc_level,const int pattern) {
+ 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 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;
- }
- }
+/* Add version information */
+static void add_version_info(unsigned char *grid,const int size,const int version) {
+ int i;
+
+ long int version_data = qr_annex_d[version - 7];
+ for (i = 0; i < 6; i++) {
+ grid[((size - 11) * size) + i] += (version_data >> (i * 3)) & 0x41;
+ grid[((size - 10) * size) + i] += (version_data >> ((i * 3) + 1)) & 0x41;
+ grid[((size - 9) * size) + i] += (version_data >> ((i * 3) + 2)) & 0x41;
+ grid[(i * size) + (size - 11)] += (version_data >> (i * 3)) & 0x41;
+ grid[(i * size) + (size - 10)] += (version_data >> ((i * 3) + 1)) & 0x41;
+ grid[(i * size) + (size - 9)] += (version_data >> ((i * 3) + 2)) & 0x41;
+ }
}
-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;
+static size_t blockLength(const size_t start,const char inputMode[],const size_t inputLength) {
+ /* Find the length of the block starting from 'start' */
+ size_t i;
+ int count;
+ char mode = inputMode[start];
+
+ count = 0;
+ i = start;
+
+ do {
+ count++;
+ } while (((i + count) < inputLength) && (inputMode[i + count] == mode));
+
+ return count;
}
-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);
+static int getBinaryLength(const int version, char inputMode[], const unsigned int inputData[], const size_t inputLength, const int gs1, const int eci, const int debug) {
+ /* Calculate the actual bitlength of the proposed binary string */
+ size_t i, j;
+ char currentMode;
+ int count = 0;
+ int alphalength;
+ int blocklength;
+
+ qr_define_mode(inputMode, inputData, inputLength, gs1, version, debug);
+
+ currentMode = ' '; // Null
+
+ if (gs1 == 1) { /* Not applicable to MICROQR */
+ if (version < RMQR_VERSION) {
+ count += 4;
+ } else {
+ count += 3;
+ }
+ }
+
+ if (eci != 0) { // RMQR and MICROQR do not support ECI
+ count += 4;
+ if (eci <= 127) {
+ count += 8;
+ } else if (eci <= 16383) {
+ count += 16;
+ } else {
+ count += 24;
+ }
+ }
+
+ for (i = 0; i < inputLength; i++) {
+ if (inputMode[i] != currentMode) {
+ count += mode_bits(version) + cci_bits(version, inputMode[i]);
+ blocklength = blockLength(i, inputMode, inputLength);
+ switch (inputMode[i]) {
+ case 'K':
+ count += (blocklength * 13);
+ break;
+ case 'B':
+ for (j = i; j < (i + blocklength); j++) {
+ if (inputData[j] > 0xff) {
+ count += 16;
+ } else {
+ count += 8;
+ }
+ }
+ break;
+ case 'A':
+ alphalength = blocklength;
+ if (gs1) {
+ // In alphanumeric mode % becomes %%
+ for (j = i; j < (i + blocklength); j++) {
+ if (inputData[j] == '%') {
+ alphalength++;
+ }
+ }
+ }
+ switch (alphalength % 2) {
+ case 0:
+ count += (alphalength / 2) * 11;
+ break;
+ case 1:
+ count += ((alphalength - 1) / 2) * 11;
+ count += 6;
+ break;
+ }
+ break;
+ case 'N':
+ switch (blocklength % 3) {
+ case 0:
+ count += (blocklength / 3) * 10;
+ break;
+ case 1:
+ count += ((blocklength - 1) / 3) * 10;
+ count += 4;
+ break;
+ case 2:
+ count += ((blocklength - 2) / 3) * 10;
+ count += 7;
+ break;
+ }
+ break;
+ }
+ currentMode = inputMode[i];
+ }
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("Estimated Binary Length: %d (version %d, eci %d, gs1 %d)\n", count, version, eci, gs1);
+ }
+
+ return count;
}
-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, k2;
+INTERNAL int qr_code(struct zint_symbol *symbol, const unsigned char source[], size_t length) {
+ int i, j, est_binlen;
+ int ecc_level, autosize, version, max_cw, target_codewords, blocks, size;
+ int bitmask, gs1;
+ int full_multibyte;
+ int canShrink;
#ifndef _MSC_VER
- char local[size * size];
+ unsigned int jisdata[length + 1];
+ char mode[length + 1];
#else
- char* local = (char *)_alloca((size * size) * sizeof(char));
+ unsigned char* datastream;
+ unsigned char* fullstream;
+ unsigned char* grid;
+ unsigned int* jisdata = (unsigned int *) _alloca((length + 1) * sizeof (unsigned int));
+ char* mode = (char *) _alloca(length + 1);
#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++;
- if(block ==5)
- result += 3;
-
- if(block>5)
- result +=1;
- } else {
- block=0;
- }
- }
- }
-
- /* 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++;
- if(block ==5)
- result += 3;
-
- if(block>5)
- result +=1;
- } else {
- block=0;
- }
- }
- }
-
- /* Test 2 fd02131114 */
- for(x = 0; x < size-1; x++) {
- for(y = 0; y < (size - 7) -1; y++) {
- // y + 1???
- if((local[((y + 1) * size) + x] == '1') &&
- (local[((y + 1) * size) + x+1] == '1') &&
- (local[(((y + 1)+1) * size) + x] == '1') &&
- (local[(((y + 1)+1) * size) + x+1] == '1')
- ) { result += 3; }
-
- if((local[((y + 1) * size) + x] == '0') &&
- (local[((y + 1) * size) + x+1] == '0') &&
- (local[(((y + 1)+1) * size) + x] == '0') &&
- (local[(((y + 1)+1) * size) + x+1] == '0')
- ) { result += 3; }
- }
- }
-
- /* Test 3: fd02131114 */
- /*pattern 10111010000 */
- /* Vertical */
- for(x = 0; x < size; x++) {
- for(y = 0; y < (size - 11); y++) {
- p = 0;
- if(local[(y * size) + x] == '1') { p += 1; }
- if(local[((y + 1) * size) + x] == '0') { p += 1; }
- if(local[((y + 2) * size) + x] == '1') { p += 1; }
- if(local[((y + 3) * size) + x] == '1') { p += 1; }
- if(local[((y + 4) * size) + x] == '1') { p += 1; }
- if(local[((y + 5) * size) + x] == '0') { p += 1; }
- if(local[((y + 6) * size) + x] == '1') { p += 1; }
- if(local[((y + 7) * size) + x] == '0') { p += 1; }
- if(local[((y + 8) * size) + x] == '0') { p += 1; }
- if(local[((y + 9) * size) + x] == '0') { p += 1; }
- if(local[((y + 10) * size) + x] == '0') { p += 1; }
- if(p == 11) {
- result += 40;
- }
- }
- }
-
- /* Horizontal */
- for(y = 0; y < size; y++) {
- for(x = 0; x < (size - 11); x++) {
- p = 0;
- if(local[(y * size) + x] == '1') { p += 1; }
- if(local[(y * size) + x + 1] == '0') { p += 1; }
- if(local[(y * size) + x + 2] == '1') { p += 1; }
- if(local[(y * size) + x + 3] == '1') { p += 1; }
- if(local[(y * size) + x + 4] == '1') { p += 1; }
- if(local[(y * size) + x + 5] == '0') { p += 1; }
- if(local[(y * size) + x + 6] == '1') { p += 1; }
- if(local[(y * size) + x + 7] == '0') { p += 1; }
- if(local[(y * size) + x + 8] == '0') { p += 1; }
- if(local[(y * size) + x + 9] == '0') { p += 1; }
- if(local[(y * size) + x + 10] == '0') { p += 1; }
- if(p == 11) {
- result += 40;
- }
- }
- }
-
- /*pattern 00001011101 */
- /* Vertical */
- for(x = 0; x < size; x++) {
- for(y = 0; y < (size - 11); y++) {
- p = 0;
- if(local[(y * size) + x] == '0') { p += 1; }
- if(local[((y + 1) * size) + x] == '0') { p += 1; }
- if(local[((y + 2) * size) + x] == '0') { p += 1; }
- if(local[((y + 3) * size) + x] == '0') { p += 1; }
- if(local[((y + 4) * size) + x] == '1') { p += 1; }
- if(local[((y + 5) * size) + x] == '0') { p += 1; }
- if(local[((y + 6) * size) + x] == '1') { p += 1; }
- if(local[((y + 7) * size) + x] == '1') { p += 1; }
- if(local[((y + 8) * size) + x] == '1') { p += 1; }
- if(local[((y + 9) * size) + x] == '0') { p += 1; }
- if(local[((y + 10) * size) + x] == '1') { p += 1; }
- if(p == 11) {
- result += 40;
- }
- }
- }
-
- /* Horizontal */
- for(y = 0; y < size; y++) {
- for(x = 0; x < (size - 11); x++) {
- p = 0;
- if(local[(y * size) + x] == '0') { p += 1; }
- if(local[(y * size) + x + 1] == '0') { p += 1; }
- if(local[(y * size) + x + 2] == '0') { p += 1; }
- if(local[(y * size) + x + 3] == '0') { p += 1; }
- if(local[(y * size) + x + 4] == '1') { p += 1; }
- if(local[(y * size) + x + 5] == '0') { p += 1; }
- if(local[(y * size) + x + 6] == '1') { p += 1; }
- if(local[(y * size) + x + 7] == '1') { p += 1; }
- if(local[(y * size) + x + 8] == '1') { p += 1; }
- if(local[(y * size) + x + 9] == '0') { p += 1; }
- if(local[(y * size) + x + 10] == '1') { p += 1; }
- if(p == 11) {
- 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));
- int m=0;
- for(x = 0; x < 100; x+=5) {
- if(x<percentage)
- m=x;
- }
-
- k=abs((m-50)/5);
- k2=abs((m+5-50)/5);
-
- int smallest=k;
- if(k2<smallest)
- smallest=k2;
-
- result += 10 * smallest;
-
- return result;
-}
+ gs1 = ((symbol->input_mode & 0x07) == GS1_MODE);
+ full_multibyte = symbol->option_3 == ZINT_FULL_MULTIBYTE; /* If set use Kanji mode in DATA_MODE or for single-byte Latin */
+
+ if ((symbol->input_mode & 0x07) == DATA_MODE) {
+ sjis_cpy(source, &length, jisdata, full_multibyte);
+ } else {
+ int done = 0;
+ if (symbol->eci != 20) { /* Unless ECI 20 (Shift JIS) */
+ /* Try single byte (Latin) conversion first */
+ int error_number = sjis_utf8tosb(symbol->eci && symbol->eci <= 899 ? symbol->eci : 3, source, &length, jisdata, full_multibyte);
+ if (error_number == 0) {
+ done = 1;
+ } else if (symbol->eci && symbol->eci <= 899) {
+ strcpy(symbol->errtxt, "575: Invalid characters in input data");
+ return error_number;
+ }
+ }
+ if (!done) {
+ /* Try Shift-JIS */
+ int error_number = sjis_utf8tomb(symbol, source, &length, jisdata);
+ if (error_number != 0) {
+ return error_number;
+ }
+ }
+ }
+
+ est_binlen = getBinaryLength(40, mode, jisdata, length, gs1, symbol->eci, symbol->debug);
+
+ ecc_level = LEVEL_L;
+ max_cw = 2956;
+ if ((symbol->option_1 >= 1) && (symbol->option_1 <= 4)) {
+ switch (symbol->option_1) {
+ case 1:
+ 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, "561: Input too long for selected error correction level");
+ return ZINT_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 (autosize != 40) {
+ est_binlen = getBinaryLength(autosize, mode, jisdata, length, gs1, symbol->eci, symbol->debug);
+ }
+
+ // Now see if the optimised binary will fit in a smaller symbol.
+ canShrink = 1;
+
+ do {
+ if (autosize == 1) {
+ canShrink = 0;
+ } else {
+ est_binlen = getBinaryLength(autosize - 1, mode, jisdata, length, gs1, symbol->eci, symbol->debug);
+
+ switch (ecc_level) {
+ case LEVEL_L:
+ if ((8 * qr_data_codewords_L[autosize - 2]) < est_binlen) {
+ canShrink = 0;
+ }
+ break;
+ case LEVEL_M:
+ if ((8 * qr_data_codewords_M[autosize - 2]) < est_binlen) {
+ canShrink = 0;
+ }
+ break;
+ case LEVEL_Q:
+ if ((8 * qr_data_codewords_Q[autosize - 2]) < est_binlen) {
+ canShrink = 0;
+ }
+ break;
+ case LEVEL_H:
+ if ((8 * qr_data_codewords_H[autosize - 2]) < est_binlen) {
+ canShrink = 0;
+ }
+ break;
+ }
+
+ if (canShrink == 1) {
+ // Optimisation worked - data will fit in a smaller symbol
+ autosize--;
+ } else {
+ // Data did not fit in the smaller symbol, revert to original size
+ est_binlen = getBinaryLength(autosize, mode, jisdata, length, gs1, symbol->eci, symbol->debug);
+ }
+ }
+ } while (canShrink == 1);
+
+ version = autosize;
+
+ if ((symbol->option_2 >= 1) && (symbol->option_2 <= 40)) {
+ /* If the user has selected a larger symbol than the smallest available,
+ then use the size the user has selected, and re-optimise for this
+ symbol size.
+ */
+ if (symbol->option_2 > version) {
+ version = symbol->option_2;
+ est_binlen = getBinaryLength(symbol->option_2, mode, jisdata, length, gs1, symbol->eci, symbol->debug);
+ }
+
+ if (symbol->option_2 < version) {
+ strcpy(symbol->errtxt, "569: Input too long for selected symbol size");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ }
+
+ /* Ensure maxium error correction capacity unless user-specified */
+ if (symbol->option_1 == -1 || symbol->option_1 != ecc_level) {
+ if (est_binlen <= qr_data_codewords_M[version - 1] * 8) {
+ ecc_level = LEVEL_M;
+ }
+ if (est_binlen <= qr_data_codewords_Q[version - 1] * 8) {
+ ecc_level = LEVEL_Q;
+ }
+ if (est_binlen <= qr_data_codewords_H[version - 1] * 8) {
+ ecc_level = LEVEL_H;
+ }
+ }
+
+ target_codewords = qr_data_codewords_L[version - 1];
+ blocks = qr_blocks_L[version - 1];
+ switch (ecc_level) {
+ case LEVEL_M: target_codewords = qr_data_codewords_M[version - 1];
+ blocks = qr_blocks_M[version - 1];
+ break;
+ case LEVEL_Q: target_codewords = qr_data_codewords_Q[version - 1];
+ blocks = qr_blocks_Q[version - 1];
+ break;
+ case LEVEL_H: target_codewords = qr_data_codewords_H[version - 1];
+ blocks = qr_blocks_H[version - 1];
+ break;
+ }
+
+#ifndef _MSC_VER
+ unsigned char datastream[target_codewords + 1];
+ unsigned char fullstream[qr_total_codewords[version - 1] + 1];
+#else
+ datastream = (unsigned char *) _alloca(target_codewords + 1);
+ fullstream = (unsigned char *) _alloca(qr_total_codewords[version - 1] + 1);
+#endif
+
+ qr_binary(datastream, version, target_codewords, mode, jisdata, length, gs1, symbol->eci, est_binlen, symbol->debug);
+#ifdef ZINT_TEST
+ if (symbol->debug & ZINT_DEBUG_TEST) debug_test_codeword_dump(symbol, datastream, target_codewords);
+#endif
+ add_ecc(fullstream, datastream, version, target_codewords, blocks, symbol->debug);
-void add_format_info_eval(unsigned char *eval, int size, int ecc_level, int pattern)
-{
- /* Add format information to grid */
+ size = qr_sizes[version - 1];
+#ifndef _MSC_VER
+ unsigned char grid[size * size];
+#else
+ grid = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
+#endif
- int format = pattern;
- unsigned int seq;
- int i;
+ for (i = 0; i < size; i++) {
+ for (j = 0; j < size; j++) {
+ grid[(i * size) + j] = 0;
+ }
+ }
- switch(ecc_level) {
- case LEVEL_L: format += 0x08; break;
- case LEVEL_Q: format += 0x18; break;
- case LEVEL_H: format += 0x10; break;
- }
+ setup_grid(grid, size, version);
+ populate_grid(grid, size, size, fullstream, qr_total_codewords[version - 1]);
- seq = qr_annex_c[format];
+ if (version >= 7) {
+ add_version_info(grid, size, version);
+ }
- for(i = 0; i < 6; i++) {
- eval[(i * size) + 8] = (seq >> i) & 0x01 ? (0x01 >> pattern) : 0x00;
- }
+ bitmask = apply_bitmask(grid, size, ecc_level);
- for(i = 0; i < 8; i++) {
- eval[(8 * size) + (size - i - 1)] = (seq >> i) & 0x01 ? (0x01 >> pattern) : 0x00;
- }
+ add_format_info(grid, size, ecc_level, bitmask);
- for(i = 0; i < 6; i++) {
- eval[(8 * size) + (5 - i)] = (seq >> (i + 9)) & 0x01 ? (0x01 >> pattern) : 0x00;
- }
+ symbol->width = size;
+ symbol->rows = size;
- for(i = 0; i < 7; i++) {
- eval[(((size - 7) + i) * size) + 8] = (seq >> (i + 8)) & 0x01 ? (0x01 >> pattern) : 0x00;
- }
+ 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;
+ }
- eval[(7 * size) + 8] = (seq >> 6) & 0x01 ? (0x01 >> pattern) : 0x00;
- eval[(8 * size) + 8] = (seq >> 7) & 0x01 ? (0x01 >> pattern) : 0x00;
- eval[(8 * size) + 7] = (seq >> 8) & 0x01 ? (0x01 >> pattern) : 0x00;
+ return 0;
}
-int apply_bitmask(unsigned char *grid, int size, int ecc_level)
-{
- 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];
+static void micro_qr_m1(struct zint_symbol *symbol, char binary_data[]) {
+ int i, j, latch;
+ int bits_total, bits_left;
+ int data_codewords, ecc_codewords;
+ unsigned char data_blocks[4], ecc_blocks[3];
+
+ bits_total = 20;
+ latch = 0;
+
+ /* Add terminator */
+ bits_left = bits_total - (int)strlen(binary_data);
+ if (bits_left <= 3) {
+ for (i = 0; i < bits_left; i++) {
+ strcat(binary_data, "0");
+ }
+ latch = 1;
+ } else {
+ strcat(binary_data, "000");
+ }
+
+ if (latch == 0) {
+ /* Manage last (4-bit) block */
+ bits_left = bits_total - (int)strlen(binary_data);
+ if (bits_left <= 4) {
+ for (i = 0; i < bits_left; i++) {
+ strcat(binary_data, "0");
+ }
+ latch = 1;
+ }
+ }
+
+ if (latch == 0) {
+ /* Complete current byte */
+ int remainder = 8 - (strlen(binary_data) % 8);
+ if (remainder == 8) {
+ remainder = 0;
+ }
+ for (i = 0; i < remainder; i++) {
+ strcat(binary_data, "0");
+ }
+
+ /* Add padding */
+ bits_left = bits_total - (int)strlen(binary_data);
+ if (bits_left > 4) {
+ remainder = (bits_left - 4) / 8;
+ for (i = 0; i < remainder; i++) {
+ strcat(binary_data, (i & 1) ? "00010001" : "11101100");
+ }
+ }
+ bin_append(0, 4, binary_data);
+ }
+
+ data_codewords = 3;
+ ecc_codewords = 2;
+
+ /* Copy data into codewords */
+ for (i = 0; i < (data_codewords - 1); i++) {
+ data_blocks[i] = 0;
+ for (j = 0; j < 8; j++) {
+ if (binary_data[(i * 8) + j] == '1') {
+ data_blocks[i] += 0x80 >> j;
+ }
+ }
+ }
+ data_blocks[2] = 0;
+ for (j = 0; j < 4; j++) {
+ if (binary_data[16 + j] == '1') {
+ data_blocks[2] += 0x80 >> j;
+ }
+ }
+#ifdef ZINT_TEST
+ if (symbol->debug & ZINT_DEBUG_TEST) debug_test_codeword_dump(symbol, data_blocks, data_codewords);
#else
- unsigned char* mask = (unsigned char *)_alloca((size * size) * sizeof(unsigned char));
- unsigned char* eval = (unsigned char *)_alloca((size * size) * sizeof(unsigned char));
+ (void)symbol; /* Unused */
#endif
- /* Perform data masking */
- for(x = 0; x < size; x++) {
- for(y = 0; y < size; y++) {
- mask[(y * size) + x] = 0x00;
-
- // all eight bitmask variants are encoded in the 8 bits of the bytes that make up the mask array.
- if (!(grid[(y * size) + x] & 0xf0)) { // exclude areas not to be masked.
- if(((y + x) & 1) == 0) { mask[(y * size) + x] += 0x01; }
- if((y & 1) == 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)) & 1) == 0) { mask[(y * size) + x] += 0x10; }
- if((((y * x) & 1) + ((y * x) % 3)) == 0) { mask[(y * size) + x] += 0x20; }
- if(((((y * x) & 1) + ((y * x) % 3)) & 1) == 0) { mask[(y * size) + x] += 0x40; }
- if(((((y + x) & 1) + ((y * x) % 3)) & 1) == 0) { mask[(y * size) + x] += 0x80; }
- }
- }
- }
-
- // apply data masks to grid, result in eval
- 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++) {
- add_format_info_eval(eval, size, ecc_level, 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;
-}
+ /* 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();
-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;
+ /* Add Reed-Solomon codewords to binary data */
+ for (i = 0; i < ecc_codewords; i++) {
+ bin_append(ecc_blocks[ecc_codewords - i - 1], 8, binary_data);
+ }
}
-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 >> (i * 3)) & 0x41;
- grid[((size - 10) * size) + i] += (version_data >> ((i * 3) + 1)) & 0x41;
- grid[((size - 9) * size) + i] += (version_data >> ((i * 3) + 2)) & 0x41;
- grid[(i * size) + (size - 11)] += (version_data >> (i * 3)) & 0x41;
- grid[(i * size) + (size - 10)] += (version_data >> ((i * 3) + 1)) & 0x41;
- grid[(i * size) + (size - 9)] += (version_data >> ((i * 3) + 2)) & 0x41;
- }
+static void micro_qr_m2(struct zint_symbol *symbol, char binary_data[], const int ecc_mode) {
+ int i, j, latch;
+ int bits_total=0, bits_left;
+ int data_codewords=0, ecc_codewords=0;
+ unsigned char data_blocks[6], ecc_blocks[7];
+
+ latch = 0;
+
+ if (ecc_mode == LEVEL_L) {
+ bits_total = 40;
+ }
+ else if (ecc_mode == LEVEL_M) {
+ bits_total = 32;
+ }
+ else assert(0);
+
+ /* Add terminator */
+ bits_left = bits_total - (int)strlen(binary_data);
+ if (bits_left <= 5) {
+ for (i = 0; i < bits_left; i++) {
+ strcat(binary_data, "0");
+ }
+ latch = 1;
+ } else {
+ bin_append(0, 5, binary_data);
+ }
+
+ if (latch == 0) {
+ /* Complete current byte */
+ int remainder = 8 - (strlen(binary_data) % 8);
+ if (remainder == 8) {
+ remainder = 0;
+ }
+ for (i = 0; i < remainder; i++) {
+ strcat(binary_data, "0");
+ }
+
+ /* Add padding */
+ bits_left = bits_total - (int)strlen(binary_data);
+ remainder = bits_left / 8;
+ for (i = 0; i < remainder; i++) {
+ strcat(binary_data, (i & 1) ? "00010001" : "11101100");
+ }
+ }
+
+ if (ecc_mode == LEVEL_L) {
+ data_codewords = 5;
+ ecc_codewords = 5;
+ }
+ else if (ecc_mode == LEVEL_M) {
+ data_codewords = 4;
+ ecc_codewords = 6;
+ }
+ else assert(0);
+
+ /* Copy data into codewords */
+ for (i = 0; i < data_codewords; i++) {
+ data_blocks[i] = 0;
+
+ for (j = 0; j < 8; j++) {
+ if (binary_data[(i * 8) + j] == '1') {
+ data_blocks[i] += 0x80 >> j;
+ }
+ }
+ }
+#ifdef ZINT_TEST
+ if (symbol->debug & ZINT_DEBUG_TEST) debug_test_codeword_dump(symbol, data_blocks, data_codewords);
+#else
+ (void)symbol; /* Unused */
+#endif
+
+ /* 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++) {
+ bin_append(ecc_blocks[ecc_codewords - i - 1], 8, binary_data);
+ }
+
+ return;
}
-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];
+static void micro_qr_m3(struct zint_symbol *symbol, char binary_data[], const int ecc_mode) {
+ int i, j, latch;
+ int bits_total=0, bits_left;
+ int data_codewords=0, ecc_codewords=0;
+ unsigned char data_blocks[12], ecc_blocks[9];
+
+ latch = 0;
+
+ if (ecc_mode == LEVEL_L) {
+ bits_total = 84;
+ }
+ else if (ecc_mode == LEVEL_M) {
+ bits_total = 68;
+ }
+ else assert(0);
+
+ /* Add terminator */
+ bits_left = bits_total - (int)strlen(binary_data);
+ if (bits_left <= 7) {
+ for (i = 0; i < bits_left; i++) {
+ strcat(binary_data, "0");
+ }
+ latch = 1;
+ } else {
+ bin_append(0, 7, binary_data);
+ }
+
+ if (latch == 0) {
+ /* Manage last (4-bit) block */
+ bits_left = bits_total - (int)strlen(binary_data);
+ if (bits_left <= 4) {
+ for (i = 0; i < bits_left; i++) {
+ strcat(binary_data, "0");
+ }
+ latch = 1;
+ }
+ }
+
+ if (latch == 0) {
+ /* Complete current byte */
+ int remainder = 8 - (strlen(binary_data) % 8);
+ if (remainder == 8) {
+ remainder = 0;
+ }
+ for (i = 0; i < remainder; i++) {
+ strcat(binary_data, "0");
+ }
+
+ /* Add padding */
+ bits_left = bits_total - (int)strlen(binary_data);
+ if (bits_left > 4) {
+ remainder = (bits_left - 4) / 8;
+ for (i = 0; i < remainder; i++) {
+ strcat(binary_data, (i & 1) ? "00010001" : "11101100");
+ }
+ }
+ bin_append(0, 4, binary_data);
+ }
+
+ if (ecc_mode == LEVEL_L) {
+ data_codewords = 11;
+ ecc_codewords = 6;
+ }
+ else if (ecc_mode == LEVEL_M) {
+ data_codewords = 9;
+ ecc_codewords = 8;
+ }
+ else assert(0);
+
+ /* Copy data into codewords */
+ for (i = 0; i < (data_codewords - 1); i++) {
+ data_blocks[i] = 0;
+
+ for (j = 0; j < 8; j++) {
+ if (binary_data[(i * 8) + j] == '1') {
+ data_blocks[i] += 0x80 >> j;
+ }
+ }
+ }
+
+ if (ecc_mode == LEVEL_L) {
+ data_blocks[10] = 0;
+ for (j = 0; j < 4; j++) {
+ if (binary_data[80 + j] == '1') {
+ data_blocks[10] += 0x80 >> j;
+ }
+ }
+ }
+
+ if (ecc_mode == LEVEL_M) {
+ data_blocks[8] = 0;
+ for (j = 0; j < 4; j++) {
+ if (binary_data[64 + j] == '1') {
+ data_blocks[8] += 0x80 >> j;
+ }
+ }
+ }
+#ifdef ZINT_TEST
+ if (symbol->debug & ZINT_DEBUG_TEST) debug_test_codeword_dump(symbol, data_blocks, data_codewords);
#else
- int* utfdata = (int *)_alloca((length + 1) * sizeof(int));
- int* jisdata = (int *)_alloca((length + 1) * sizeof(int));
- char* mode = (char *)_alloca(length + 1);
+ (void)symbol; /* Unused */
#endif
-
- gs1 = (symbol->input_mode == GS1_MODE);
-
- 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];
+
+ /* 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++) {
+ bin_append(ecc_blocks[ecc_codewords - i - 1], 8, binary_data);
+ }
+
+ return;
+}
+
+static void micro_qr_m4(struct zint_symbol *symbol, char binary_data[], const int ecc_mode) {
+ int i, j, latch;
+ int bits_total=0, bits_left;
+ int data_codewords=0, ecc_codewords=0;
+ unsigned char data_blocks[17], ecc_blocks[15];
+
+ latch = 0;
+
+ if (ecc_mode == LEVEL_L) {
+ bits_total = 128;
+ }
+ else if (ecc_mode == LEVEL_M) {
+ bits_total = 112;
+ }
+ else if (ecc_mode == LEVEL_Q) {
+ bits_total = 80;
+ }
+ else assert(0);
+
+ /* Add terminator */
+ bits_left = bits_total - (int)strlen(binary_data);
+ if (bits_left <= 9) {
+ for (i = 0; i < bits_left; i++) {
+ strcat(binary_data, "0");
+ }
+ latch = 1;
+ } else {
+ bin_append(0, 9, binary_data);
+ }
+
+ if (latch == 0) {
+ /* Complete current byte */
+ int remainder = 8 - (strlen(binary_data) % 8);
+ if (remainder == 8) {
+ remainder = 0;
+ }
+ for (i = 0; i < remainder; i++) {
+ strcat(binary_data, "0");
+ }
+
+ /* Add padding */
+ bits_left = bits_total - (int)strlen(binary_data);
+ remainder = bits_left / 8;
+ for (i = 0; i < remainder; i++) {
+ strcat(binary_data, (i & 1) ? "00010001" : "11101100");
+ }
+ }
+
+ if (ecc_mode == LEVEL_L) {
+ data_codewords = 16;
+ ecc_codewords = 8;
+ }
+ else if (ecc_mode == LEVEL_M) {
+ data_codewords = 14;
+ ecc_codewords = 10;
+ }
+ else if (ecc_mode == LEVEL_Q) {
+ data_codewords = 10;
+ ecc_codewords = 14;
+ }
+ else assert(0);
+
+ /* Copy data into codewords */
+ for (i = 0; i < data_codewords; i++) {
+ data_blocks[i] = 0;
+
+ for (j = 0; j < 8; j++) {
+ if (binary_data[(i * 8) + j] == '1') {
+ data_blocks[i] += 0x80 >> j;
+ }
+ }
+ }
+#ifdef ZINT_TEST
+ if (symbol->debug & ZINT_DEBUG_TEST) debug_test_codeword_dump(symbol, data_blocks, data_codewords);
#else
- int* datastream = (int *)_alloca((target_binlen + 1) * sizeof(int));
- int* fullstream = (int *)_alloca((qr_total_codewords[version - 1] + 1) * sizeof(int));
+ (void)symbol; /* Unused */
#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];
+ /* 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++) {
+ bin_append(ecc_blocks[ecc_codewords - i - 1], 8, binary_data);
+ }
+}
+
+static void micro_setup_grid(unsigned char* grid,const 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;
+}
+
+static void micro_populate_grid(unsigned char* grid,const int size,const char full_stream[]) {
+ int direction = 1; /* up */
+ int row = 0; /* right hand side */
+ size_t n, i;
+ int y;
+
+ n = strlen(full_stream);
+ y = size - 1;
+ i = 0;
+ do {
+ int 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);
+}
+
+static int micro_evaluate(const unsigned char *grid,const int size,const 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;
+}
+
+static int micro_apply_bitmask(unsigned char *grid,const int size) {
+ int x, y;
+ unsigned char p;
+ int pattern, value[8];
+ int best_val, best_pattern;
+
#ifndef _MSC_VER
- unsigned char grid[size * size];
+ unsigned char mask[size * size];
+ unsigned char eval[size * size];
#else
- unsigned char* grid = (unsigned char *)_alloca((size * size) * sizeof(unsigned char));
+ unsigned char* mask = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
+ unsigned char* eval = (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]);
-
- if(version >= 7) {
- add_version_info(grid, size, version);
- }
-
- bitmask = apply_bitmask(grid, size, ecc_level);
-
- add_format_info(grid, size, ecc_level, bitmask);
-
- 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;
+
+ /* 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 & 1) == 0) {
+ mask[(y * size) + x] += 0x01;
+ }
+
+ if ((((y / 2) + (x / 3)) & 1) == 0) {
+ mask[(y * size) + x] += 0x02;
+ }
+
+ if (((((y * x) & 1) + ((y * x) % 3)) & 1) == 0) {
+ mask[(y * size) + x] += 0x04;
+ }
+
+ if (((((y + x) & 1) + ((y * x) % 3)) & 1) == 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++) {
+ if (mask[(y * size) + x] & (0x01 << best_pattern)) {
+ if (grid[(y * size) + x] & 0x01) {
+ grid[(y * size) + x] = 0x00;
+ } else {
+ grid[(y * size) + x] = 0x01;
+ }
+ }
+ }
+ }
+
+ return best_pattern;
}
-/* 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;
- int short_data_block_length, i;
- char data_block;
- char buffer[2];
-
- strcpy(binary, "");
-
-#ifdef _DEBUG_MODE_
- for(i = 0; i < length; i++) {
- printf("%c", mode[i]);
- }
- printf("\n");
+INTERNAL int microqr(struct zint_symbol *symbol, const unsigned char source[], size_t length) {
+ size_t i, size, j;
+ char full_stream[200];
+ int full_multibyte;
+
+ unsigned int jisdata[40];
+ char mode[40];
+ int alpha_used = 0, byte_or_kanji_used = 0;
+ int version_valid[4];
+ int binary_count[4];
+ int ecc_level, autoversion, version;
+ int bitmask, format, format_full;
+#ifdef _MSC_VER
+ unsigned char* grid;
#endif
- 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);
-#ifdef _DEBUG_MODE_
- printf("Kanji block (length %d)\n\t", short_data_block_length);
-#endif
-
- /* 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;
-
- qr_bscan(binary, prod, 0x1000);
-#ifdef _DEBUG_MODE_
- printf("0x%4X ", prod);
-#endif
- if(strlen(binary) > 128) {
- return ERROR_TOO_LONG;
- }
- }
-#ifdef _DEBUG_MODE_
- printf("\n");
-#endif
-
- 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);
-#ifdef _DEBUG_MODE_
- printf("Byte block (length %d)\n\t", short_data_block_length);
-#endif
-
- /* Character representation */
- for(i = 0; i < short_data_block_length; i++) {
- int byte = jisdata[position + i];
-
- qr_bscan(binary, byte, 0x80);
-#ifdef _DEBUG_MODE_
- printf("0x%4X ", byte);
-#endif
- if(strlen(binary) > 128) {
- return ERROR_TOO_LONG;
- }
- }
-#ifdef _DEBUG_MODE_
- printf("\n");
-#endif
- 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);
-#ifdef _DEBUG_MODE_
- printf("Alpha block (length %d)\n\t", short_data_block_length);
+ if (length > 35) {
+ strcpy(symbol->errtxt, "562: Input data too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ /* Check option 1 in combination with option 2 */
+ ecc_level = LEVEL_L;
+ if (symbol->option_1 >= 1 && symbol->option_1 <= 4) {
+ if (symbol->option_1 == 4) {
+ strcpy(symbol->errtxt, "566: Error correction level H not available");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+ if (symbol->option_2 >= 1 && symbol->option_2 <= 4) {
+ if (symbol->option_2 == 1 && symbol->option_1 != 1) {
+ strcpy(symbol->errtxt, "574: Version M1 supports error correction level L only");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+ if (symbol->option_2 != 4 && symbol->option_1 == 3) {
+ strcpy(symbol->errtxt, "575: Error correction level Q requires Version M4");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+ }
+ ecc_level = symbol->option_1;
+ }
+
+ full_multibyte = symbol->option_3 == ZINT_FULL_MULTIBYTE; /* If set use Kanji mode in DATA_MODE or for single-byte Latin */
+
+ if ((symbol->input_mode & 0x07) == DATA_MODE) {
+ sjis_cpy(source, &length, jisdata, full_multibyte);
+ } else {
+ /* Try ISO 8859-1 conversion first */
+ int error_number = sjis_utf8tosb(3, source, &length, jisdata, full_multibyte);
+ if (error_number != 0) {
+ /* Try Shift-JIS */
+ error_number = sjis_utf8tomb(symbol, source, &length, jisdata);
+ if (error_number != 0) {
+ return error_number;
+ }
+ }
+ }
+
+ /* Determine if alpha (excluding numerics), byte or kanji used */
+ for (i = 0; i < length && (alpha_used == 0 || byte_or_kanji_used == 0); i++) {
+ if (jisdata[i] < '0' || jisdata[i] > '9') {
+ if (is_alpha(jisdata[i], 0 /*gs1*/)) {
+ alpha_used = 1;
+ } else {
+ byte_or_kanji_used = 1;
+ }
+ }
+ }
+
+ for (i = 0; i < 4; i++) {
+ version_valid[i] = 1;
+ }
+
+ /* Eliminate possible versions depending on type of content */
+ if (byte_or_kanji_used) {
+ version_valid[0] = 0;
+ version_valid[1] = 0;
+ } else if (alpha_used) {
+ version_valid[0] = 0;
+ }
+
+ /* Eliminate possible versions depending on error correction level specified */
+ if (ecc_level == LEVEL_Q) {
+ version_valid[0] = 0;
+ version_valid[1] = 0;
+ version_valid[2] = 0;
+ } else if (ecc_level == LEVEL_M) {
+ version_valid[0] = 0;
+ }
+
+ /* Determine length of binary data */
+ for (i = 0; i < 4; i++) {
+ if (version_valid[i]) {
+ binary_count[i] = getBinaryLength(MICROQR_VERSION + i, mode, jisdata, length, 0 /*gs1*/, 0 /*eci*/, symbol->debug);
+ } else {
+ binary_count[i] = 128 + 1;
+ }
+ }
+
+ /* 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, "565: Input data too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ /* Eliminate possible versions depending on binary length and error correction level specified */
+ if (ecc_level == LEVEL_Q) {
+ if (binary_count[3] > 80) {
+ strcpy(symbol->errtxt, "567: Input data too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ } else if (ecc_level == LEVEL_M) {
+ 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, "568: Input data too long");
+ return ZINT_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 - 1 >= autoversion) {
+ version = symbol->option_2 - 1;
+ } else {
+ strcpy(symbol->errtxt, "570: Input too long for selected symbol size");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ }
+
+ /* If there is enough unused space then increase the error correction level, unless user-specified */
+ if (symbol->option_1 == -1 || symbol->option_1 != ecc_level) {
+ if (version == 3) {
+ if (binary_count[3] <= 112) {
+ ecc_level = LEVEL_M;
+ }
+ if (binary_count[3] <= 80) {
+ ecc_level = LEVEL_Q;
+ }
+ } else if (version == 2) {
+ if (binary_count[2] <= 68) {
+ ecc_level = LEVEL_M;
+ }
+ } else if (version == 1) {
+ if (binary_count[1] <= 32) {
+ ecc_level = LEVEL_M;
+ }
+ }
+ }
+
+ qr_define_mode(mode, jisdata, length, 0 /*gs1*/, MICROQR_VERSION + version, symbol->debug);
+
+ qr_binary((unsigned char*)full_stream, MICROQR_VERSION + version, 0 /*target_codewords*/, mode, jisdata, length, 0 /*gs1*/, 0 /*eci*/, binary_count[version], symbol->debug);
+
+ switch (version) {
+ case 0: micro_qr_m1(symbol, full_stream);
+ break;
+ case 1: micro_qr_m2(symbol, full_stream, ecc_level);
+ break;
+ case 2: micro_qr_m3(symbol, full_stream, ecc_level);
+ break;
+ case 3: micro_qr_m4(symbol, full_stream, ecc_level);
+ break;
+ }
+
+ size = micro_qr_sizes[version];
+#ifndef _MSC_VER
+ unsigned char grid[size * size];
+#else
+ grid = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
#endif
- /* 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;
- }
-
- qr_bscan(binary, prod, 1 << (5 * count)); /* count = 1..2 */
-#ifdef _DEBUG_MODE_
- printf("0x%4X ", prod);
+
+ 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;
+}
+
+/* For UPNQR the symbol size and error correction capacity is fixed */
+INTERNAL int upnqr(struct zint_symbol *symbol, const unsigned char source[], size_t length) {
+ int i, j, est_binlen;
+ int ecc_level, version, target_codewords, blocks, size;
+ int bitmask, error_number;
+
+#ifndef _MSC_VER
+ unsigned int jisdata[length + 1];
+ char mode[length + 1];
+#else
+ unsigned char* datastream;
+ unsigned char* fullstream;
+ unsigned char* grid;
+ unsigned int* jisdata = (unsigned int *) _alloca((length + 1) * sizeof (unsigned int));
+ char* mode = (char *) _alloca(length + 1);
#endif
- if(strlen(binary) > 128) {
- return ERROR_TOO_LONG;
- }
-
- i += 2;
- };
-#ifdef _DEBUG_MODE_
- printf("\n");
+
+#ifndef _MSC_VER
+ unsigned char preprocessed[length + 1];
+#else
+ unsigned char* preprocessed = (unsigned char*) _alloca(length + 1);
#endif
- 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);
-#ifdef _DEBUG_MODE_
- printf("Number block (length %d)\n\t", short_data_block_length);
+
+ symbol->eci = 4; /* Set before any processing */
+
+ switch (symbol->input_mode & 0x07) {
+ case DATA_MODE:
+ /* Input is already in ISO-8859-2 format */
+ for (i = 0; i < (int) length; i++) {
+ jisdata[i] = source[i];
+ mode[i] = 'B';
+ }
+ break;
+ case GS1_MODE:
+ strcpy(symbol->errtxt, "571: UPNQR does not support GS-1 encoding");
+ return ZINT_ERROR_INVALID_OPTION;
+ break;
+ case UNICODE_MODE:
+ error_number = utf_to_eci(4, source, preprocessed, &length);
+ if (error_number != 0) {
+ strcpy(symbol->errtxt, "572: Invalid characters in input data");
+ return error_number;
+ }
+ for (i = 0; i < (int) length; i++) {
+ jisdata[i] = preprocessed[i];
+ mode[i] = 'B';
+ }
+ break;
+ }
+
+ est_binlen = getBinaryLength(15, mode, jisdata, length, 0, symbol->eci, symbol->debug);
+
+ ecc_level = LEVEL_M;
+
+ if (est_binlen > 3320) {
+ strcpy(symbol->errtxt, "573: Input too long for selected symbol");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ version = 15; // 77 x 77
+
+ target_codewords = qr_data_codewords_M[version - 1];
+ blocks = qr_blocks_M[version - 1];
+#ifndef _MSC_VER
+ unsigned char datastream[target_codewords + 1];
+ unsigned char fullstream[qr_total_codewords[version - 1] + 1];
+#else
+ datastream = (unsigned char *) _alloca(target_codewords + 1);
+ fullstream = (unsigned char *) _alloca(qr_total_codewords[version - 1] + 1);
#endif
- /* 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;
- }
-
- qr_bscan(binary, prod, 1 << (3 * count)); /* count = 1..3 */
-#ifdef _DEBUG_MODE_
- printf("0x%4X (%d)", prod, prod);
+
+ qr_binary(datastream, version, target_codewords, mode, jisdata, length, 0, symbol->eci, est_binlen, symbol->debug);
+#ifdef ZINT_TEST
+ if (symbol->debug & ZINT_DEBUG_TEST) debug_test_codeword_dump(symbol, datastream, target_codewords);
#endif
- if(strlen(binary) > 128) {
- return ERROR_TOO_LONG;
- }
-
- i += 3;
- };
-#ifdef _DEBUG_MODE_
- printf("\n");
+ add_ecc(fullstream, datastream, version, target_codewords, blocks, symbol->debug);
+
+ size = qr_sizes[version - 1];
+#ifndef _MSC_VER
+ unsigned char grid[size * size];
+#else
+ grid = (unsigned char *) _alloca((size * size) * sizeof (unsigned char));
#endif
- 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);
-}
+ for (i = 0; i < size; i++) {
+ for (j = 0; j < size; j++) {
+ grid[(i * size) + j] = 0;
+ }
+ }
-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 */
- qr_bscan(full_stream, binary_stream[i + 1], 4 << version); /* version = 0..3 */
-
- 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 */
- qr_bscan(full_stream, binary_stream[i + 1], 2 << version); /* version = 1..3 */
-
- 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 */
- qr_bscan(full_stream, binary_stream[i + 1], 2 << version); /* version = 2..3 */
-
- 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 */
- qr_bscan(full_stream, binary_stream[i + 1], 1 << version); /* version = 2..3 */
-
- i += 2;
- break;
- }
-
- } while (i < length);
-}
+ setup_grid(grid, size, version);
+ populate_grid(grid, size, size, fullstream, qr_total_codewords[version - 1]);
-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++) {
- concat(binary_data, i & 1 ? "00010001" : "11101100");
- }
- }
- 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++) {
- qr_bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
- }
-}
+ add_version_info(grid, size, version);
-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++) {
- concat(binary_data, i & 1 ? "00010001" : "11101100");
- }
- }
-
- 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++) {
- qr_bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
- }
-
- return;
-}
+ bitmask = apply_bitmask(grid, size, ecc_level);
-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++) {
- concat(binary_data, i & 1 ? "00010001" : "11101100");
- }
- }
- 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++) {
- qr_bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
- }
-
- return;
-}
+ add_format_info(grid, size, ecc_level, bitmask);
-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++) {
- concat(binary_data, i & 1 ? "00010001" : "11101100");
- }
- }
-
- 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++) {
- qr_bscan(binary_data, ecc_blocks[ecc_codewords - i - 1], 0x80);
- }
-}
+ symbol->width = size;
+ symbol->rows = size;
-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;
-}
+ 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;
+ }
-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);
+ return 0;
}
-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;
+static void setup_rmqr_grid(unsigned char* grid, const int h_size, const int v_size) {
+ int i, j;
+ char alignment[] = {0x1F, 0x11, 0x15, 0x11, 0x1F};
+ int h_version, finder_position;
+
+ /* Add timing patterns - top and bottom */
+ for (i = 0; i < h_size; i++) {
+ if (i % 2) {
+ grid[i] = 0x20;
+ grid[((v_size - 1) * h_size) + i] = 0x20;
+ } else {
+ grid[i] = 0x21;
+ grid[((v_size - 1) * h_size) + i] = 0x21;
+ }
+ }
+
+ /* Add timing patterns - left and right */
+ for (i = 0; i < v_size; i++) {
+ if (i % 2) {
+ grid[i * h_size] = 0x20;
+ grid[(i * h_size) + (h_size - 1)] = 0x20;
+ } else {
+ grid[i * h_size] = 0x21;
+ grid[(i * h_size) + (h_size - 1)] = 0x21;
+ }
+ }
+
+ /* Add finder pattern */
+ place_finder(grid, h_size, 0, 0); // This works because finder is always top left
+
+ /* Add finder sub-pattern to bottom right */
+ for (i = 0; i < 5; i++) {
+ for (j = 0; j < 5; j++) {
+ if (alignment[j] & 0x10 >> i) {
+ grid[((v_size - 5) * h_size) + (h_size * i) + (h_size - 5) + j] = 0x11;
+ } else {
+ grid[((v_size - 5) * h_size) + (h_size * i) + (h_size - 5) + j] = 0x10;
+ }
+ }
+ }
+
+ /* Add corner finder pattern - bottom left */
+ grid[(v_size - 2) * h_size] = 0x11;
+ grid[((v_size - 2) * h_size) + 1] = 0x10;
+ grid[((v_size - 1) * h_size) + 1] = 0x11;
+
+ /* Add corner finder pattern - top right */
+ grid[h_size - 2] = 0x11;
+ grid[(h_size * 2) - 2] = 0x10;
+ grid[(h_size * 2) - 1] = 0x11;
+
+ /* Add seperator */
+ for (i = 0; i < 7; i++) {
+ grid[(i * h_size) + 7] = 0x20;
+ }
+ if (v_size > 7) {
+ // Note for v_size = 9 this overrides the bottom right corner finder pattern
+ for(i = 0; i < 8; i++) {
+ grid[(7 * h_size) + i] = 0x20;
+ }
+ }
+
+ /* Add alignment patterns */
+ if (h_size > 27) {
+ for(i = 0; i < 5; i++) {
+ if (h_size == rmqr_width[i]) {
+ h_version = i;
+ }
+ }
+
+ for(i = 0; i < 4; i++) {
+ finder_position = rmqr_table_d1[(h_version * 4) + i];
+
+ if (finder_position != 0) {
+ for (j = 0; j < v_size; j++) {
+ if (j % 2) {
+ grid[(j * h_size) + finder_position] = 0x10;
+ } else {
+ grid[(j * h_size) + finder_position] = 0x11;
+ }
+ }
+
+ // Top square
+ grid[h_size + finder_position - 1] = 0x11;
+ grid[(h_size * 2) + finder_position - 1] = 0x11;
+ grid[h_size + finder_position + 1] = 0x11;
+ grid[(h_size * 2) + finder_position + 1] = 0x11;
+
+ // Bottom square
+ grid[(h_size * (v_size - 3)) + finder_position - 1] = 0x11;
+ grid[(h_size * (v_size - 2)) + finder_position - 1] = 0x11;
+ grid[(h_size * (v_size - 3)) + finder_position + 1] = 0x11;
+ grid[(h_size * (v_size - 2)) + finder_position + 1] = 0x11;
+ }
+ }
+ }
+
+ /* Reserve space for format information */
+ for (i = 0; i < 5; i++) {
+ for (j = 0; j < 3; j++) {
+ grid[(h_size * (i + 1)) + j + 8] = 0x20;
+ grid[(h_size * (v_size - 6)) + (h_size * i) + j + (h_size - 8)] = 0x20;
+ }
+ }
+ grid[(h_size * 1) + 11] = 0x20;
+ grid[(h_size * 2) + 11] = 0x20;
+ grid[(h_size * 3) + 11] = 0x20;
+ grid[(h_size * (v_size - 6)) + (h_size - 5)] = 0x20;
+ grid[(h_size * (v_size - 6)) + (h_size - 4)] = 0x20;
+ grid[(h_size * (v_size - 6)) + (h_size - 3)] = 0x20;
}
-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;
-
+/* rMQR according to 2018 draft standard */
+INTERNAL int rmqr(struct zint_symbol *symbol, const unsigned char source[], size_t length) {
+ int i, j, est_binlen;
+ int ecc_level, autosize, version, max_cw, target_codewords, blocks, h_size, v_size;
+ int gs1;
+ int full_multibyte;
+ int footprint, best_footprint, format_data;
+ unsigned int left_format_info, right_format_info;
+
#ifndef _MSC_VER
- unsigned char mask[size * size];
- unsigned char eval[size * size];
+ unsigned int jisdata[length + 1];
+ char mode[length + 1];
#else
- unsigned char* mask = (unsigned char *)_alloca((size * size) * sizeof(unsigned char));
- unsigned char* eval = (unsigned char *)_alloca((size * size) * sizeof(unsigned char));
+ unsigned char* datastream;
+ unsigned char* fullstream;
+ unsigned char* grid;
+ unsigned int* jisdata = (unsigned int *) _alloca((length + 1) * sizeof (unsigned int));
+ char* mode = (char *) _alloca(length + 1);
#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 & 1) == 0) {
- mask[(y * size) + x] += 0x01;
- }
-
- if((((y / 2) + (x / 3)) & 1) == 0) {
- mask[(y * size) + x] += 0x02;
- }
-
- if(((((y * x) & 1) + ((y * x) % 3)) & 1) == 0) {
- mask[(y * size) + x] += 0x04;
- }
-
- if(((((y + x) & 1) + ((y * x) % 3)) & 1) == 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;
-}
+ gs1 = ((symbol->input_mode & 0x07) == GS1_MODE);
+ full_multibyte = symbol->option_3 == ZINT_FULL_MULTIBYTE; /* If set use Kanji mode in DATA_MODE or for single-byte Latin */
+
+ if ((symbol->input_mode & 0x07) == DATA_MODE) {
+ sjis_cpy(source, &length, jisdata, full_multibyte);
+ } else {
+ /* Try ISO 8859-1 conversion first */
+ int error_number = sjis_utf8tosb(3, source, &length, jisdata, full_multibyte);
+ if (error_number != 0) {
+ /* Try Shift-JIS */
+ error_number = sjis_utf8tomb(symbol, source, &length, jisdata);
+ if (error_number != 0) {
+ return error_number;
+ }
+ }
+ }
+
+ est_binlen = getBinaryLength(RMQR_VERSION + 31, mode, jisdata, length, gs1, 0 /*eci*/, symbol->debug);
+
+ ecc_level = LEVEL_M;
+ max_cw = 152;
+ if (symbol->option_1 == 1) {
+ strcpy(symbol->errtxt, "576: Error correction level L not available in rMQR");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ if (symbol->option_1 == 3) {
+ strcpy(symbol->errtxt, "577: Error correction level Q not available in rMQR");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ if (symbol->option_1 == 4) {
+ ecc_level = LEVEL_H;
+ max_cw = 76;
+ }
+
+ if (est_binlen > (8 * max_cw)) {
+ strcpy(symbol->errtxt, "578: Input too long for selected error correction level");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ if ((symbol->option_2 < 0) || (symbol->option_2 > 38)) {
+ strcpy(symbol->errtxt, "579: Invalid rMQR symbol size");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+ version = 31; // Set default to keep compiler happy
+
+ if (symbol->option_2 == 0) {
+ // Automatic symbol size
+ autosize = 31;
+ best_footprint = rmqr_height[31] * rmqr_width[31];
+ for (version = 30; version >= 0; version--) {
+ est_binlen = getBinaryLength(RMQR_VERSION + version, mode, jisdata, length, gs1, 0 /*eci*/, symbol->debug);
+ footprint = rmqr_height[version] * rmqr_width[version];
+ if (ecc_level == LEVEL_M) {
+ if (8 * rmqr_data_codewords_M[version] >= est_binlen) {
+ if (footprint < best_footprint) {
+ autosize = version;
+ best_footprint = footprint;
+ }
+ }
+ } else {
+ if (8 * rmqr_data_codewords_H[version] >= est_binlen) {
+ if (footprint < best_footprint) {
+ autosize = version;
+ best_footprint = footprint;
+ }
+ }
+ }
+ }
+ version = autosize;
+ est_binlen = getBinaryLength(RMQR_VERSION + version, mode, jisdata, length, gs1, 0 /*eci*/, symbol->debug);
+ }
+
+ if ((symbol->option_2 >= 1) && (symbol->option_2 <= 32)) {
+ // User specified symbol size
+ version = symbol->option_2 - 1;
+ est_binlen = getBinaryLength(RMQR_VERSION + version, mode, jisdata, length, gs1, 0 /*eci*/, symbol->debug);
+ }
+
+ if (symbol->option_2 >= 33) {
+ // User has specified symbol height only
+ version = rmqr_fixed_height_upper_bound[symbol->option_2 - 32];
+ for(i = version - 1; i > rmqr_fixed_height_upper_bound[symbol->option_2 - 33]; i--) {
+ est_binlen = getBinaryLength(RMQR_VERSION + i, mode, jisdata, length, gs1, 0 /*eci*/, symbol->debug);
+ if (ecc_level == LEVEL_M) {
+ if (8 * rmqr_data_codewords_M[i] >= est_binlen) {
+ version = i;
+ }
+ } else {
+ if (8 * rmqr_data_codewords_H[i] >= est_binlen) {
+ version = i;
+ }
+ }
+ }
+ est_binlen = getBinaryLength(RMQR_VERSION + version, mode, jisdata, length, gs1, 0 /*eci*/, symbol->debug);
+ }
+
+ if (symbol->option_1 == -1) {
+ // Detect if there is enough free space to increase ECC level
+ if (est_binlen < (rmqr_data_codewords_H[version] * 8)) {
+ ecc_level = LEVEL_H;
+ }
+ }
+
+ if (ecc_level == LEVEL_M) {
+ target_codewords = rmqr_data_codewords_M[version];
+ blocks = rmqr_blocks_M[version];
+ } else {
+ target_codewords = rmqr_data_codewords_H[version];
+ blocks = rmqr_blocks_H[version];
+ }
+
+ if (est_binlen > (target_codewords * 8)) {
+ // User has selected a symbol too small for the data
+ strcpy(symbol->errtxt, "580: Input too long for selected symbol size");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Minimum codewords = %d\n", est_binlen / 8);
+ printf("Selected version: %d = R%dx%d-", (version + 1), rmqr_height[version], rmqr_width[version]);
+ if (ecc_level == LEVEL_M) {
+ printf("M\n");
+ } else {
+ printf("H\n");
+ }
+ printf("Number of data codewords in symbol = %d\n", target_codewords);
+ printf("Number of ECC blocks = %d\n", blocks);
+ }
-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 - 1) >= autoversion) {
- version = symbol->option_2 - 1;
- }
- }
-
- /* 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];
+ unsigned char datastream[target_codewords + 1];
+ unsigned char fullstream[rmqr_total_codewords[version] + 1];
#else
- unsigned char* grid = (unsigned char *)_alloca((size * size) * sizeof(unsigned char));
+ datastream = (unsigned char *) _alloca((target_codewords + 1) * sizeof (unsigned char));
+ fullstream = (unsigned char *) _alloca((rmqr_total_codewords[version] + 1) * sizeof (unsigned char));
+#endif
+
+ qr_binary(datastream, RMQR_VERSION + version, target_codewords, mode, jisdata, length, gs1, 0 /*eci*/, est_binlen, symbol->debug);
+#ifdef ZINT_TEST
+ if (symbol->debug & ZINT_DEBUG_TEST) debug_test_codeword_dump(symbol, datastream, target_codewords);
#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;
+ add_ecc(fullstream, datastream, RMQR_VERSION + version, target_codewords, blocks, symbol->debug);
+
+ h_size = rmqr_width[version];
+ v_size = rmqr_height[version];
+
+#ifndef _MSC_VER
+ unsigned char grid[h_size * v_size];
+#else
+ grid = (unsigned char *) _alloca((h_size * v_size) * sizeof (unsigned char));
+#endif
+
+ for (i = 0; i < v_size; i++) {
+ for (j = 0; j < h_size; j++) {
+ grid[(i * h_size) + j] = 0;
+ }
+ }
+
+ setup_rmqr_grid(grid, h_size, v_size);
+ populate_grid(grid, h_size, v_size, fullstream, rmqr_total_codewords[version]);
+
+ /* apply bitmask */
+ for (i = 0; i < v_size; i++) {
+ for (j = 0; j < h_size; j++) {
+ if ((grid[(i * h_size) + j] & 0xf0) == 0) {
+ // This is a data module
+ if (((i / 2) + (j / 3)) % 2 == 0) { // < This is the data mask from section 7.8.2
+ // This module needs to be changed
+ if (grid[(i * h_size) + j] == 0x01) {
+ grid[(i * h_size) + j] = 0x00;
+ } else {
+ grid[(i * h_size) + j] = 0x01;
+ }
+ }
+ }
+ }
+ }
+
+ /* add format information */
+ format_data = version;
+ if (ecc_level == LEVEL_H) {
+ format_data += 32;
+ }
+ left_format_info = rmqr_format_info_left[format_data];
+ right_format_info = rmqr_format_info_right[format_data];
+
+ for (i = 0; i < 5; i++) {
+ for (j = 0; j < 3; j++) {
+ grid[(h_size * (i + 1)) + j + 8] = (left_format_info >> ((j * 5) + i)) & 0x01;
+ grid[(h_size * (v_size - 6)) + (h_size * i) + j + (h_size - 8)] = (right_format_info >> ((j * 5) + i)) & 0x01;
+ }
+ }
+ grid[(h_size * 1) + 11] = (left_format_info >> 15) & 0x01;
+ grid[(h_size * 2) + 11] = (left_format_info >> 16) & 0x01;
+ grid[(h_size * 3) + 11] = (left_format_info >> 17) & 0x01;
+ grid[(h_size * (v_size - 6)) + (h_size - 5)] = (right_format_info >> 15) & 0x01;
+ grid[(h_size * (v_size - 6)) + (h_size - 4)] = (right_format_info >> 16) & 0x01;
+ grid[(h_size * (v_size - 6)) + (h_size - 3)] = (right_format_info >> 17) & 0x01;
+
+
+ symbol->width = h_size;
+ symbol->rows = v_size;
+
+ for (i = 0; i < v_size; i++) {
+ for (j = 0; j < h_size; j++) {
+ if (grid[(i * h_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
index 0efb263..b19ded6 100644
--- a/backend/qr.h
+++ b/backend/qr.h
@@ -1,8 +1,7 @@
-/* qr.h Data for QR Code */
+/* qr.h Data for QR Code, Micro QR Code and rMQR
-/*
libzint - the open source barcode library
- Copyright (C) 2008 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2008-2019 Robin Stuart <rstuart114@gmail.com>
Copyright (C) 2006 Kentaro Fukuchi <fukuchi@megaui.net>
Redistribution and use in source and binary forms, with or without
@@ -29,139 +28,278 @@
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.
-*/
+ */
-#define LEVEL_L 1
-#define LEVEL_M 2
-#define LEVEL_Q 3
-#define LEVEL_H 4
+#define LEVEL_L 1
+#define LEVEL_M 2
+#define LEVEL_Q 3
+#define LEVEL_H 4
#define RHODIUM "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"
+#define RMQR_VERSION 100
+#define MICROQR_VERSION 200
+
/* 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 const unsigned short 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 const unsigned short 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 const unsigned short 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 const unsigned short 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 const unsigned short 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 const unsigned short int rmqr_height[] = {
+ 7, 7, 7, 7, 7,
+ 9, 9, 9, 9, 9,
+ 11, 11, 11, 11, 11, 11,
+ 13, 13, 13, 13, 13, 13,
+ 15, 15, 15, 15, 15,
+ 17, 17, 17, 17, 17
+};
+
+static const unsigned short int rmqr_width[] = {
+ 43, 59, 77, 99, 139,
+ 43, 59, 77, 99, 139,
+ 27, 43, 59, 77, 99, 139,
+ 27, 43, 59, 77, 99, 139,
+ 43, 59, 77, 99, 139,
+ 43, 59, 77, 99, 139
+};
+
+static const unsigned short int rmqr_data_codewords_M[] = {
+ 6, 12, 20, 28, 44, // R7x
+ 12, 21, 31, 42, 63, // R9x
+ 7, 19, 31, 43, 57, 84, // R11x
+ 12, 27, 38, 53, 73, 106, // R13x
+ 33, 48, 67, 88, 127, // R15x
+ 39, 56, 78, 100, 152 // R17x
+};
+
+static const unsigned short int rmqr_data_codewords_H[] = {
+ 3, 7, 10, 14, 24, // R7x
+ 7, 11, 17, 22, 33, // R9x
+ 5, 11, 15, 23, 29, 42, // R11x
+ 7, 13, 20, 29, 35, 54, // R13x
+ 15, 26, 31, 48, 69, // R15x
+ 21, 28, 38, 56, 76 // R17x
+};
+
+static const short int rmqr_fixed_height_upper_bound[] = {
+ -1, 4, 9, 15, 21, 26, 31
+};
+
+static const unsigned short int rmqr_total_codewords[] = {
+ 13, 21, 32, 44, 68, // R7x
+ 21, 33, 49, 66, 99, // R9x
+ 15, 31, 47, 67, 89, 132, // R11x
+ 21, 41, 60, 85, 113, 166, // R13x
+ 51, 74, 103, 136, 199, // R15x
+ 61, 88, 122, 160, 232 // R17x
+};
+
+
+static const unsigned short int rmqr_numeric_cci[] = {
+ 4, 5, 6, 7, 7,
+ 5, 6, 7, 7, 8,
+ 5, 6, 7, 7, 8, 8,
+ 5, 7, 7, 8, 8, 8,
+ 7, 7, 8, 8, 9,
+ 7, 8, 8, 8, 9
+};
+
+static const unsigned short int rmqr_alphanum_cci[] = {
+ 4, 5, 5, 6, 6,
+ 5, 5, 6, 6, 7,
+ 4, 5, 6, 6, 7, 7,
+ 5, 6, 6, 7, 7, 8,
+ 6, 7, 7, 7, 8,
+ 6, 7, 7, 8, 8
+};
+
+static const unsigned short int rmqr_byte_cci[] = {
+ 3, 4, 5, 5, 6,
+ 4, 5, 5, 6, 6,
+ 3, 5, 5, 6, 6, 7,
+ 4, 5, 6, 6, 7, 7,
+ 6, 6, 7, 7, 7,
+ 6, 6, 7, 7, 8
};
-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 const unsigned short int rmqr_kanji_cci[] = {
+ 2, 3, 4, 5, 5,
+ 3, 4, 5, 5, 6,
+ 2, 4, 5, 5, 6, 6,
+ 3, 5, 5, 6, 6, 7,
+ 5, 5, 6, 6, 7,
+ 5, 6, 6, 6, 7
};
-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 const char 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_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 const char 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 const char 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 const char 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 const char rmqr_blocks_M[] = {
+ 1, 1, 1, 1, 1, // R7x
+ 1, 1, 1, 1, 2, // R9x
+ 1, 1, 1, 1, 2, 2, // R11x
+ 1, 1, 1, 2, 2, 3, // R13x
+ 1, 1, 2, 2, 3, // R15x
+ 1, 2, 2, 3, 4 // R17x
+};
+
+static const char rmqr_blocks_H[] = {
+ 1, 1, 1, 1, 2, // R7x
+ 1, 1, 2, 2, 3, // R9x
+ 1, 1, 2, 2, 2, 3, // R11x
+ 1, 1, 2, 2, 3, 4, // R13x
+ 2, 2, 3, 4, 5, // R15x
+ 2, 2, 3, 4, 6 // R17x
+};
+
+static const unsigned short 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 const char micro_qr_sizes[] = {
+ 11, 13, 15, 17
+};
+
+static const char 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
+};
+
+// Table E1 - Row/column coordinates of center module of alignment patterns
+static const unsigned short 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
+};
+
+// Table D1 - Column coordinates of centre module of alignment patterns
+static const unsigned short int rmqr_table_d1[] = {
+ 21, 0, 0, 0,
+ 19, 39, 0, 0,
+ 25, 51, 0, 0,
+ 23, 49, 75, 0,
+ 27, 55, 83, 111
+};
+
+static const 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 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
+static const unsigned 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 const unsigned 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
+};
+
+static const unsigned int rmqr_format_info_left[] = {
+ /* rMQR format information for finder pattern side */
+ 0x1FAB2, 0x1E597, 0x1DBDD, 0x1C4F8, 0x1B86C, 0x1A749, 0x19903, 0x18626, 0x17F0E, 0x1602B,
+ 0x15E61, 0x14144, 0x13DD0, 0x122F5, 0x11CBF, 0x1039A, 0x0F1CA, 0x0EEEF, 0x0D0A5, 0x0CF80,
+ 0x0B314, 0x0AC31, 0x0927B, 0x08D5E, 0x07476, 0x06B53, 0x05519, 0x04A3C, 0x036A8, 0x0298D,
+ 0x017C7, 0x008E2, 0x3F367, 0x3EC42, 0x3D208, 0x3CD2D, 0x3B1B9, 0x3AE9C, 0x390D6, 0x38FF3,
+ 0x376DB, 0x369FE, 0x357B4, 0x34891, 0x33405, 0x32B20, 0x3156A, 0x30A4F, 0x2F81F, 0x2E73A,
+ 0x2D970, 0x2C655, 0x2BAC1, 0x2A5E4, 0x29BAE, 0x2848B, 0x27DA3, 0x26286, 0x25CCC, 0x243E9,
+ 0x23F7D, 0x22058, 0x21E12, 0x20137
+};
+
+static const unsigned int rmqr_format_info_right[] = {
+ /* rMQR format information for subfinder pattern side */
+ 0x20A7B, 0x2155E, 0x22B14, 0x23431, 0x248A5, 0x25780, 0x269CA, 0x276EF, 0x28FC7, 0x290E2,
+ 0x2AEA8, 0x2B18D, 0x2CD19, 0x2D23C, 0x2EC76, 0x2F353, 0x30103, 0x31E26, 0x3206C, 0x33F49,
+ 0x343DD, 0x35CF8, 0x362B2, 0x37D97, 0x384BF, 0x39B9A, 0x3A5D0, 0x3BAF5, 0x3C661, 0x3D944,
+ 0x3E70E, 0x3F82B, 0x003AE, 0x01C8B, 0x022C1, 0x03DE4, 0x04170, 0x05E55, 0x0601F, 0x07F3A,
+ 0x08612, 0x09937, 0x0A77D, 0x0B858, 0x0C4CC, 0x0DBE9, 0x0E5A3, 0x0FA86, 0x108D6, 0x117F3,
+ 0x129B9, 0x1369C, 0x14A08, 0x1552D, 0x16B67, 0x17442, 0x18D6A, 0x1924F, 0x1AC05, 0x1B320,
+ 0x1CFB4, 0x1D091, 0x1EEDB, 0x1F1FE
+};
diff --git a/backend/raster.c b/backend/raster.c
new file mode 100644
index 0000000..434ab8f
--- /dev/null
+++ b/backend/raster.c
@@ -0,0 +1,1170 @@
+/* raster.c - Handles output to raster files */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <stdio.h>
+#ifdef _MSC_VER
+#include <fcntl.h>
+#include <io.h>
+#endif
+#include <string.h>
+#include "common.h"
+#include "output.h"
+
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif /* _MSC_VER */
+
+#include "font.h" /* Font for human readable text */
+
+#define SSET "0123456789ABCDEF"
+
+#define DEFAULT_INK '1'
+#define DEFAULT_PAPER '0'
+
+#ifndef NO_PNG
+INTERNAL int png_pixel_plot(struct zint_symbol *symbol, char *pixelbuf);
+#endif /* NO_PNG */
+INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, char *pixelbuf);
+INTERNAL int pcx_pixel_plot(struct zint_symbol *symbol, char *pixelbuf);
+INTERNAL int gif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf);
+INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf);
+
+static const char ultra_colour[] = "WCBMRYGK";
+
+static int buffer_plot(struct zint_symbol *symbol, char *pixelbuf) {
+ /* Place pixelbuffer into symbol */
+ int fgred, fggrn, fgblu, bgred, bggrn, bgblu;
+ int row, column, i;
+
+ if (symbol->bitmap != NULL) {
+ free(symbol->bitmap);
+ symbol->bitmap = NULL;
+ }
+ symbol->bitmap = (unsigned char *) malloc(symbol->bitmap_width * symbol->bitmap_height * 3);
+ if (symbol->bitmap == NULL) {
+ strcpy(symbol->errtxt, "661: Insufficient memory for bitmap buffer");
+ return ZINT_ERROR_MEMORY;
+ }
+
+ fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]);
+ fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]);
+ fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]);
+ bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]);
+ bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
+ bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);
+
+ for (row = 0; row < symbol->bitmap_height; row++) {
+ for (column = 0; column < symbol->bitmap_width; column++) {
+ i = ((row * symbol->bitmap_width) + column) * 3;
+ switch (*(pixelbuf + (symbol->bitmap_width * row) + column)) {
+ case 'W': // White
+ symbol->bitmap[i] = 255;
+ symbol->bitmap[i + 1] = 255;
+ symbol->bitmap[i + 2] = 255;
+ break;
+ case 'C': // Cyan
+ symbol->bitmap[i] = 0;
+ symbol->bitmap[i + 1] = 255;
+ symbol->bitmap[i + 2] = 255;
+ break;
+ case 'B': // Blue
+ symbol->bitmap[i] = 0;
+ symbol->bitmap[i + 1] = 0;
+ symbol->bitmap[i + 2] = 255;
+ break;
+ case 'M': // Magenta
+ symbol->bitmap[i] = 255;
+ symbol->bitmap[i + 1] = 0;
+ symbol->bitmap[i + 2] = 255;
+ break;
+ case 'R': // Red
+ symbol->bitmap[i] = 255;
+ symbol->bitmap[i + 1] = 0;
+ symbol->bitmap[i + 2] = 0;
+ break;
+ case 'Y': // Yellow
+ symbol->bitmap[i] = 255;
+ symbol->bitmap[i + 1] = 255;
+ symbol->bitmap[i + 2] = 0;
+ break;
+ case 'G': // Green
+ symbol->bitmap[i] = 0;
+ symbol->bitmap[i + 1] = 255;
+ symbol->bitmap[i + 2] = 0;
+ break;
+ case 'K': // Black
+ symbol->bitmap[i] = 0;
+ symbol->bitmap[i + 1] = 0;
+ symbol->bitmap[i + 2] = 0;
+ break;
+ case DEFAULT_INK:
+ symbol->bitmap[i] = fgred;
+ symbol->bitmap[i + 1] = fggrn;
+ symbol->bitmap[i + 2] = fgblu;
+ break;
+ default: // DEFAULT_PAPER
+ symbol->bitmap[i] = bgred;
+ symbol->bitmap[i + 1] = bggrn;
+ symbol->bitmap[i + 2] = bgblu;
+ break;
+
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int save_raster_image_to_file(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle, int image_type) {
+ int error_number;
+ int row, column;
+
+ char *rotated_pixbuf = pixelbuf;
+
+ 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 (rotate_angle) {
+ if (!(rotated_pixbuf = (char *) malloc(image_width * image_height))) {
+ strcpy(symbol->errtxt, "650: Insufficient memory for pixel buffer");
+ return ZINT_ERROR_ENCODING_PROBLEM;
+ }
+ }
+
+ /* Rotate image before plotting */
+ switch (rotate_angle) {
+ case 0: /* Plot the right way up */
+ /* Nothing to do */
+ break;
+ case 90: /* Plot 90 degrees clockwise */
+ for (row = 0; row < image_width; row++) {
+ for (column = 0; column < image_height; column++) {
+ rotated_pixbuf[(row * image_height) + column] =
+ *(pixelbuf + (image_width * (image_height - column - 1)) + row);
+ }
+ }
+ break;
+ case 180: /* Plot upside down */
+ for (row = 0; row < image_height; row++) {
+ for (column = 0; column < image_width; column++) {
+ rotated_pixbuf[(row * image_width) + column] =
+ *(pixelbuf + (image_width * (image_height - row - 1)) + (image_width - column - 1));
+ }
+ }
+ break;
+ case 270: /* Plot 90 degrees anti-clockwise */
+ for (row = 0; row < image_width; row++) {
+ for (column = 0; column < image_height; column++) {
+ rotated_pixbuf[(row * image_height) + column] =
+ *(pixelbuf + (image_width * column) + (image_width - row - 1));
+ }
+ }
+ break;
+ }
+
+ switch (image_type) {
+ case OUT_BUFFER:
+ error_number = buffer_plot(symbol, rotated_pixbuf);
+ break;
+ case OUT_PNG_FILE:
+#ifndef NO_PNG
+ error_number = png_pixel_plot(symbol, rotated_pixbuf);
+#else
+ if (rotate_angle) {
+ free(rotated_pixbuf);
+ }
+ return ZINT_ERROR_INVALID_OPTION;
+#endif
+ break;
+ case OUT_PCX_FILE:
+ error_number = pcx_pixel_plot(symbol, rotated_pixbuf);
+ break;
+ case OUT_GIF_FILE:
+ error_number = gif_pixel_plot(symbol, rotated_pixbuf);
+ break;
+ case OUT_TIF_FILE:
+ error_number = tif_pixel_plot(symbol, rotated_pixbuf);
+ break;
+ default:
+ error_number = bmp_pixel_plot(symbol, rotated_pixbuf);
+ break;
+ }
+
+ if (rotate_angle) {
+ free(rotated_pixbuf);
+ }
+ return error_number;
+}
+
+static void draw_bar(char *pixelbuf, int xpos, int xlen, int ypos, int ylen, int image_width, int image_height, char fill) {
+ /* 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) = fill;
+ }
+ }
+}
+
+static void draw_circle(char *pixelbuf, int image_width, int image_height, int x0, int y0, float radius, char fill) {
+ int x, y;
+ int radius_i = (int) radius;
+
+ for (y = -radius_i; y <= radius_i; y++) {
+ for (x = -radius_i; x <= radius_i; x++) {
+ if ((x * x) + (y * y) <= (radius_i * radius_i)) {
+ if ((y + y0 >= 0) && (y + y0 < image_height)
+ && (x + x0 >= 0) && (x + x0 < image_width)) {
+ *(pixelbuf + ((y + y0) * image_width) + (x + x0)) = fill;
+ }
+ }
+ }
+ }
+}
+
+static void draw_bullseye(char *pixelbuf, int image_width, int image_height, int xoffset, int yoffset, int scaler) {
+ /* Central bullseye in Maxicode symbols */
+ float x = 14.5 * scaler;
+ float y = 15.0 * scaler;
+ if(scaler < 10) {
+ x = 16.0 * scaler;
+ y = 16.5 * scaler;
+ }
+
+ draw_circle(pixelbuf, image_width, image_height, x + xoffset, y + yoffset, (4.571 * scaler) + 1, DEFAULT_INK);
+ draw_circle(pixelbuf, image_width, image_height, x + xoffset, y + yoffset, (3.779 * scaler) + 1, DEFAULT_PAPER);
+ draw_circle(pixelbuf, image_width, image_height, x + xoffset, y + yoffset, (2.988 * scaler) + 1, DEFAULT_INK);
+ draw_circle(pixelbuf, image_width, image_height, x + xoffset, y + yoffset, (2.196 * scaler) + 1, DEFAULT_PAPER);
+ draw_circle(pixelbuf, image_width, image_height, x + xoffset, y + yoffset, (1.394 * scaler) + 1, DEFAULT_INK);
+ draw_circle(pixelbuf, image_width, image_height, x + xoffset, y + yoffset, (0.602 * scaler) + 1, DEFAULT_PAPER);
+}
+
+static void draw_hexagon(char *pixelbuf, int image_width, char *scaled_hexagon, int hexagon_size, int xposn, int yposn) {
+ /* Put a hexagon into the pixel buffer */
+ int i, j;
+
+ for (i = 0; i < hexagon_size; i++) {
+ for (j = 0; j < hexagon_size; j++) {
+ if (scaled_hexagon[(i * hexagon_size) + j] == DEFAULT_INK) {
+ *(pixelbuf + (image_width * i) + (image_width * yposn) + xposn + j) = DEFAULT_INK;
+ }
+ }
+ }
+}
+
+static void draw_letter(char *pixelbuf, unsigned char letter, int xposn, int yposn, int textflags, int image_width, int image_height) {
+ /* Put a letter into a position */
+ int skip;
+
+ skip = 0;
+
+ if (letter < 33) {
+ skip = 1;
+ }
+
+ if ((letter > 127) && (letter < 161)) {
+ skip = 1;
+ }
+
+ if (xposn < 0 || yposn < 0) {
+ skip = 1;
+ }
+
+ if (skip == 0) {
+ int glyph_no;
+ int x, y;
+ if (letter > 128) {
+ glyph_no = letter - 66;
+ } else {
+ glyph_no = letter - 33;
+ }
+
+
+ switch (textflags) {
+ int max_x, max_y;
+ case 1: // small font 5x9
+ max_x = 5;
+ max_y = 9;
+
+ if (xposn + max_x >= image_width) {
+ max_x = image_width - xposn - 1;
+ }
+
+ if (yposn + max_y >= image_height) {
+ max_y = image_height - yposn - 1;
+ }
+
+ for (y = 0; y < max_y; y++) {
+ for (x = 0; x < max_x; x++) {
+ if (small_font[(glyph_no * 9) + y] & (0x10 >> x)) {
+ *(pixelbuf + (y * image_width) + (yposn * image_width) + xposn + x) = DEFAULT_INK;
+ }
+ }
+ }
+ break;
+
+ case 2: // bold font -> twice the regular font
+ {
+ char * linePtr;
+ max_x = 7;
+ max_y = 14;
+
+ if (xposn + max_x + 1 >= image_width) {
+ max_x = image_width - xposn - 2;
+ }
+
+ if (yposn + max_y >= image_height) {
+ max_y = image_height - yposn - 1;
+ }
+
+ linePtr = pixelbuf + (yposn * image_width) + xposn + 1;
+ for (y = 0; y < max_y; y++) {
+ char * pixelPtr = linePtr;
+ int extra_dot = 0;
+ for (x = 0; x < max_x; x++) {
+ if (ascii_font[(glyph_no * 14) + y] & (0x40 >> x)) {
+ *pixelPtr = DEFAULT_INK;
+ extra_dot = 1;
+ } else {
+ if (extra_dot) {
+ *pixelPtr = DEFAULT_INK;
+ }
+
+ extra_dot = 0;
+ }
+
+ ++pixelPtr;
+ }
+
+ if (extra_dot) {
+ *pixelPtr = DEFAULT_INK;
+ }
+
+ linePtr += image_width;
+ }
+ }
+ break;
+
+ default: // regular font 7x14
+ max_x = 7;
+ max_y = 14;
+
+ if (xposn + max_x >= image_width) {
+ max_x = image_width - xposn - 1;
+ }
+
+ if (yposn + max_y >= image_height) {
+ max_y = image_height - yposn - 1;
+ }
+
+ for (y = 0; y < max_y; y++) {
+ for (x = 0; x < max_x; x++) {
+ if (ascii_font[(glyph_no * 14) + y] & (0x40 >> x)) {
+ *(pixelbuf + (y * image_width) + (yposn * image_width) + xposn + x) = DEFAULT_INK;
+ }
+ }
+ }
+ break;
+ }
+ }
+}
+
+/* Plot a string into the pixel buffer */
+static void draw_string(char *pixbuf, char input_string[], int xposn, int yposn, int textflags, int image_width, int image_height) {
+ int i, string_length, string_left_hand, letter_width = 7;
+
+ switch (textflags) {
+ case 1: // small font 5x9
+ letter_width = 5;
+ break;
+
+ case 2: // bold font -> width of the regular font + 1 extra dot + 1 extra space
+ letter_width = 9;
+ break;
+
+ default: // regular font 7x15
+ letter_width = 7;
+ break;
+ }
+
+ string_length = strlen(input_string);
+ string_left_hand = xposn - ((letter_width * string_length) / 2);
+
+ for (i = 0; i < string_length; i++) {
+ // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage) suppress false positive about 2nd arg input_string[i] being uninitialized
+ draw_letter(pixbuf, input_string[i], string_left_hand + (i * letter_width), yposn, textflags, image_width, image_height);
+ }
+
+}
+
+static void plot_hexline(char *scaled_hexagon, int hexagon_size, float start_x, float start_y, float end_x, float end_y) {
+ /* Draw a straight line from start to end */
+ int i;
+ float inc_x, inc_y;
+
+ inc_x = (end_x - start_x) / hexagon_size;
+ inc_y = (end_y - start_y) / hexagon_size;
+
+ for (i = 0; i < hexagon_size; i++) {
+ float this_x = start_x + ((float)i * inc_x);
+ float this_y = start_y + ((float)i * inc_y);
+ if (((this_x >= 0) && (this_x < hexagon_size)) && ((this_y >= 0) && (this_y < hexagon_size))) {
+ scaled_hexagon[(hexagon_size * (int)this_y) + (int)this_x] = DEFAULT_INK;
+ }
+ }
+}
+
+static void plot_hexagon(char *scaled_hexagon, int hexagon_size) {
+ /* Create a hexagon shape and fill it */
+ int line, i;
+
+ float x_offset[6];
+ float y_offset[6];
+ float start_x, start_y;
+ float end_x, end_y;
+
+ x_offset[0] = 0.0;
+ x_offset[1] = 0.86;
+ x_offset[2] = 0.86;
+ x_offset[3] = 0.0;
+ x_offset[4] = -0.86;
+ x_offset[5] = -0.86;
+
+ y_offset[0] = 1.0;
+ y_offset[1] = 0.5;
+ y_offset[2] = -0.5;
+ y_offset[3] = -1.0;
+ y_offset[4] = -0.5;
+ y_offset[5] = 0.5;
+
+ /* Plot hexagon outline */
+ for (line = 0; line < 5; line++) {
+ start_x = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * x_offset[line]);
+ start_y = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * y_offset[line]);
+ end_x = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * x_offset[line + 1]);
+ end_y = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * y_offset[line + 1]);
+ plot_hexline(scaled_hexagon, hexagon_size, start_x, start_y, end_x, end_y);
+ }
+ start_x = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * x_offset[line]);
+ start_y = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * y_offset[line]);
+ end_x = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * x_offset[0]);
+ end_y = ((float)hexagon_size / 2.0) + (((float)hexagon_size / 2.0) * y_offset[0]);
+ plot_hexline(scaled_hexagon, hexagon_size, start_x, start_y, end_x, end_y);
+
+ /* Fill hexagon */
+ for (line = 0; line < hexagon_size; line++) {
+ char ink = DEFAULT_PAPER;
+ for (i = 0; i < hexagon_size; i++) {
+ if (scaled_hexagon[(hexagon_size * line) + i] == DEFAULT_INK) {
+ if (i < (hexagon_size / 2)) {
+ ink = DEFAULT_INK;
+ } else {
+ ink = DEFAULT_PAPER;
+ }
+ }
+
+ if (ink == DEFAULT_INK) {
+ scaled_hexagon[(hexagon_size * line) + i] = ink;
+ }
+ }
+ }
+}
+
+static int plot_raster_maxicode(struct zint_symbol *symbol, int rotate_angle, int data_type) {
+ /* Plot a MaxiCode symbol with hexagons and bullseye */
+ int row, column, xposn;
+ int image_height, image_width;
+ char *pixelbuf;
+ int error_number;
+ int xoffset, yoffset;
+ int roffset, boffset;
+ float scaler = symbol->scale;
+ char *scaled_hexagon;
+ int hexagon_size;
+
+ if (scaler <= 0) {
+ scaler = 0.5;
+ }
+
+ set_whitespace_offsets(symbol, &xoffset, &yoffset, &roffset, &boffset);
+
+ image_width = (300 + 2 * (xoffset + roffset)) * scaler;
+ image_height = (300 + 2 * (yoffset + boffset)) * scaler;
+
+ if (!(pixelbuf = (char *) malloc(image_width * image_height))) {
+ strcpy(symbol->errtxt, "655: Insufficient memory for pixel buffer");
+ return ZINT_ERROR_ENCODING_PROBLEM;
+ }
+ memset(pixelbuf, DEFAULT_PAPER, image_width * image_height);
+
+ hexagon_size = (int)(scaler * 10);
+
+ if (!(scaled_hexagon = (char *) malloc(hexagon_size * hexagon_size))) {
+ strcpy(symbol->errtxt, "656: Insufficient memory for pixel buffer");
+ free(pixelbuf);
+ return ZINT_ERROR_ENCODING_PROBLEM;
+ }
+ memset(scaled_hexagon, DEFAULT_PAPER, hexagon_size * hexagon_size);
+
+ plot_hexagon(scaled_hexagon, hexagon_size);
+
+ for (row = 0; row < symbol->rows; row++) {
+ int yposn = row * 9;
+ for (column = 0; column < symbol->width; column++) {
+ xposn = column * 10;
+ if (module_is_set(symbol, row, column)) {
+ if (row & 1) {
+ /* Odd (reduced) row */
+ xposn += 5;
+ draw_hexagon(pixelbuf, image_width, scaled_hexagon, hexagon_size, (xposn + (2 * xoffset)) * scaler, (yposn + (2 * yoffset)) * scaler);
+ } else {
+ /* Even (full) row */
+ draw_hexagon(pixelbuf, image_width, scaled_hexagon, hexagon_size, (xposn + (2 * xoffset)) * scaler, (yposn + (2 * yoffset)) * scaler);
+ }
+ }
+ }
+ }
+
+ draw_bullseye(pixelbuf, image_width, image_height, (2.0 * xoffset), (2.0 * yoffset), scaler * 10);
+
+ // Virtual hexagon
+ //draw_hexagon(pixelbuf, image_width, scaled_hexagon, hexagon_size, ((14 * 10) + (2 * xoffset)) * scaler, ((16 * 9) + (2 * yoffset)) * scaler);
+
+ if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) {
+ /* boundary bars */
+ draw_bar(pixelbuf, 0, image_width, 0, symbol->border_width * 2, image_width, image_height, DEFAULT_INK);
+ draw_bar(pixelbuf, 0, image_width, 300 + (symbol->border_width * 2), symbol->border_width * 2, image_width, image_height, DEFAULT_INK);
+ }
+
+ if (symbol->output_options & BARCODE_BOX) {
+ /* side bars */
+ draw_bar(pixelbuf, 0, symbol->border_width * 2, 0, image_height, image_width, image_height, DEFAULT_INK);
+ 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, DEFAULT_INK);
+ }
+
+ error_number = save_raster_image_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type);
+ free(scaled_hexagon);
+ free(pixelbuf);
+ return error_number;
+}
+
+/* Convert UTF-8 to Latin1 Codepage for the interpretation line */
+static void to_latin1(unsigned char source[], unsigned char preprocessed[]) {
+ int j, i, input_length;
+
+ input_length = ustrlen(source);
+
+ j = 0;
+ i = 0;
+ while (i < input_length) {
+ switch (source[i]) {
+ case 0xC2:
+ /* UTF-8 C2xxh */
+ /* Character range: C280h (latin: 80h) to C2BFh (latin: BFh) */
+ i++;
+ preprocessed[j] = source[i];
+ j++;
+ break;
+ case 0xC3:
+ /* UTF-8 C3xx */
+ /* Character range: C380h (latin: C0h) to C3BFh (latin: FFh) */
+ i++;
+ preprocessed[j] = source[i] + 64;
+ j++;
+ break;
+ default:
+ /* Process ASCII (< 80h), all other unicode points are ignored */
+ if (source[i] < 128) {
+ preprocessed[j] = source[i];
+ j++;
+ }
+ break;
+ }
+ i++;
+ }
+ preprocessed[j] = '\0';
+
+ return;
+}
+
+static int plot_raster_dotty(struct zint_symbol *symbol, int rotate_angle, int data_type) {
+ float scaler = 2 * symbol->scale;
+ char *scaled_pixelbuf;
+ int r, i;
+ int scale_width, scale_height;
+ int error_number = 0;
+ int xoffset, yoffset, image_width, image_height;
+ int roffset, boffset;
+
+ symbol->height = symbol->rows; // This is true because only 2d matrix symbols are processed here
+
+ set_whitespace_offsets(symbol, &xoffset, &yoffset, &roffset, &boffset);
+
+ image_width = symbol->width + xoffset + roffset;
+ image_height = symbol->height + yoffset + boffset;
+
+ if (scaler < 2.0) {
+ scaler = 2.0;
+ }
+ scale_width = (image_width * scaler) + 1;
+ scale_height = (image_height * scaler) + 1;
+
+ /* Apply scale options by creating another pixel buffer */
+ if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) {
+ strcpy(symbol->errtxt, "657: Insufficient memory for pixel buffer");
+ return ZINT_ERROR_ENCODING_PROBLEM;
+ }
+ memset(scaled_pixelbuf, DEFAULT_PAPER, scale_width * scale_height);
+
+ /* Plot the body of the symbol to the pixel buffer */
+ for (r = 0; r < symbol->rows; r++) {
+ for (i = 0; i < symbol->width; i++) {
+ if (module_is_set(symbol, r, i)) {
+ draw_circle(scaled_pixelbuf, scale_width, scale_height,
+ (int) ((i + xoffset) * scaler) + (scaler / 2.0),
+ (int) ((r + yoffset) * scaler) + (scaler / 2.0),
+ (symbol->dot_size / 2.0) * scaler,
+ DEFAULT_INK);
+ }
+ }
+ }
+
+ error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle, data_type);
+ free(scaled_pixelbuf);
+
+ return error_number;
+}
+
+static int plot_raster_default(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;
+ int roffset, boffset;
+ char *pixelbuf;
+ int addon_latch = 0, textflags = 0;
+ int block_width, textpos;
+ float row_height, row_posn;
+ int error_number;
+ int default_text_posn;
+ int next_yposn;
+ float scaler = symbol->scale;
+ char *scaled_pixelbuf;
+ int horiz, vert;
+ int scale_width, scale_height;
+#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) {
+ /* Copy text from symbol */
+ to_latin1(symbol->text, local_text);
+ } else {
+ /* No text needed */
+ if (is_extendable(symbol->symbology)) {
+ /* For these symbols use dummy text to ensure formatting is done
+ * properly even if no text is required */
+ for (i = 0; i < (int) ustrlen(symbol->text); i++) {
+ if (symbol->text[i] == '+') {
+ local_text[i] = '+';
+ } else {
+ local_text[i] = ' ';
+ }
+ }
+ local_text[ustrlen(symbol->text)] = '\0';
+ } else {
+ /* For everything else, just remove the text */
+ memset(local_text, 0, ustrlen(symbol->text) + 1); /* Note using memset() here to suppress clang-tidy false positives */
+ }
+ }
+
+ textdone = 0;
+ main_width = symbol->width;
+ comp_offset = 0;
+ addon_text_posn = 0.0;
+ if (symbol->output_options & SMALL_TEXT) {
+ textflags = 1;
+ } else if (symbol->output_options & BOLD_TEXT) {
+ textflags = 2;
+ }
+
+ 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;
+ }
+
+ if (is_composite(symbol->symbology)) {
+ 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->symbology == BARCODE_EANX_CHK)
+ || (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;
+ }
+ } else if ((symbol->symbology == BARCODE_UPCA) || (symbol->symbology == BARCODE_UPCA_CHK)
+ || (symbol->symbology == BARCODE_UPCA_CC)) {
+ if (symbol->whitespace_width == 0) {
+ symbol->whitespace_width = 10;
+ }
+ main_width = 96 + comp_offset;
+ } else if ((symbol->symbology == BARCODE_UPCE) || (symbol->symbology == BARCODE_UPCE_CHK)
+ || (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 < (int) 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;
+ }
+
+ set_whitespace_offsets(symbol, &xoffset, &yoffset, &roffset, &boffset);
+
+ image_width = 2 * (symbol->width + xoffset + roffset);
+ image_height = 2 * (symbol->height + textoffset + yoffset + boffset);
+
+ if (!(pixelbuf = (char *) malloc(image_width * image_height))) {
+ strcpy(symbol->errtxt, "658: Insufficient memory for pixel buffer");
+ return ZINT_ERROR_ENCODING_PROBLEM;
+ }
+ memset(pixelbuf, DEFAULT_PAPER, image_width * image_height);
+
+ default_text_posn = image_height - 17;
+
+ 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++) {
+ int plot_yposn;
+ int plot_height;
+ int this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */
+ int module_fill;
+ row_posn += row_height;
+ plot_yposn = next_yposn;
+ 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;
+
+ do {
+ module_fill = module_is_set(symbol, this_row, i);
+ block_width = 0;
+ do {
+ block_width++;
+ } while ((i + block_width < symbol->width) && module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i));
+
+ if ((addon_latch == 0) && (r == 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 (module_fill) {
+ /* a bar */
+ if (symbol->symbology == BARCODE_ULTRA) {
+ draw_bar(pixelbuf, (i + xoffset) * 2, block_width * 2, plot_yposn * 2, plot_height * 2, image_width, image_height, ultra_colour[module_fill]);
+ } else {
+ draw_bar(pixelbuf, (i + xoffset) * 2, block_width * 2, plot_yposn * 2, plot_height * 2, image_width, image_height, DEFAULT_INK);
+ }
+ }
+ i += block_width;
+
+ } while (i < symbol->width);
+ }
+
+ xoffset += comp_offset;
+
+ if ((symbol->symbology == BARCODE_EANX) || (symbol->symbology == BARCODE_EANX_CHK)
+ || (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, DEFAULT_INK);
+ draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height, DEFAULT_INK);
+ draw_bar(pixelbuf, (32 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height, DEFAULT_INK);
+ draw_bar(pixelbuf, (34 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height, DEFAULT_INK);
+ draw_bar(pixelbuf, (64 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height, DEFAULT_INK);
+ draw_bar(pixelbuf, (66 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height, DEFAULT_INK);
+ for (i = 0; i < 4; i++) {
+ textpart[i] = local_text[i];
+ }
+ textpart[4] = '\0';
+ textpos = 2 * (17 + xoffset);
+
+ draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
+ for (i = 0; i < 4; i++) {
+ textpart[i] = local_text[i + 4];
+ }
+ textpart[4] = '\0';
+ textpos = 2 * (50 + xoffset);
+ draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, 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, textflags, image_width, image_height);
+ break;
+ case 5:
+ textpos = 2 * (xoffset + 100);
+ draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, 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, DEFAULT_INK);
+ draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height, DEFAULT_INK);
+ draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height, DEFAULT_INK);
+ draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height, DEFAULT_INK);
+ draw_bar(pixelbuf, (92 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height, DEFAULT_INK);
+ draw_bar(pixelbuf, (94 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height, DEFAULT_INK);
+
+ textpart[0] = local_text[0];
+ textpart[1] = '\0';
+ textpos = 2 * (-7 + xoffset);
+ draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
+ for (i = 0; i < 6; i++) {
+ textpart[i] = local_text[i + 1];
+ }
+ textpart[6] = '\0';
+ textpos = 2 * (24 + xoffset);
+ draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
+ for (i = 0; i < 6; i++) {
+ textpart[i] = local_text[i + 7];
+ }
+ textpart[6] = '\0';
+ textpos = 2 * (71 + xoffset);
+ draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, 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, textflags, image_width, image_height);
+ break;
+ case 5:
+ textpos = 2 * (xoffset + 128);
+ draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height);
+ break;
+ }
+ break;
+
+ }
+
+ } else if ((symbol->symbology == BARCODE_UPCA) || (symbol->symbology == BARCODE_UPCA_CHK)
+ || (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 ((i + block_width < symbol->width) && 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, DEFAULT_INK);
+ 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, DEFAULT_INK);
+ draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height, DEFAULT_INK);
+ latch = 1;
+ i = 85 + comp_offset;
+ do {
+ block_width = 0;
+ do {
+ block_width++;
+ } while ((i + block_width < symbol->width) && module_is_set(symbol, symbol->rows - 1, i + block_width) == module_is_set(symbol, symbol->rows - 1, i));
+ 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, DEFAULT_INK);
+ latch = 0;
+ } else {
+ /* a space */
+ latch = 1;
+ }
+ i += block_width;
+ } while (i < 96 + comp_offset);
+ textpart[0] = local_text[0];
+ textpart[1] = '\0';
+ textpos = 2 * (-5 + xoffset);
+ draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
+ for (i = 0; i < 5; i++) {
+ textpart[i] = local_text[i + 1];
+ }
+ textpart[5] = '\0';
+ textpos = 2 * (27 + xoffset);
+ draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
+ for (i = 0; i < 5; i++) {
+ textpart[i] = local_text[i + 6];
+ }
+ textpart[6] = '\0';
+ textpos = 2 * (68 + xoffset);
+ draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
+ textpart[0] = local_text[11];
+ textpart[1] = '\0';
+ textpos = 2 * (100 + xoffset);
+ draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, 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, textflags, image_width, image_height);
+ break;
+ case 5:
+ textpos = 2 * (xoffset + 130);
+ draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height);
+ break;
+ }
+
+ } else if ((symbol->symbology == BARCODE_UPCE) || (symbol->symbology == BARCODE_UPCE_CHK)
+ || (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, DEFAULT_INK);
+ draw_bar(pixelbuf, (2 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height, DEFAULT_INK);
+ draw_bar(pixelbuf, (46 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height, DEFAULT_INK);
+ draw_bar(pixelbuf, (48 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height, DEFAULT_INK);
+ draw_bar(pixelbuf, (50 + xoffset) * 2, 1 * 2, (4 + (int) yoffset) * 2, 5 * 2, image_width, image_height, DEFAULT_INK);
+
+ textpart[0] = local_text[0];
+ textpart[1] = '\0';
+ textpos = 2 * (-5 + xoffset);
+ draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
+ for (i = 0; i < 6; i++) {
+ textpart[i] = local_text[i + 1];
+ }
+ textpart[6] = '\0';
+ textpos = 2 * (24 + xoffset);
+ draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, image_width, image_height);
+ textpart[0] = local_text[7];
+ textpart[1] = '\0';
+ textpos = 2 * (55 + xoffset);
+ draw_string(pixelbuf, textpart, textpos, default_text_posn, textflags, 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, textflags, image_width, image_height);
+ break;
+ case 5:
+ textpos = 2 * (xoffset + 84);
+ draw_string(pixelbuf, addon, textpos, image_height - (addon_text_posn * 2) - 13, textflags, image_width, image_height);
+ break;
+ }
+
+ }
+
+ xoffset -= comp_offset;
+
+ /* Put boundary bars or box around symbol */
+ if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) {
+ /* boundary bars */
+ if ((symbol->output_options & BARCODE_BOX) || (symbol->symbology != BARCODE_CODABLOCKF && symbol->symbology != BARCODE_HIBC_BLOCKF)) {
+ draw_bar(pixelbuf, 0, (symbol->width + xoffset + roffset) * 2, textoffset * 2, symbol->border_width * 2, image_width, image_height, DEFAULT_INK);
+ draw_bar(pixelbuf, 0, (symbol->width + xoffset + roffset) * 2, (textoffset + symbol->height + symbol->border_width) * 2, symbol->border_width * 2, image_width, image_height, DEFAULT_INK);
+ } else {
+ draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, textoffset * 2, symbol->border_width * 2, image_width, image_height, DEFAULT_INK);
+ draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, (textoffset + symbol->height + symbol->border_width) * 2, symbol->border_width * 2, image_width, image_height, DEFAULT_INK);
+ }
+ if ((symbol->output_options & BARCODE_BIND) != 0) {
+ if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) {
+ double sep_height = 1;
+ if (symbol->option_3 > 0 && symbol->option_3 <= 4) {
+ sep_height = symbol->option_3;
+ }
+ /* row binding */
+ if (symbol->symbology != BARCODE_CODABLOCKF && symbol->symbology != BARCODE_HIBC_BLOCKF) {
+ for (r = 1; r < symbol->rows; r++) {
+ draw_bar(pixelbuf, xoffset * 2, symbol->width * 2, ((r * row_height) + textoffset + yoffset - sep_height / 2) * 2, sep_height * 2, image_width, image_height, DEFAULT_INK);
+ }
+ } else {
+ for (r = 1; r < symbol->rows; r++) {
+ /* Avoid 11-module start and 13-module stop chars */
+ draw_bar(pixelbuf, (xoffset + 11) * 2, (symbol->width - 24) * 2, ((r * row_height) + textoffset + yoffset - sep_height / 2) * 2, sep_height * 2, image_width, image_height, DEFAULT_INK);
+ }
+ }
+ }
+ }
+ }
+
+ if (symbol->output_options & BARCODE_BOX) {
+ /* side bars */
+ draw_bar(pixelbuf, 0, symbol->border_width * 2, textoffset * 2, (symbol->height + (2 * symbol->border_width)) * 2, image_width, image_height, DEFAULT_INK);
+ draw_bar(pixelbuf, (symbol->width + xoffset + roffset - symbol->border_width) * 2, symbol->border_width * 2, textoffset * 2, (symbol->height + (2 * symbol->border_width)) * 2, image_width, image_height, DEFAULT_INK);
+ }
+
+ /* 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, textflags, image_width, image_height);
+ }
+
+
+ if (scaler <= 0) {
+ scaler = 0.5;
+ }
+
+ if (scaler != 1.0) {
+ 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))) {
+ free(pixelbuf);
+ strcpy(symbol->errtxt, "659: Insufficient memory for pixel buffer");
+ return ZINT_ERROR_ENCODING_PROBLEM;
+ }
+ memset(scaled_pixelbuf, DEFAULT_PAPER, scale_width * scale_height);
+
+ 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));
+ }
+ }
+
+ error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle, data_type);
+ free(scaled_pixelbuf);
+ } else {
+ error_number = save_raster_image_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type);
+ }
+ free(pixelbuf);
+ return error_number;
+}
+
+INTERNAL int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type) {
+ int error;
+
+#ifdef NO_PNG
+ if (file_type == OUT_PNG_FILE) {
+ strcpy(symbol->errtxt, "660: PNG format disabled at compile time");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+#endif /* NO_PNG */
+
+ error = check_colour_options(symbol);
+ if (error != 0) {
+ return error;
+ }
+
+ if (symbol->output_options & BARCODE_DOTTY_MODE) {
+ error = plot_raster_dotty(symbol, rotate_angle, file_type);
+ } else {
+ if (symbol->symbology == BARCODE_MAXICODE) {
+ error = plot_raster_maxicode(symbol, rotate_angle, file_type);
+ } else {
+ error = plot_raster_default(symbol, rotate_angle, file_type);
+ }
+ }
+
+ return error;
+}
diff --git a/backend/reedsol.c b/backend/reedsol.c
index ef9e402..6d908e4 100644
--- a/backend/reedsol.c
+++ b/backend/reedsol.c
@@ -27,7 +27,8 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
// It is not written with high efficiency in mind, so is probably
// not suitable for real-time encoding. The aim was to keep it
@@ -48,12 +49,12 @@
// malloc/free can be avoided by using static arrays of a suitable
// size.
-#include <stdio.h> // only needed for debug (main)
-#include <stdlib.h> // only needed for malloc/free
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+#include "common.h"
#include "reedsol.h"
-static int gfpoly;
-static int symsize; // in bits
-static int logmod; // 2**symsize - 1
+static int logmod; // 2**symsize - 1
static int rlen;
static int *logt = NULL, *alog = NULL, *rspoly = NULL;
@@ -68,30 +69,32 @@ static int *logt = NULL, *alog = NULL, *rspoly = NULL;
// 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;
- }
+INTERNAL void rs_init_gf(const 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--;
+
+ // Ensure m not negative to supress gcc -Walloc-size-larger-than
+ if (m < 0) {
+ m = 0;
+ }
+
+ // 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
@@ -101,71 +104,69 @@ void rs_init_gf(int poly)
// (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++;
- }
+INTERNAL void rs_init_code(const 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;
- }
+INTERNAL void rs_encode(const size_t len, const unsigned char *data, unsigned char *res) {
+ int i, k;
+ for (i = 0; i < rlen; i++)
+ res[i] = 0;
+ for (i = 0; i < (int) len; i++) {
+ int m = res[rlen - 1] ^ data[i];
+ for (k = rlen - 1; k > 0; k--) {
+ if (m && rspoly[k])
+ res[k] = (unsigned char) (res[k - 1] ^ alog[(logt[m] + logt[rspoly[k]]) % logmod]);
+ else
+ res[k] = res[k - 1];
+ }
+ if (m && rspoly[0])
+ res[0] = (unsigned char) (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;
- }
+/* The same as above but for larger bitlengths - Aztec code compatible */
+INTERNAL void rs_encode_long(const int len, const unsigned int *data, unsigned int *res) {
+ int i, k;
+ for (i = 0; i < rlen; i++)
+ res[i] = 0;
+ for (i = 0; i < len; i++) {
+ int 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;
+/* Free memory */
+INTERNAL void rs_free(void) {
+ free(logt);
+ free(alog);
+ free(rspoly);
+ rspoly = NULL;
}
diff --git a/backend/reedsol.h b/backend/reedsol.h
index d61af2c..d0703c9 100644
--- a/backend/reedsol.h
+++ b/backend/reedsol.h
@@ -28,21 +28,21 @@
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
#ifndef __REEDSOL_H
#define __REEDSOL_H
#ifdef __cplusplus
-extern "C"
-{
+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);
+INTERNAL void rs_init_gf(const int poly);
+INTERNAL void rs_init_code(const int nsym,int index);
+INTERNAL void rs_encode(const size_t len,const unsigned char *data, unsigned char *res);
+INTERNAL void rs_encode_long(const int len,const unsigned int *data, unsigned int *res);
+INTERNAL void rs_free(void);
#ifdef __cplusplus
}
diff --git a/backend/render.c b/backend/render.c
deleted file mode 100644
index 6c7968c..0000000
--- a/backend/render.c
+++ /dev/null
@@ -1,792 +0,0 @@
-/*
- * render.c - Generic Rendered Format
- *
- * Initiall written by Sam Lown for use in gLabels. Converts encoded
- * data into a generic internal structure of lines and characters
- * usable in external applications.
- */
-
-/*
- libzint - the open source barcode library
- Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the project nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- SUCH DAMAGE.
-*/
-
-#include <locale.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "common.h"
-
-#define GL_CONST 2.8346
-
-struct zint_render_line *render_plot_create_line(float x, float y, float width, float length);
-int render_plot_add_line(struct zint_symbol *symbol, struct zint_render_line *line, struct zint_render_line **last_line);
-struct zint_render_ring *render_plot_create_ring(float x, float y, float radius, float line_width);
-int render_plot_add_ring(struct zint_symbol *symbol, struct zint_render_ring *ring, struct zint_render_ring **last_ring);
-struct zint_render_hexagon *render_plot_create_hexagon(float x, float y);
-int render_plot_add_hexagon(struct zint_symbol *symbol, struct zint_render_hexagon *ring, struct zint_render_hexagon **last_hexagon);
-
-int render_plot_add_string(struct zint_symbol *symbol, unsigned char *text, float x, float y, float fsize, float width, struct zint_render_string **last_string);
-
-int render_plot(struct zint_symbol *symbol, float width, float height)
-{
- struct zint_render *render;
- struct zint_render_line *line, *last_line = NULL;
- struct zint_render_string *last_string = NULL;
- struct zint_render_ring *ring, *last_ring = NULL;
- struct zint_render_hexagon *hexagon, *last_hexagon = NULL;
-
- int i, r, block_width, latch, this_row;
- float textpos, textwidth, large_bar_height, preset_height, row_height, row_posn = 0.0;
- // int error_number = 0;
- int text_offset, text_height, xoffset, yoffset, textdone, main_symbol_width_x, addon_width_x;
- char addon[6], textpart[10];
- int large_bar_count, symbol_lead_in, total_symbol_width_x, total_area_width_x;
- float addon_text_posn;
- float default_text_posn;
- float scaler;
- const char *locale = NULL;
- int hide_text = 0;
- float required_aspect;
- float symbol_aspect = 1;
- float x_dimension;
- int upceanflag = 0;
-
- // Allocate memory for the rendered version
- render = symbol->rendered = (struct zint_render*)malloc(sizeof(struct zint_render));
- render->lines = NULL;
- render->strings = NULL;
- render->rings = NULL;
- render->hexagons = NULL;
-
- locale = setlocale(LC_ALL, "C");
-
- row_height = 0;
- textdone = 0;
- textpos = 0.0;
- main_symbol_width_x = symbol->width;
- strcpy(addon, "");
- symbol_lead_in = 0;
- addon_text_posn = 0.0;
- addon_width_x = 0;
-
- /*
- * Determine if there will be any addon texts and text height
- */
- 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) || (ustrlen(symbol->text) == 0)) {
- hide_text = 1;
- text_height = text_offset = 0.0;
- } else {
- text_height = 9.0;
- text_offset = 2.0;
- }
-
-
- /*
- * Calculate the width of the barcode, especially if there are any extra
- * borders or white space to add.
- */
-
- while(!(module_is_set(symbol, symbol->rows - 1, symbol_lead_in))) {
- symbol_lead_in++;
- }
-
- /* 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_symbol_width_x = 96 + symbol_lead_in;
- upceanflag = 13;
- break;
- case 2:
- main_symbol_width_x = 22 + symbol_lead_in;
- upceanflag = 2;
- break;
- case 5:
- main_symbol_width_x = 49 + symbol_lead_in;
- upceanflag = 5;
- break;
- default:
- main_symbol_width_x = 68 + symbol_lead_in;
- upceanflag = 8;
- }
- switch(ustrlen(symbol->text)) {
- case 11:
- case 16:
- /* EAN-2 add-on */
- addon_width_x = 31;
- break;
- case 14:
- case 19:
- /* EAN-5 add-on */
- addon_width_x = 58;
- break;
- }
- }
-
- if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) {
- upceanflag = 12;
- if(symbol->whitespace_width < 10) {
- symbol->whitespace_width = 10;
- main_symbol_width_x = 96 + symbol_lead_in;
- }
- switch(ustrlen(symbol->text)) {
- case 15:
- /* EAN-2 add-on */
- addon_width_x = 31;
- break;
- case 18:
- /* EAN-5 add-on */
- addon_width_x = 58;
- break;
- }
- }
-
- if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) {
- upceanflag = 6;
- if(symbol->whitespace_width == 0) {
- symbol->whitespace_width = 10;
- main_symbol_width_x = 51 + symbol_lead_in;
- }
- switch(ustrlen(symbol->text)) {
- case 11:
- /* EAN-2 add-on */
- addon_width_x = 31;
- break;
- case 14:
- /* EAN-5 add-on */
- addon_width_x = 58;
- break;
- }
- }
-
- total_symbol_width_x = main_symbol_width_x + addon_width_x;
- total_area_width_x = total_symbol_width_x + (2 * (symbol->border_width + symbol->whitespace_width));
-
- xoffset = symbol->border_width + symbol->whitespace_width;
- yoffset = symbol->border_width;
-
- // Determine if height should be overridden
- 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) {
- required_aspect = width / height;
- symbol_aspect = (total_symbol_width_x + (2 * xoffset)) / (preset_height + (2 * yoffset) + text_offset + text_height);
- symbol->height = preset_height;
- if (required_aspect > symbol_aspect) {
- /* the area is too wide */
- scaler = height / (preset_height + (2 * yoffset) + text_offset + text_height);
- render->width = symbol_aspect * height;
- render->height = height;
- } else {
- /* the area is too high */
- scaler = width / (total_symbol_width_x + (2 * xoffset));
- render->width = width;
- render->height = width / symbol_aspect;
- }
- } else {
- scaler = width / (total_symbol_width_x + (2 * xoffset));
- symbol->height = (height / scaler) - ((2 * yoffset) + text_offset + text_height);
-
- render->width = width;
- render->height = height;
- }
- large_bar_height = (symbol->height - preset_height) / large_bar_count;
-
- if(((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {
- default_text_posn = (symbol->height + text_offset + symbol->border_width + symbol->border_width) * scaler;
- } else {
- default_text_posn = (symbol->height + text_offset + symbol->border_width) * scaler;
- }
-
- x_dimension = render->width / total_area_width_x;
- x_dimension /= GL_CONST;
-
- /* Set minimum size of symbol */
- /* Barcode must be at least 2mm high by 2mm across */
- if(render->height < ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 2.0) * GL_CONST) {
- render->height = ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 2.0) * GL_CONST;
- }
- if(render->width < (2.0 * GL_CONST)) {
- render->width = (2.0 * GL_CONST);
- }
-
- if(symbol->symbology == BARCODE_CODABAR) {
- /* The minimum X-dimension of Codabar is 0.191mm. The minimum bar height is 5mm */
- if(x_dimension < 0.191) {
- render->width = 0.191 * GL_CONST * total_area_width_x;
- }
- if(render->height < ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 5.0) * GL_CONST) {
- render->height = ((x_dimension * ((2 * symbol->border_width) + text_offset + text_height)) + 5.0) * GL_CONST;
- }
- }
-
- if(symbol->symbology == BARCODE_CODE49) {
- /* The minimum X-dimension of Code 49 is 0.191mm */
- if(x_dimension < 0.191) {
- render->width = 0.191 * GL_CONST * total_area_width_x;
- render->height = render->width / symbol_aspect;
- }
- }
-
- if(upceanflag != 0) {
- /* The X-dimension of UPC/EAN symbols is fixed at 0.330mm */
- /* NOTE: This code will need adjustment before it correctly deals with composite symbols */
- render->width = 0.330 * GL_CONST * total_area_width_x;
- /* The height is also fixed */
- switch (upceanflag) {
- case 6:
- case 12:
- case 13:
- /* UPC-A, UPC-E and EAN-13 */
- /* Height of bars should be 22.85mm */
- render->height = ((0.330 * ((2 * symbol->border_width) + text_offset + text_height)) + 22.85) * GL_CONST;
- break;
- case 8:
- /* EAN-8 */
- /* Height of bars should be 18.23mm */
- render->height = ((0.330 * ((2 * symbol->border_width) + text_offset + text_height)) + 18.23) * GL_CONST;
- break;
- default:
- /* EAN-2 and EAN-5 */
- /* Height of bars should be 21.10mm */
- render->height = ((0.330 * ((2 * symbol->border_width) + text_offset + text_height)) + 21.10) * GL_CONST;
- }
- }
-
- if(symbol->symbology == BARCODE_ONECODE) {
- /* The size of USPS Intelligent Mail barcode is fixed */
- render->width = 0.508 * GL_CONST * total_area_width_x;
- render->height = 4.064 * GL_CONST;
- }
-
- if((symbol->symbology == BARCODE_POSTNET) || (symbol->symbology == BARCODE_PLANET)) {
- /* The size of PostNet and PLANET are fized */
- render->width = 0.508 * GL_CONST * total_area_width_x;
- render->height = 2.921 * GL_CONST;
- }
-
- if(((symbol->symbology == BARCODE_AUSPOST) || (symbol->symbology == BARCODE_AUSREPLY)) ||
- ((symbol->symbology == BARCODE_AUSROUTE) || (symbol->symbology == BARCODE_AUSREDIRECT))) {
- /* Australia Post use the same sizes as USPS */
- render->width = 0.508 * GL_CONST * total_area_width_x;
- render->height = 4.064 * GL_CONST;
- }
-
- if((symbol->symbology == BARCODE_RM4SCC) || (symbol->symbology == BARCODE_KIX)) {
- /* Royal Mail and KIX Code uses 22 bars per inch */
- render->width = 0.577 * GL_CONST * total_area_width_x;
- render->height = 5.22 * GL_CONST;
- }
-
- if(symbol->symbology == BARCODE_MAXICODE) {
- /* Maxicode is a fixed size */
- scaler = GL_CONST; /* Converts from millimeters to the scale used by glabels */
- render->width = 28.16 * scaler;
- render->height = 26.86 * scaler;
-
- /* Central bullseye pattern */
- ring = render_plot_create_ring(13.64 * scaler, 13.43 * scaler, 0.85 * scaler, 0.67 * scaler);
- render_plot_add_ring(symbol, ring, &last_ring);
- ring = render_plot_create_ring(13.64 * scaler, 13.43 * scaler, 2.20 * scaler, 0.67 * scaler);
- render_plot_add_ring(symbol, ring, &last_ring);
- ring = render_plot_create_ring(13.64 * scaler, 13.43 * scaler, 3.54 * scaler, 0.67 * scaler);
- render_plot_add_ring(symbol, ring, &last_ring);
-
- /* Hexagons */
- for(r = 0; r < symbol->rows; r++) {
- for(i = 0; i < symbol->width; i++) {
- if(module_is_set(symbol, r, i)) {
- hexagon = render_plot_create_hexagon(((i * 0.88) + (r & 1 ? 1.76 : 1.32)) * scaler, ((r * 0.76) + 0.76) * scaler);
- render_plot_add_hexagon(symbol, hexagon, &last_hexagon);
- }
- }
- }
-
- } else {
- /* 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_symbol_width_x)) {
- addon_text_posn = row_posn * scaler;
- addon_latch = 1;
- }
- if(latch == 1) {
- /* a bar */
- if(addon_latch == 0) {
- line = render_plot_create_line((i + xoffset) * scaler, (row_posn) * scaler, block_width * scaler, row_height * scaler);
- } else {
- line = render_plot_create_line((i + xoffset) * scaler, (row_posn + 10.0) * scaler, block_width * scaler, (row_height - 5.0) * scaler);
- }
- latch = 0;
-
- render_plot_add_line(symbol, line, &last_line);
- } else {
- /* a space */
- latch = 1;
- }
- i += block_width;
-
- } while (i < symbol->width);
- }
- }
- /* That's done the actual data area, everything else is human-friendly */
-
-
- /* Add the text */
- xoffset -= symbol_lead_in;
- row_posn = (row_posn + large_bar_height) * scaler;
-
- if (!hide_text) {
- if(upceanflag == 8) {
- /* guard bar extensions and text formatting for EAN-8 */
- i = 0;
- for (line = symbol->rendered->lines; line != NULL; line = line->next) {
- switch(i) {
- case 0:
- case 1:
- case 10:
- case 11:
- case 20:
- case 21:
- line->length += (5.0 * scaler);
- break;
- }
- i++;
- }
-
- for(i = 0; i < 4; i++) {
- textpart[i] = symbol->text[i];
- }
- textpart[4] = '\0';
- textpos = 17;
- textwidth = 4.0 * 8.5;
- render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string);
- for(i = 0; i < 4; i++) {
- textpart[i] = symbol->text[i + 4];
- }
- textpart[4] = '\0';
- textpos = 50;
- render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string);
- textdone = 1;
- switch(strlen(addon)) {
- case 2:
- textpos = xoffset + 86;
- textwidth = 2.0 * 8.5;
- render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string);
- break;
- case 5:
- textpos = xoffset + 100;
- textwidth = 5.0 * 8.5;
- render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string);
- break;
- }
-
- }
-
- if(upceanflag == 13) {
- /* guard bar extensions and text formatting for EAN-13 */
- i = 0;
- for (line = symbol->rendered->lines; line != NULL; line = line->next) {
- switch(i) {
- case 0:
- case 1:
- case 14:
- case 15:
- case 28:
- case 29:
- line->length += (5.0 * scaler);
- break;
- }
- i++;
- }
-
- textpart[0] = symbol->text[0];
- textpart[1] = '\0';
- textpos = -5; // 7
- textwidth = 8.5;
- render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string);
-
- for(i = 0; i < 6; i++) {
- textpart[i] = symbol->text[i + 1];
- }
- textpart[6] = '\0';
- textpos = 25;
- textwidth = 6.0 * 8.5;
- render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string);
- for(i = 0; i < 6; i++) {
- textpart[i] = symbol->text[i + 7];
- }
- textpart[6] = '\0';
- textpos = 72;
- render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string);
- textdone = 1;
- switch(strlen(addon)) {
- case 2:
- textpos = xoffset + 114;
- textwidth = 2.0 * 8.5;
- render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string);
- break;
- case 5:
- textpos = xoffset + 128;
- textwidth = 5.0 * 8.5;
- render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string);
- break;
- }
- }
-
- if (upceanflag == 12) {
- /* guard bar extensions and text formatting for UPCA */
- i = 0;
- for (line = symbol->rendered->lines; line != NULL; line = line->next) {
- switch(i) {
- case 0:
- case 1:
- case 2:
- case 3:
- case 14:
- case 15:
- case 26:
- case 27:
- case 28:
- case 29:
- line->length += (5.0 * scaler);
- break;
- }
- i++;
- }
-
- textpart[0] = symbol->text[0];
- textpart[1] = '\0';
- textpos = -5;
- textwidth = 6.2;
- render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string);
- for(i = 0; i < 5; i++) {
- textpart[i] = symbol->text[i + 1];
- }
- textpart[5] = '\0';
- textpos = 27;
- textwidth = 5.0 * 8.5;
- render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string);
- for(i = 0; i < 5; i++) {
- textpart[i] = symbol->text[i + 6];
- }
- textpos = 68;
- render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string);
- textpart[0] = symbol->text[11];
- textpart[1] = '\0';
- textpos = 100;
- textwidth = 6.2;
- render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string);
- textdone = 1;
- switch(strlen(addon)) {
- case 2:
- textpos = xoffset + 116;
- textwidth = 2.0 * 8.5;
- render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string);
- break;
- case 5:
- textpos = xoffset + 130;
- textwidth = 5.0 * 8.5;
- render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string);
- break;
- }
- }
-
- if (upceanflag == 6) {
- /* guard bar extensions and text formatting for UPCE */
- i = 0;
- for (line = symbol->rendered->lines; line != NULL; line = line->next) {
- switch(i) {
- case 0:
- case 1:
- case 14:
- case 15:
- case 16:
- line->length += (5.0 * scaler);
- break;
- }
- i++;
- }
-
- textpart[0] = symbol->text[0];
- textpart[1] = '\0';
- textpos = -5;
- textwidth = 6.2;
- render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string);
- for(i = 0; i < 6; i++) {
- textpart[i] = symbol->text[i + 1];
- }
- textpart[6] = '\0';
- textpos = 24;
- textwidth = 6.0 * 8.5;
- render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn, 11.0 * scaler, textwidth * scaler, &last_string);
- textpart[0] = symbol->text[7];
- textpart[1] = '\0';
- textpos = 55;
- textwidth = 6.2;
- render_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset) * scaler, default_text_posn + (2.0 * scaler), 8.0 * scaler, textwidth * scaler, &last_string);
- textdone = 1;
- switch(strlen(addon)) {
- case 2:
- textpos = xoffset + 70;
- textwidth = 2.0 * 8.5;
- render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string);
- break;
- case 5:
- textpos = xoffset + 84;
- textwidth = 5.0 * 8.5;
- render_plot_add_string(symbol, (unsigned char *) addon, textpos * scaler, addon_text_posn * scaler, 11.0 * scaler, textwidth * scaler, &last_string);
- break;
- }
- }
-
- /* Put normal human readable text at the bottom (and centered) */
- if (textdone == 0) {
- // caculate start xoffset to center text
- render_plot_add_string(symbol, symbol->text, ((symbol->width / 2.0) + xoffset) * scaler, default_text_posn, 9.0 * scaler, 0.0, &last_string);
- }
- }
-
- switch(symbol->symbology) {
- case BARCODE_MAXICODE:
- /* Do nothing! */
- 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++) {
- line = render_plot_create_line(xoffset * scaler, ((r * row_height) + yoffset - 1) * scaler, symbol->width * scaler, 2.0 * scaler);
- render_plot_add_line(symbol, line, &last_line);
- }
- }
- }
- if (((symbol->output_options & BARCODE_BOX) != 0) || ((symbol->output_options & BARCODE_BIND) != 0)) {
- line = render_plot_create_line(0, 0, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler);
- render_plot_add_line(symbol, line, &last_line);
- line = render_plot_create_line(0, (symbol->height + symbol->border_width) * scaler, (symbol->width + xoffset + xoffset) * scaler, symbol->border_width * scaler);
- render_plot_add_line(symbol, line, &last_line);
- }
- if((symbol->output_options & BARCODE_BOX) != 0) {
- /* side bars */
- line = render_plot_create_line(0, 0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler);
- render_plot_add_line(symbol, line, &last_line);
- line = render_plot_create_line((symbol->width + xoffset + xoffset - symbol->border_width) * scaler, 0, symbol->border_width * scaler, (symbol->height + (2 * symbol->border_width)) * scaler);
- render_plot_add_line(symbol, line, &last_line);
- }
- break;
- }
-
- if (locale)
- setlocale(LC_ALL, locale);
-
- return 1;
-}
-
-
-/*
- * Create a new line with its memory allocated ready for adding to the
- * rendered structure.
- *
- * This is much quicker than writing out each line manually (in some cases!)
- */
-struct zint_render_line *render_plot_create_line(float x, float y, float width, float length)
-{
- struct zint_render_line *line;
-
- line = (struct zint_render_line*)malloc(sizeof(struct zint_render_line));
- if (line)
- {
- line->next = NULL;
- line->x = x;
- line->y = y;
- line->width = width;
- line->length = length;
- }
- return line;
-}
-
-/*
- * Add the line to the current rendering and update the last line's
- * next value.
- */
-int render_plot_add_line(struct zint_symbol *symbol, struct zint_render_line *line, struct zint_render_line **last_line)
-{
- if (*last_line)
- (*last_line)->next = line;
- else
- symbol->rendered->lines = line; // first line
-
- *last_line = line;
- return 1;
-}
-
-struct zint_render_ring *render_plot_create_ring(float x, float y, float radius, float line_width)
-{
- struct zint_render_ring *ring;
-
- ring = (struct zint_render_ring*)malloc(sizeof(struct zint_render_ring));
- if (ring)
- {
- ring->next = NULL;
- ring->x = x;
- ring->y = y;
- ring->radius = radius;
- ring->line_width = line_width;
- }
- return ring;
-}
-
-int render_plot_add_ring(struct zint_symbol *symbol, struct zint_render_ring *ring, struct zint_render_ring **last_ring)
-{
- if (*last_ring)
- (*last_ring)->next = ring;
- else
- symbol->rendered->rings = ring; // first ring
-
- *last_ring = ring;
- return 1;
-}
-
-struct zint_render_hexagon *render_plot_create_hexagon(float x, float y)
-{
- struct zint_render_hexagon *hexagon;
-
- hexagon = (struct zint_render_hexagon*)malloc(sizeof(struct zint_render_hexagon));
- if (hexagon)
- {
- hexagon->next = NULL;
- hexagon->x = x;
- hexagon->y = y;
- }
- return hexagon;
-}
-
-int render_plot_add_hexagon(struct zint_symbol *symbol, struct zint_render_hexagon *hexagon, struct zint_render_hexagon **last_hexagon)
-{
- if (*last_hexagon)
- (*last_hexagon)->next = hexagon;
- else
- symbol->rendered->hexagons = hexagon; // first hexagon
-
- *last_hexagon = hexagon;
- return 1;
-}
-
-/*
- * Add a string structure to the symbol.
- * Coordinates assumed to be from top-center.
- */
-int render_plot_add_string(struct zint_symbol *symbol,
- unsigned char *text, float x, float y, float fsize, float width,
- struct zint_render_string **last_string)
-{
- struct zint_render_string *string;
-
- string = (struct zint_render_string*)malloc(sizeof(struct zint_render_string));
- if (string)
- {
- string->next = NULL;
- string->x = x;
- string->y = y;
- string->width = width;
- string->fsize = fsize;
- string->length = ustrlen(text);
- string->text = (unsigned char*)malloc(sizeof(unsigned char) * (ustrlen(text) + 1));
-
- if (string->text)
- ustrcpy(string->text, text);
-
- if (*last_string)
- (*last_string)->next = string;
- else
- symbol->rendered->strings = string; // First character
- *last_string = string;
- }
- return 1;
-}
diff --git a/backend/rss.c b/backend/rss.c
new file mode 100644
index 0000000..d71177b
--- /dev/null
+++ b/backend/rss.c
@@ -0,0 +1,1765 @@
+/* rss.c - Handles Reduced Space Symbology (GS1 DataBar) */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008-2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/* 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 */
+
+/* Note: This code reflects the symbol names as used in ISO/IEC 24724:2006. These names
+ * were updated in ISO/IEC 24724:2011 as follows:
+ *
+ * RSS-14 > GS1 DataBar Omnidirectional
+ * RSS-14 Truncated > GS1 DataBar Truncated
+ * RSS-14 Stacked > GS1 DataBar Stacked
+ * RSS-14 Stacked Omnidirectional > GS1 DataBar Stacked Omnidirectional
+ * RSS Limited > GS1 DataBar Limited
+ * RSS Expanded > GS1 DataBar Expanded Omnidirectional
+ * RSS Expanded Stacked > GS1 DataBar Expanded Stacked Omnidirectional
+ */
+
+#include <stdio.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+#include "common.h"
+#include "large.h"
+#include "rss.h"
+#include "gs1.h"
+#include "general_field.h"
+
+/**********************************************************************
+ * combins(n,r): returns the number of Combinations of r selected from n:
+ * Combinations = n! / ((n - r)! * r!)
+ **********************************************************************/
+static 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
+ **********************************************************************/
+static 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 << bar);
+ ;
+ elmWidth++, narrowMask &= ~(1 << bar)) {
+ /* get all combinations */
+ subVal = combins(n - elmWidth - 1, elements - bar - 2);
+ /* less combinations with no single-module element */
+ if ((!noNarrow) && (!narrowMask) &&
+ (n - elmWidth - (elements - bar - 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;
+}
+
+/* GS1 DataBar-14 */
+INTERNAL int rss14(struct zint_symbol *symbol, unsigned char source[], int src_len) {
+ int error_number = 0, i, j;
+ large_int accum;
+ uint64_t left_pair, right_pair;
+ int data_character[4] = {0}, data_group[4] = {0}, v_odd[4], v_even[4];
+ int data_widths[8][4], checksum, c_left, c_right, total_widths[46], writer;
+ char latch;
+ int separator_row;
+
+ separator_row = 0;
+
+ if (src_len > 13) {
+ strcpy(symbol->errtxt, "380: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, src_len);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "381: 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;
+ }
+
+ large_load_str_u64(&accum, source, src_len);
+
+ if (symbol->option_1 == 2) {
+ /* Add symbol linkage flag */
+ large_add_u64(&accum, 10000000000000);
+ }
+
+ /* Calculate left and right pair values */
+
+ right_pair = large_div_u64(&accum, 4537077);
+ left_pair = large_lo(&accum);
+
+ /* Calculate four data characters */
+
+ data_character[0] = left_pair / 1597;
+ data_character[1] = left_pair % 1597;
+
+ data_character[2] = right_pair / 1597;
+ data_character[3] = right_pair % 1597;
+
+ /* 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)) {
+ int count;
+ int check_digit;
+ char hrt[15];
+ 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 & 1)) {
+ count += 2 * (ctoi(hrt[i]));
+ }
+ }
+
+ check_digit = 10 - (count % 10);
+ if (check_digit == 10) {
+ check_digit = 0;
+ }
+ hrt[13] = itoc(check_digit);
+
+ strcat((char*) symbol->text, hrt);
+
+ set_minimum_height(symbol, 14); // Minimum height is 14X for truncated symbol
+ }
+
+ 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 = 1; 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);
+ }
+ }
+ }
+ unset_module(symbol, symbol->rows - 1, 1);
+ unset_module(symbol, symbol->rows - 1, 2);
+ unset_module(symbol, symbol->rows - 1, 3);
+ 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++;
+ }
+ latch = (latch == '1' ? '0' : '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;
+
+ set_minimum_height(symbol, 33);
+ }
+
+
+ return error_number;
+}
+
+/* GS1 DataBar Limited */
+INTERNAL int rsslimited(struct zint_symbol *symbol, unsigned char source[], int src_len) {
+ int error_number = 0, i;
+ large_int accum;
+ uint64_t left_character, right_character;
+ int left_group, right_group, left_odd, left_even, right_odd, right_even;
+ int left_widths[14], right_widths[14];
+ int checksum, check_elements[14], total_widths[46], writer, j, check_digit, count;
+ char latch, hrt[15];
+ int separator_row;
+
+ separator_row = 0;
+
+ if (src_len > 13) {
+ strcpy(symbol->errtxt, "382: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ error_number = is_sane(NEON, source, src_len);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "383: Invalid characters in data");
+ return error_number;
+ }
+ if (src_len == 13) {
+ if ((source[0] != '0') && (source[0] != '1')) {
+ strcpy(symbol->errtxt, "384: Input out of range");
+ return ZINT_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;
+ }
+
+ large_load_str_u64(&accum, source, src_len);
+
+ if (symbol->option_1 == 2) {
+ /* Add symbol linkage flag */
+ large_add_u64(&accum, 2015133531096);
+ }
+
+ /* Calculate left and right pair values */
+
+ right_character = large_div_u64(&accum, 2013571);
+ left_character = large_lo(&accum);
+
+ if (left_character >= 1996939) {
+ left_group = 6;
+ left_character -= 1996939;
+ } else if (left_character >= 1979845) {
+ left_group = 5;
+ left_character -= 1979845;
+ } else if (left_character >= 1491021) {
+ left_group = 4;
+ left_character -= 1491021;
+ } else if (left_character >= 1000776) {
+ left_group = 3;
+ left_character -= 1000776;
+ } else if (left_character >= 820064) {
+ left_group = 2;
+ left_character -= 820064;
+ } else if (left_character >= 183064) {
+ left_group = 1;
+ left_character -= 183064;
+ } else {
+ left_group = 0;
+ }
+
+ if (right_character >= 1996939) {
+ right_group = 6;
+ right_character -= 1996939;
+ } else if (right_character >= 1979845) {
+ right_group = 5;
+ right_character -= 1979845;
+ } else if (right_character >= 1491021) {
+ right_group = 4;
+ right_character -= 1491021;
+ } else if (right_character >= 1000776) {
+ right_group = 3;
+ right_character -= 1000776;
+ } else if (right_character >= 820064) {
+ right_group = 2;
+ right_character -= 820064;
+ } else if (right_character >= 183064) {
+ right_group = 1;
+ right_character -= 183064;
+ } else {
+ right_group = 0;
+ }
+
+ 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++;
+ }
+ latch = (latch == '1' ? '0' : '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 & 1)) {
+ 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';
+
+ strcat((char*) symbol->text, hrt);
+
+ set_minimum_height(symbol, 10);
+
+ return error_number;
+}
+
+/* Handles all data encodation from section 7.2.5 of ISO/IEC 24724 */
+static int rss_binary_string(struct zint_symbol *symbol, char source[], char binary_string[]) {
+ int encoding_method, i, j, read_posn, last_digit, debug = (symbol->debug & ZINT_DEBUG_PRINT), mode = NUMERIC;
+ int symbol_characters, characters_per_row;
+#ifndef _MSC_VER
+ char general_field[strlen(source) + 1];
+#else
+ char* general_field = (char*) _alloca(strlen(source) + 1);
+#endif
+ int remainder, d1, d2;
+ char padstring[40];
+
+ read_posn = 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 Method 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];
+
+ for (i = 0; i < 6; i++) {
+ weight_str[i] = source[20 + i];
+ }
+ weight_str[6] = '\0';
+
+ if (weight_str[0] == '0') { /* Maximum weight = 99999 */
+
+ if ((source[19] == '3') && (strlen(source) == 26)) {
+ /* (01) and (3103) */
+ float weight; /* In kilos */
+ 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];
+
+ for (i = 0; i < 6; i++) {
+ weight_str[i] = source[20 + i];
+ }
+ weight_str[6] = '\0';
+
+ if (weight_str[0] == '0') { /* Maximum weight = 99999 */
+
+ if (((source[19] == '2') || (source[19] == '3')) && (strlen(source) == 26)) {
+ /* (01) and (3202)/(3203) */
+ float weight; /* In pounds */
+
+ if (source[19] == '3') {
+ weight = (float) (atof(weight_str) / 1000.0F);
+ if (weight <= 22.767) {
+ encoding_method = 4;
+ }
+ } else {
+ weight = (float) (atof(weight_str) / 100.0F);
+ 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: strcat(binary_string, "1XX");
+ read_posn = 16;
+ break;
+ case 2: strcat(binary_string, "00XX");
+ read_posn = 0;
+ break;
+ case 3: // 0100
+ case 4: // 0101
+ bin_append(4 + (encoding_method - 3), 4, binary_string);
+ read_posn = strlen(source);
+ break;
+ case 5: strcat(binary_string, "01100XX");
+ read_posn = 20;
+ break;
+ case 6: strcat(binary_string, "01101XX");
+ read_posn = 23;
+ break;
+ default: /* modes 7 to 14 */
+ bin_append(56 + (encoding_method - 7), 7, binary_string);
+ 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, "385: Invalid characters in input data");
+ return ZINT_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];
+
+ group[0] = source[2];
+ group[1] = '\0';
+
+ bin_append(atoi(group), 4, binary_string);
+
+ 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';
+
+ bin_append(atoi(group), 10, binary_string);
+ }
+ }
+
+ if ((encoding_method == 3) || (encoding_method == 4)) {
+ /* Encoding method field "0100" - variable weight item
+ (0,001 kilogram icrements) */
+ /* Encoding method field "0101" - variable weight item (0,01 or
+ 0,001 pound increment) */
+ char group[4];
+ 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';
+
+ bin_append(atoi(group), 10, binary_string);
+ }
+
+ for (i = 0; i < 6; i++) {
+ weight_str[i] = source[20 + i];
+ }
+ weight_str[6] = '\0';
+
+ if ((encoding_method == 4) && (source[19] == '3')) {
+ bin_append(atoi(weight_str) + 10000, 15, binary_string);
+ } else {
+ bin_append(atoi(weight_str), 15, binary_string);
+ }
+ }
+
+ if ((encoding_method == 5) || (encoding_method == 6)) {
+ /* Encoding method "01100" - variable measure item and price */
+ /* Encoding method "01101" - variable measure item and price with ISO 4217
+ Currency Code */
+
+ char group[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';
+
+ bin_append(atoi(group), 10, binary_string);
+ }
+
+ bin_append(source[19] - '0', 2, binary_string);
+
+ if (encoding_method == 6) {
+ char currency_str[5];
+
+ for (i = 0; i < 3; i++) {
+ currency_str[i] = source[20 + i];
+ }
+ currency_str[3] = '\0';
+
+ bin_append(atoi(currency_str), 10, binary_string);
+ }
+ }
+
+ 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];
+
+ 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';
+
+ bin_append(atoi(group), 10, binary_string);
+ }
+
+ weight_str[0] = source[19];
+
+ for (i = 0; i < 5; i++) {
+ weight_str[i + 1] = source[21 + i];
+ }
+ weight_str[6] = '\0';
+
+ bin_append(atoi(weight_str), 20, binary_string);
+
+ if (strlen(source) == 34) {
+ /* Date information is included */
+ char date_str[4];
+ 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;
+ }
+
+ bin_append(group_val, 16, binary_string);
+ }
+
+ /* 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 < (int) strlen(source); i++) {
+ general_field[j] = source[i];
+ j++;
+ }
+ general_field[j] = '\0';
+ if (debug) printf("General field data = %s\n", general_field);
+
+ if (!general_field_encode(general_field, &mode, &last_digit, binary_string)) {
+ /* Invalid characters in input data */
+ strcpy(symbol->errtxt, "386: Invalid characters in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ 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;
+ }
+ symbol_characters = ((strlen(binary_string) + remainder) / 12) + 1;
+
+ if ((symbol->symbology == BARCODE_RSS_EXPSTACK) || (symbol->symbology == BARCODE_RSS_EXPSTACK_CC)) {
+ characters_per_row = symbol->option_2 * 2;
+
+ if ((characters_per_row < 2) || (characters_per_row > 20)) {
+ characters_per_row = 4;
+ }
+
+ if ((symbol_characters % characters_per_row) == 1) {
+ symbol_characters++;
+ }
+ }
+
+ if (symbol_characters < 4) {
+ symbol_characters = 4;
+ }
+
+ remainder = (12 * (symbol_characters - 1)) - strlen(binary_string);
+
+ if (last_digit) {
+ /* There is still one more numeric digit to encode */
+ if (debug) printf("Adding extra (odd) numeric digit\n");
+
+ if ((remainder >= 4) && (remainder <= 6)) {
+ bin_append(ctoi(last_digit) + 1, 4, binary_string);
+ } else {
+ d1 = ctoi(last_digit);
+ d2 = 10;
+
+ bin_append((11 * d1) + d2 + 8, 7, binary_string);
+ }
+
+ remainder = 12 - (strlen(binary_string) % 12);
+ if (remainder == 12) {
+ remainder = 0;
+ }
+ symbol_characters = ((strlen(binary_string) + remainder) / 12) + 1;
+
+ if ((symbol->symbology == BARCODE_RSS_EXPSTACK) || (symbol->symbology == BARCODE_RSS_EXPSTACK_CC)) {
+ characters_per_row = symbol->option_2 * 2;
+
+ if ((characters_per_row < 2) || (characters_per_row > 20)) {
+ characters_per_row = 4;
+ }
+
+ if ((symbol_characters % characters_per_row) == 1) {
+ symbol_characters++;
+ }
+ }
+
+ if (symbol_characters < 4) {
+ symbol_characters = 4;
+ }
+
+ remainder = (12 * (symbol_characters - 1)) - 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) { /* 252 = (21 * 12) */
+ strcpy(symbol->errtxt, "387: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ /* Now add padding to binary string (7.2.5.5.4) */
+ i = remainder;
+ if (mode == NUMERIC) {
+ strcpy(padstring, "0000");
+ i -= 4;
+ } else {
+ strcpy(padstring, "");
+ }
+ for (; i > 0; i -= 5) {
+ strcat(padstring, "00100");
+ }
+
+ padstring[remainder] = '\0';
+ strcat(binary_string, padstring);
+
+ /* Patch variable length symbol bit field */
+ d1 = symbol_characters & 1;
+
+ if (symbol_characters <= 14) {
+ d2 = 0;
+ } else {
+ d2 = 1;
+ }
+
+ if (encoding_method == 1) {
+ binary_string[2] = d1 ? '1' : '0';
+ binary_string[3] = d2 ? '1' : '0';
+ }
+ if (encoding_method == 2) {
+ binary_string[3] = d1 ? '1' : '0';
+ binary_string[4] = d2 ? '1' : '0';
+ }
+ if ((encoding_method == 5) || (encoding_method == 6)) {
+ binary_string[6] = d1 ? '1' : '0';
+ binary_string[7] = d2 ? '1' : '0';
+ }
+ if (debug) printf("Resultant binary = %s\n", binary_string);
+ if (debug) printf("\tLength: %d\n", (int) strlen(binary_string));
+ return 0;
+}
+
+/* GS1 DataBar Expanded */
+INTERNAL int rssexpanded(struct zint_symbol *symbol, unsigned char source[], int src_len) {
+ int i, j, k, p, 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 separator_row;
+ unsigned int bin_len = 13 * src_len + 200 + 1; /* Allow for 8 bits + 5-bit latch per char + 200 bits overhead/padding */
+#ifndef _MSC_VER
+ char reduced[src_len + 1], binary_string[bin_len];
+#else
+ char* reduced = (char*) _alloca(src_len + 1);
+ char* binary_string = (char*) _alloca(bin_len);
+#endif
+
+ separator_row = 0;
+ reader = 0;
+
+ 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) {
+ strcat(binary_string, "1");
+ } else {
+ strcat(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;
+ for (p = 0; p < 12; p++) {
+ if (substring[i][p] == '1') {
+ vs[i] += (0x800 >> p);
+ }
+ }
+ }
+
+ 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++) {
+ int 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) & 1)) * 5) + ((data_chars + 1) * 8) + 4;
+ for (i = 0; i < pattern_width; i++) {
+ elements[i] = 0;
+ }
+
+ /* Put finder patterns in element array */
+ for (i = 0; i < (((data_chars + 1) / 2) + ((data_chars + 1) & 1)); i++) {
+ k = ((((((data_chars + 1) - 2) / 2) + ((data_chars + 1) & 1)) - 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 */
+
+ elements[0] = 1; // left guard
+ elements[1] = 1;
+
+ elements[pattern_width - 2] = 1; // right guard
+ elements[pattern_width - 1] = 1;
+
+ 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 {
+ int stack_rows;
+ int current_row, current_block, left_to_right;
+ /* RSS Expanded Stacked */
+
+ /* Bug corrected: Character missing for message
+ * [01]90614141999996[10]1234222222222221
+ * Patch by Daniel Frede
+ */
+ int codeblocks = (data_chars + 1) / 2 + ((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++) {
+ int special_case_row = 0;
+ int elements_in_sub;
+ int sub_elements[235];
+ for (i = 0; i < 235; i++) {
+ sub_elements[i] = 0;
+ }
+
+ /* Row Start */
+ sub_elements[0] = 1; // left guard
+ sub_elements[1] = 1;
+ elements_in_sub = 2;
+
+ /* Row Data */
+ reader = 0;
+ do {
+ if (((symbol->option_2 & 1) || (current_row & 1)) ||
+ ((current_row == stack_rows) && (codeblocks != (current_row * symbol->option_2)) &&
+ (((current_row * symbol->option_2) - codeblocks) & 1))) {
+ /* left to right */
+ left_to_right = 1;
+ i = 2 + (current_block * 21);
+ for (j = 0; j < 21; j++) {
+ if ((i + j) < pattern_width) {
+ sub_elements[j + (reader * 21) + 2] = elements[i + j];
+ }
+ elements_in_sub++;
+ }
+ } else {
+ /* right to left */
+ left_to_right = 0;
+ i = 2 + (((current_row * symbol->option_2) - reader - 1) * 21);
+ for (j = 0; j < 21; j++) {
+ if ((i + j) < pattern_width) {
+ 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; // right guard
+ sub_elements[elements_in_sub + 1] = 1;
+ elements_in_sub += 2;
+
+ latch = (current_row & 1) ? '0' : '1';
+
+ if ((current_row == stack_rows) && (codeblocks != (current_row * symbol->option_2)) &&
+ ((current_row & 1) == 0) && ((symbol->option_2 & 1) == 0)) {
+ /* 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 + special_case_row; 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 + special_case_row;
+ 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 {
+ if ((current_row == stack_rows) && (data_chars % 2 == 0)) {
+ k -= 18;
+ }
+ 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);
+ }
+ }
+ }
+ }
+
+ }
+
+ for (i = 0; i < symbol->rows; i++) {
+ if (symbol->row_height[i] == 0) {
+ symbol->row_height[i] = 34;
+ }
+ }
+
+ return 0;
+}
diff --git a/backend/rss.h b/backend/rss.h
new file mode 100644
index 0000000..d6c1fb9
--- /dev/null
+++ b/backend/rss.h
@@ -0,0 +1,293 @@
+/* rss.h - Data tables for Reduced Space Symbology */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2007-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/* RSS-14 Tables */
+static const unsigned short int g_sum_table[9] = {
+ 0, 161, 961, 2015, 2715, 0, 336, 1036, 1516
+};
+
+static const char t_table[9] = {
+ 1, 10, 34, 70, 126, 4, 20, 48, 81
+};
+
+static const char modules_odd[9] = {
+ 12, 10, 8, 6, 4, 5, 7, 9, 11
+};
+
+static const char modules_even[9] = {
+ 4, 6, 8, 10, 12, 10, 8, 6, 4
+};
+
+static const char widest_odd[9] = {
+ 8, 6, 4, 3, 1, 2, 4, 6, 8
+};
+
+static const char widest_even[9] = {
+ 1, 3, 5, 6, 8, 7, 5, 3, 1
+};
+
+static int widths[8];
+static const char 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 const char 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 const unsigned short int t_even_ltd[7] = {
+ 28, 728, 6454, 203, 2408, 1, 16632
+};
+
+static const char modules_odd_ltd[7] = {
+ 17, 13, 9, 15, 11, 19, 7
+};
+
+static const char modules_even_ltd[7] = {
+ 9, 13, 17, 11, 15, 7, 19
+};
+
+static const char widest_odd_ltd[7] = {
+ 6, 5, 3, 5, 4, 8, 1
+};
+
+static const char widest_even_ltd[7] = {
+ 3, 4, 6, 4, 5, 1, 8
+};
+
+static const char 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 const char finder_pattern_ltd[1246] = {
+ 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,
+ 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1
+};
+
+/* RSS Expanded Tables */
+static const unsigned short int g_sum_exp[5] = {
+ 0, 348, 1388, 2948, 3988
+};
+
+static const unsigned short int t_even_exp[5] = {
+ 4, 20, 52, 104, 204
+};
+
+static const char modules_odd_exp[5] = {
+ 12, 10, 8, 6, 4
+};
+
+static const char modules_even_exp[5] = {
+ 5, 7, 9, 11, 13
+};
+
+static const char widest_odd_exp[5] = {
+ 7, 5, 4, 3, 1
+};
+
+static const char widest_even_exp[5] = {
+ 2, 4, 5, 6, 8
+};
+
+static const unsigned short 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 const char 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 const char 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 const char 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.c b/backend/sjis.c
new file mode 100644
index 0000000..daa8aae
--- /dev/null
+++ b/backend/sjis.c
@@ -0,0 +1,1591 @@
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008-2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+/*
+ * Adapted from the GNU LIBICONV library and patched to make compatible with
+ * https://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/JIS/SHIFTJIS.TXT
+ * with the exception of one duplicate mapping to reverse solidus 0x815F
+ * and the mapping of user-defined PUA codepoints U+E000..E757.
+ */
+/*
+ * Copyright (C) 1999-2002, 2016 Free Software Foundation, Inc.
+ * This file is part of the GNU LIBICONV Library.
+ *
+ * The GNU LIBICONV Library is free software; you can redistribute it
+ * and/or modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * The GNU LIBICONV Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with the GNU LIBICONV Library; see the file COPYING.LIB.
+ * If not, see <https://www.gnu.org/licenses/>.
+ */
+#include <string.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+#include "common.h"
+#include "sjis.h"
+
+INTERNAL int utf_to_eci(const int eci, const unsigned char source[], unsigned char dest[], size_t *length); /* Convert Unicode to other encodings */
+
+/*
+ * JISX0201.1976-0 (libiconv-1.16/lib/jisx0201.h)
+ */
+
+static int jisx0201_wctomb(unsigned int* r, unsigned int wc) {
+ if (wc < 0x0080 && !(wc == 0x005c || wc == 0x007e)) {
+ *r = wc;
+ return 1;
+ }
+ if (wc == 0x00a5) {
+ *r = 0x5c;
+ return 1;
+ }
+ if (wc == 0x203e) {
+ *r = 0x7e;
+ return 1;
+ }
+ if (wc >= 0xff61 && wc < 0xffa0) {
+ *r = wc - 0xfec0;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * JISX0208.1990-0 (libiconv-1.16/lib/jisx0208.h)
+ */
+
+/* ZINT: Table converted from JIS X 0208 to Shift JIS values using tools/cnv_sjis.php:
+ *
+while ($line = fgets(STDIN)) {
+ echo preg_replace_callback('/0x([0-9a-f]{4})/', function ($matches) {
+ $dec = hexdec($matches[1]);
+ $c1 = $dec >> 8;
+ $c2 = ($dec & 0xFF);
+ $t1 = ($c1 - 0x21) >> 1;
+ $t2 = ((($c1 - 0x21) & 1) ? 0x5e : 0) + ($c2 - 0x21);
+ $r = (($t1 < 0x1f ? ($t1 + 0x81) : ($t1 + 0xc1)) << 8) | ($t2 < 0x3f ? ($t2 + 0x40) : ($t2 + 0x41));
+ return '0x' . dechex($r);
+ }, $line);
+}
+ */
+static const unsigned short jisx0208_2charset[6879] = {
+ 0x8191, 0x8192, 0x8198, 0x814e, 0x81ca, 0x818b, 0x817d, 0x814c,
+ 0x81f7, 0x817e, 0x8180, 0x839f, 0x83a0, 0x83a1, 0x83a2, 0x83a3,
+ 0x83a4, 0x83a5, 0x83a6, 0x83a7, 0x83a8, 0x83a9, 0x83aa, 0x83ab,
+ 0x83ac, 0x83ad, 0x83ae, 0x83af, 0x83b0, 0x83b1, 0x83b2, 0x83b3,
+ 0x83b4, 0x83b5, 0x83b6, 0x83bf, 0x83c0, 0x83c1, 0x83c2, 0x83c3,
+ 0x83c4, 0x83c5, 0x83c6, 0x83c7, 0x83c8, 0x83c9, 0x83ca, 0x83cb,
+ 0x83cc, 0x83cd, 0x83ce, 0x83cf, 0x83d0, 0x83d1, 0x83d2, 0x83d3,
+ 0x83d4, 0x83d5, 0x83d6, 0x8446, 0x8440, 0x8441, 0x8442, 0x8443,
+ 0x8444, 0x8445, 0x8447, 0x8448, 0x8449, 0x844a, 0x844b, 0x844c,
+ 0x844d, 0x844e, 0x844f, 0x8450, 0x8451, 0x8452, 0x8453, 0x8454,
+ 0x8455, 0x8456, 0x8457, 0x8458, 0x8459, 0x845a, 0x845b, 0x845c,
+ 0x845d, 0x845e, 0x845f, 0x8460, 0x8470, 0x8471, 0x8472, 0x8473,
+ 0x8474, 0x8475, 0x8477, 0x8478, 0x8479, 0x847a, 0x847b, 0x847c,
+ 0x847d, 0x847e, 0x8480, 0x8481, 0x8482, 0x8483, 0x8484, 0x8485,
+ 0x8486, 0x8487, 0x8488, 0x8489, 0x848a, 0x848b, 0x848c, 0x848d,
+ 0x848e, 0x848f, 0x8490, 0x8491, 0x8476, 0x815d, 0x815c, 0x8161,
+ 0x8165, 0x8166, 0x8167, 0x8168, 0x81f5, 0x81f6, 0x8164, 0x8163,
+ 0x81f1, 0x818c, 0x818d, 0x81a6, 0x818e, 0x81f0, 0x81a9, 0x81aa,
+ 0x81a8, 0x81ab, 0x81cb, 0x81cc, 0x81cd, 0x81dd, 0x81ce, 0x81de,
+ 0x81b8, 0x81b9, 0x817c, 0x81e3, 0x81e5, 0x8187, 0x81da, 0x81c8,
+ 0x81c9, 0x81bf, 0x81be, 0x81e7, 0x81e8, 0x8188, 0x81e6, 0x81e4,
+ 0x81e0, 0x8182, 0x81df, 0x8185, 0x8186, 0x81e1, 0x81e2, 0x81bc,
+ 0x81bd, 0x81ba, 0x81bb, 0x81db, 0x81dc, 0x849f, 0x84aa, 0x84a0,
+ 0x84ab, 0x84a1, 0x84ac, 0x84a2, 0x84ad, 0x84a4, 0x84af, 0x84a3,
+ 0x84ae, 0x84a5, 0x84ba, 0x84b5, 0x84b0, 0x84a7, 0x84bc, 0x84b7,
+ 0x84b2, 0x84a6, 0x84b6, 0x84bb, 0x84b1, 0x84a8, 0x84b8, 0x84bd,
+ 0x84b3, 0x84a9, 0x84b9, 0x84be, 0x84b4, 0x81a1, 0x81a0, 0x81a3,
+ 0x81a2, 0x81a5, 0x81a4, 0x819f, 0x819e, 0x819b, 0x819d, 0x819c,
+ 0x81fc, 0x819a, 0x8199, 0x818a, 0x8189, 0x81f4, 0x81f3, 0x81f2,
+ 0x8140, 0x8141, 0x8142, 0x8156, 0x8158, 0x8159, 0x815a, 0x8171,
+ 0x8172, 0x8173, 0x8174, 0x8175, 0x8176, 0x8177, 0x8178, 0x8179,
+ 0x817a, 0x81a7, 0x81ac, 0x816b, 0x816c, 0x8160, 0x829f, 0x82a0,
+ 0x82a1, 0x82a2, 0x82a3, 0x82a4, 0x82a5, 0x82a6, 0x82a7, 0x82a8,
+ 0x82a9, 0x82aa, 0x82ab, 0x82ac, 0x82ad, 0x82ae, 0x82af, 0x82b0,
+ 0x82b1, 0x82b2, 0x82b3, 0x82b4, 0x82b5, 0x82b6, 0x82b7, 0x82b8,
+ 0x82b9, 0x82ba, 0x82bb, 0x82bc, 0x82bd, 0x82be, 0x82bf, 0x82c0,
+ 0x82c1, 0x82c2, 0x82c3, 0x82c4, 0x82c5, 0x82c6, 0x82c7, 0x82c8,
+ 0x82c9, 0x82ca, 0x82cb, 0x82cc, 0x82cd, 0x82ce, 0x82cf, 0x82d0,
+ 0x82d1, 0x82d2, 0x82d3, 0x82d4, 0x82d5, 0x82d6, 0x82d7, 0x82d8,
+ 0x82d9, 0x82da, 0x82db, 0x82dc, 0x82dd, 0x82de, 0x82df, 0x82e0,
+ 0x82e1, 0x82e2, 0x82e3, 0x82e4, 0x82e5, 0x82e6, 0x82e7, 0x82e8,
+ 0x82e9, 0x82ea, 0x82eb, 0x82ec, 0x82ed, 0x82ee, 0x82ef, 0x82f0,
+ 0x82f1, 0x814a, 0x814b, 0x8154, 0x8155, 0x8340, 0x8341, 0x8342,
+ 0x8343, 0x8344, 0x8345, 0x8346, 0x8347, 0x8348, 0x8349, 0x834a,
+ 0x834b, 0x834c, 0x834d, 0x834e, 0x834f, 0x8350, 0x8351, 0x8352,
+ 0x8353, 0x8354, 0x8355, 0x8356, 0x8357, 0x8358, 0x8359, 0x835a,
+ 0x835b, 0x835c, 0x835d, 0x835e, 0x835f, 0x8360, 0x8361, 0x8362,
+ 0x8363, 0x8364, 0x8365, 0x8366, 0x8367, 0x8368, 0x8369, 0x836a,
+ 0x836b, 0x836c, 0x836d, 0x836e, 0x836f, 0x8370, 0x8371, 0x8372,
+ 0x8373, 0x8374, 0x8375, 0x8376, 0x8377, 0x8378, 0x8379, 0x837a,
+ 0x837b, 0x837c, 0x837d, 0x837e, 0x8380, 0x8381, 0x8382, 0x8383,
+ 0x8384, 0x8385, 0x8386, 0x8387, 0x8388, 0x8389, 0x838a, 0x838b,
+ 0x838c, 0x838d, 0x838e, 0x838f, 0x8390, 0x8391, 0x8392, 0x8393,
+ 0x8394, 0x8395, 0x8396, 0x8145, 0x815b, 0x8152, 0x8153, 0x88ea,
+ 0x929a, 0x8eb5, 0x969c, 0x8fe4, 0x8e4f, 0x8fe3, 0x89ba, 0x9573,
+ 0x975e, 0x98a0, 0x894e, 0x8a8e, 0x98a1, 0x90a2, 0x99c0, 0x8b75,
+ 0x95b8, 0x8fe5, 0x97bc, 0x95c0, 0x98a2, 0x9286, 0x98a3, 0x8bf8,
+ 0x98a4, 0x8adb, 0x924f, 0x8ee5, 0x98a5, 0x98a6, 0x98a7, 0x9454,
+ 0x8b76, 0x9456, 0x93e1, 0x8cc1, 0x9652, 0xe568, 0x98a8, 0x8fe6,
+ 0x98a9, 0x89b3, 0x8be3, 0x8cee, 0x96e7, 0x9ba4, 0x9790, 0x93fb,
+ 0x8aa3, 0x8b54, 0x98aa, 0x98ab, 0x97b9, 0x975c, 0x9188, 0x98ad,
+ 0x8e96, 0x93f1, 0x98b0, 0x895d, 0x8cdd, 0x8cdc, 0x88e4, 0x986a,
+ 0x9869, 0x8db1, 0x889f, 0x98b1, 0x98b2, 0x98b3, 0x9653, 0x98b4,
+ 0x8cf0, 0x88e5, 0x9692, 0x8b9c, 0x8b9d, 0x8b9e, 0x92e0, 0x97ba,
+ 0x98b5, 0x98b6, 0x98b7, 0x906c, 0x8f59, 0x906d, 0x98bc, 0x98ba,
+ 0x98bb, 0x8b77, 0x8da1, 0x89ee, 0x98b9, 0x98b8, 0x95a7, 0x8e65,
+ 0x8e64, 0x91bc, 0x98bd, 0x9574, 0x90e5, 0x8157, 0x98be, 0x98c0,
+ 0x91e3, 0x97df, 0x88c8, 0x98bf, 0x89bc, 0x8bc2, 0x9287, 0x8c8f,
+ 0x98c1, 0x9443, 0x8ae9, 0x98c2, 0x88c9, 0x8cde, 0x8aea, 0x959a,
+ 0x94b0, 0x8b78, 0x89ef, 0x98e5, 0x9360, 0x948c, 0x98c4, 0x94ba,
+ 0x97e0, 0x904c, 0x8e66, 0x8e97, 0x89be, 0x92cf, 0x9241, 0x98c8,
+ 0x88ca, 0x92e1, 0x8f5a, 0x8db2, 0x9743, 0x91cc, 0x89bd, 0x98c7,
+ 0x975d, 0x98c3, 0x98c5, 0x8dec, 0x98c6, 0x9b43, 0x98ce, 0x98d1,
+ 0x98cf, 0x89c0, 0x95b9, 0x98c9, 0x98cd, 0x8cf1, 0x8e67, 0x8aa4,
+ 0x98d2, 0x98ca, 0x97e1, 0x8e98, 0x98cb, 0x98d0, 0x98d3, 0x98cc,
+ 0x8b9f, 0x88cb, 0x8ba0, 0x89bf, 0x9b44, 0x9699, 0x958e, 0x8cf2,
+ 0x904e, 0x97b5, 0x95d6, 0x8c57, 0x91a3, 0x89e2, 0x8f72, 0x98d7,
+ 0x98dc, 0x98da, 0x98d5, 0x91ad, 0x98d8, 0x98db, 0x98d9, 0x95db,
+ 0x98d6, 0x904d, 0x9693, 0x98dd, 0x98de, 0x8f43, 0x98eb, 0x946f,
+ 0x9555, 0x98e6, 0x95ee, 0x89b4, 0x98ea, 0x98e4, 0x98ed, 0x9171,
+ 0x8cc2, 0x947b, 0xe0c5, 0x98ec, 0x937c, 0x98e1, 0x8cf4, 0x8cf3,
+ 0x98df, 0x8ed8, 0x98e7, 0x95ed, 0x926c, 0x98e3, 0x8c91, 0x98e0,
+ 0x98e8, 0x98e2, 0x97cf, 0x98e9, 0x9860, 0x8be4, 0x8c90, 0x98ee,
+ 0x98ef, 0x98f3, 0x88cc, 0x95ce, 0x98f2, 0x98f1, 0x98f5, 0x98f4,
+ 0x92e2, 0x8c92, 0x98f6, 0x8ec3, 0x91a4, 0x92e3, 0x8bf4, 0x98f7,
+ 0x8b55, 0x98f8, 0x98fa, 0x9654, 0x8c86, 0x8e50, 0x94f5, 0x98f9,
+ 0x8dc3, 0x9762, 0x98fc, 0x9942, 0x98fb, 0x8dc2, 0x8f9d, 0x8c58,
+ 0x9943, 0x8bcd, 0x9940, 0x9941, 0x93ad, 0x919c, 0x8ba1, 0x966c,
+ 0x9944, 0x97bb, 0x9945, 0x9948, 0x9946, 0x916d, 0x9947, 0x9949,
+ 0x994b, 0x994a, 0x95c6, 0x8b56, 0x994d, 0x994e, 0x89ad, 0x994c,
+ 0x8ef2, 0x9951, 0x9950, 0x994f, 0x98d4, 0x9952, 0x8f9e, 0x9953,
+ 0x9744, 0x96d7, 0x9955, 0x9954, 0x9957, 0x9956, 0x9958, 0x9959,
+ 0x88f2, 0x8cb3, 0x8c5a, 0x8f5b, 0x929b, 0x8ba2, 0x90e6, 0x8cf5,
+ 0x8d8e, 0x995b, 0x96c6, 0x9365, 0x8e99, 0x995a, 0x995c, 0x937d,
+ 0x8a95, 0x995d, 0x93fc, 0x9153, 0x995f, 0x9960, 0x94aa, 0x8cf6,
+ 0x985a, 0x9961, 0x8ba4, 0x95ba, 0x91b4, 0x8bef, 0x9354, 0x8c93,
+ 0x9962, 0x9963, 0x93e0, 0x897e, 0x9966, 0x8dfb, 0x9965, 0x8dc4,
+ 0x9967, 0xe3ec, 0x9968, 0x9660, 0x9969, 0x996a, 0x996b, 0x8fe7,
+ 0x8eca, 0x8aa5, 0x996e, 0x996c, 0x96bb, 0x996d, 0x9579, 0x996f,
+ 0x9970, 0x9971, 0x937e, 0x9975, 0x9973, 0x9974, 0x9972, 0x8de1,
+ 0x9976, 0x96e8, 0x97e2, 0x9977, 0x90a6, 0x9978, 0x8f79, 0x9979,
+ 0x929c, 0x97bd, 0x9380, 0x99c3, 0x997a, 0xeaa3, 0x8bc3, 0x997b,
+ 0x967d, 0x8f88, 0x91fa, 0x997d, 0x93e2, 0x997e, 0x9980, 0x8a4d,
+ 0x9981, 0x8ba5, 0x93ca, 0x899a, 0x8f6f, 0x949f, 0x9982, 0x9381,
+ 0x906e, 0x9983, 0x95aa, 0x90d8, 0x8aa0, 0x8aa7, 0x9984, 0x9986,
+ 0x8c59, 0x9985, 0x97f1, 0x8f89, 0x94bb, 0x95ca, 0x9987, 0x9798,
+ 0x9988, 0x9989, 0x939e, 0x998a, 0x90a7, 0x8dfc, 0x8c94, 0x998b,
+ 0x8e68, 0x8d8f, 0x92e4, 0x998d, 0x91a5, 0x8ded, 0x998e, 0x998f,
+ 0x914f, 0x998c, 0x9991, 0x9655, 0x8d84, 0x9990, 0x8c95, 0x8ddc,
+ 0x948d, 0x9994, 0x9992, 0x959b, 0x8fe8, 0x999b, 0x8a84, 0x9995,
+ 0x9993, 0x916e, 0x9997, 0x9996, 0x8a63, 0x8c80, 0x999c, 0x97ab,
+ 0x9998, 0x999d, 0x999a, 0x9999, 0x97cd, 0x8cf7, 0x89c1, 0x97f2,
+ 0x8f95, 0x9377, 0x8d85, 0x99a0, 0x99a1, 0x97e3, 0x984a, 0x99a3,
+ 0x8cf8, 0x99a2, 0x8a4e, 0x99a4, 0x9675, 0x92ba, 0x9745, 0x95d7,
+ 0x99a5, 0xe8d3, 0x93ae, 0x99a6, 0x8aa8, 0x96b1, 0x8f9f, 0x99a7,
+ 0x95e5, 0x99ab, 0x90a8, 0x99a8, 0x8bce, 0x99a9, 0x8aa9, 0x8c4d,
+ 0x99ac, 0x99ad, 0x99ae, 0x99af, 0x8ed9, 0x8cf9, 0x96dc, 0x96e6,
+ 0x93f5, 0x95ef, 0x99b0, 0x99b1, 0x99b3, 0x99b5, 0x99b4, 0x99b6,
+ 0x89bb, 0x966b, 0x8dfa, 0x99b7, 0x9178, 0x8fa0, 0x8ba7, 0x99b8,
+ 0x94d9, 0x99b9, 0x99ba, 0x99bb, 0x99bc, 0x9543, 0x8be6, 0x88e3,
+ 0x93bd, 0x99bd, 0x8f5c, 0x90e7, 0x99bf, 0x99be, 0x8fa1, 0x8cdf,
+ 0x99c1, 0x94bc, 0x99c2, 0x94da, 0x91b2, 0x91ec, 0x8ba6, 0x93ec,
+ 0x9250, 0x948e, 0x966d, 0x99c4, 0x90e8, 0x8c54, 0x99c5, 0x99c6,
+ 0x894b, 0x88f3, 0x8aeb, 0x91a6, 0x8b70, 0x9791, 0x99c9, 0x89b5,
+ 0x99c8, 0x8ba8, 0x99ca, 0x96ef, 0x99cb, 0x97d0, 0x8cfa, 0x8cb4,
+ 0x99cc, 0x99ce, 0x99cd, 0x907e, 0x8958, 0x897d, 0x99cf, 0x99d0,
+ 0x8cb5, 0x99d1, 0x8b8e, 0x8e51, 0x99d2, 0x9694, 0x8db3, 0x8b79,
+ 0x9746, 0x916f, 0x94bd, 0x8efb, 0x8f66, 0x8ee6, 0x8ef3, 0x8f96,
+ 0x94be, 0x99d5, 0x8962, 0x9170, 0x8cfb, 0x8cc3, 0x8be5, 0x99d9,
+ 0x9240, 0x91fc, 0x8ba9, 0x8fa2, 0x99da, 0x99d8, 0x89c2, 0x91e4,
+ 0x8eb6, 0x8e6a, 0x8945, 0x8a90, 0x8d86, 0x8e69, 0x99db, 0x99dc,
+ 0x8b68, 0x8a65, 0x8d87, 0x8b67, 0x92dd, 0x8944, 0x93af, 0x96bc,
+ 0x8d40, 0x9799, 0x9366, 0x8cfc, 0x8c4e, 0x99e5, 0x8be1, 0x9669,
+ 0x94db, 0x99e4, 0x8adc, 0x99df, 0x99e0, 0x99e2, 0x99e3, 0x8b7a,
+ 0x9081, 0x95ab, 0x99e1, 0x99dd, 0x8ce1, 0x99de, 0x9843, 0x95f0,
+ 0x92e6, 0x8ce0, 0x8d90, 0x99e6, 0x93db, 0x99ea, 0x8efc, 0x8ef4,
+ 0x99ed, 0x99eb, 0x96a1, 0x99e8, 0x99f1, 0x99ec, 0x99ef, 0x8cc4,
+ 0x96bd, 0x99f0, 0x99f2, 0x99f4, 0x8dee, 0x9861, 0x99e9, 0x99e7,
+ 0x99f3, 0x99ee, 0x99f6, 0x9a42, 0x99f8, 0x99fc, 0x9a40, 0x99f9,
+ 0x9a5d, 0x8de7, 0x8a50, 0x99f7, 0x9a44, 0x88f4, 0x9a43, 0x88a3,
+ 0x9569, 0x9a41, 0x99fa, 0x99f5, 0x99fb, 0x8dc6, 0x9a45, 0x88f5,
+ 0x9a4e, 0x9a46, 0x9a47, 0x8fa3, 0x9689, 0x9a4c, 0x9a4b, 0x934e,
+ 0x9a4d, 0x9a4a, 0x8953, 0x8db4, 0x904f, 0x9a48, 0x9382, 0x9a49,
+ 0x88a0, 0x9a53, 0x9742, 0x8fa5, 0x9a59, 0x9a58, 0x9a4f, 0x91c1,
+ 0x9a50, 0x91ed, 0x9a55, 0x8fa4, 0x9a52, 0x96e2, 0x8c5b, 0x9a56,
+ 0x9a57, 0x9a54, 0x9a5a, 0x9a51, 0x9a60, 0x9a65, 0x9a61, 0x9a5c,
+ 0x9a66, 0x9150, 0x9a68, 0x8d41, 0x9a5e, 0x929d, 0x9a62, 0x9a5b,
+ 0x8aab, 0x8aec, 0x8a85, 0x9a63, 0x9a5f, 0x8c96, 0x9a69, 0x9a67,
+ 0x9172, 0x8b69, 0x8baa, 0x9a64, 0x8bf2, 0x8963, 0x9a6d, 0x9a6b,
+ 0x9aa5, 0x9a70, 0x9a6a, 0x9a6e, 0x9a6c, 0x8e6b, 0x9a6f, 0x9a72,
+ 0x9a77, 0x9a75, 0x9a74, 0x9251, 0x89c3, 0x9a71, 0x9a73, 0x8fa6,
+ 0x8952, 0x9a76, 0x89dc, 0x9a82, 0x8ffa, 0x9a7d, 0x9a7b, 0x9a7c,
+ 0x9a7e, 0x895c, 0x9158, 0x9a78, 0x9a79, 0x8a9a, 0x9a81, 0x8aed,
+ 0x9a84, 0x9a80, 0x9a83, 0x95ac, 0x93d3, 0x94b6, 0x9a86, 0x9a85,
+ 0x8a64, 0x9a87, 0x9a8a, 0x9a89, 0x9a88, 0x9458, 0x9a8b, 0x9a8c,
+ 0x9a8e, 0x9a8d, 0x9a90, 0x9a93, 0x9a91, 0x9a8f, 0x9a92, 0x9a94,
+ 0x9a95, 0x9a96, 0x9a97, 0x9a98, 0x9964, 0x8efa, 0x8e6c, 0x89f1,
+ 0x88f6, 0x9263, 0x9a99, 0x8da2, 0x88cd, 0x907d, 0x9a9a, 0x8cc5,
+ 0x8d91, 0x9a9c, 0x9a9b, 0x95de, 0x9a9d, 0x9a9f, 0x9a9e, 0x9aa0,
+ 0x9aa1, 0x8c97, 0x8980, 0x9aa2, 0x9aa4, 0x9aa3, 0x9aa6, 0x9379,
+ 0x9aa7, 0x88b3, 0x8ddd, 0x8c5c, 0x926e, 0x9aa8, 0x9aa9, 0x9aab,
+ 0x9aac, 0x8de2, 0x8bcf, 0x9656, 0x9aaa, 0x9aad, 0x8dbf, 0x8d42,
+ 0x9ab1, 0x8da3, 0x9252, 0x9aae, 0x92d8, 0x9ab2, 0x9082, 0x9ab0,
+ 0x9ab3, 0x8c5e, 0x9ab4, 0x9ab5, 0x8d43, 0x8a5f, 0x9ab7, 0x9ab8,
+ 0x9ab9, 0x9ab6, 0x9aaf, 0x9aba, 0x9abb, 0x9684, 0x8fe9, 0x9abd,
+ 0x9abe, 0x9abc, 0x9ac0, 0x9457, 0x88e6, 0x9575, 0x9ac1, 0x8ffb,
+ 0x8eb7, 0x947c, 0x8aee, 0x8de9, 0x9678, 0x93b0, 0x8c98, 0x91cd,
+ 0x9abf, 0x9ac2, 0x91c2, 0x9ac3, 0x9ac4, 0x9ac6, 0x92e7, 0x8aac,
+ 0xea9f, 0x8981, 0x95f1, 0x8fea, 0x9367, 0x8de4, 0x9acc, 0x95bb,
+ 0x97db, 0x89f2, 0x9ac8, 0x9159, 0x9acb, 0x9383, 0x9368, 0x9384,
+ 0x94b7, 0x92cb, 0x8dc7, 0x9ac7, 0x8996, 0x9355, 0x9ac9, 0x9ac5,
+ 0x906f, 0x9acd, 0x8f6d, 0x8bab, 0x9ace, 0x95e6, 0x919d, 0x92c4,
+ 0x9ad0, 0x966e, 0x9ad1, 0x9ad6, 0x95ad, 0x9ad5, 0x9acf, 0x9ad2,
+ 0x9ad4, 0x8da4, 0x95c7, 0x9ad7, 0x9264, 0x89f3, 0x8feb, 0x9ad9,
+ 0x9ad8, 0x8d88, 0x9ada, 0x9adc, 0x9adb, 0x9ade, 0x9ad3, 0x9ae0,
+ 0x9adf, 0x9add, 0x8e6d, 0x9070, 0x9173, 0x9ae1, 0x90ba, 0x88eb,
+ 0x9484, 0x92d9, 0x9ae3, 0x9ae2, 0x9ae4, 0x9ae5, 0x9ae6, 0x9ae7,
+ 0x95cf, 0x9ae8, 0x89c4, 0x9ae9, 0x975b, 0x8a4f, 0x99c7, 0x8f67,
+ 0x91bd, 0x9aea, 0x96e9, 0x96b2, 0x9aec, 0x91e5, 0x9356, 0x91be,
+ 0x9576, 0x9aed, 0x9aee, 0x899b, 0x8eb8, 0x9aef, 0x88ce, 0x9af0,
+ 0x9af1, 0x8982, 0x8aef, 0x93de, 0x95f2, 0x9af5, 0x9174, 0x9af4,
+ 0x8c5f, 0x967a, 0x9af3, 0x9385, 0x9af7, 0x9af6, 0x9af9, 0x9af8,
+ 0x899c, 0x9afa, 0x8fa7, 0x9afc, 0x9244, 0x9afb, 0x95b1, 0x8f97,
+ 0x937a, 0x9b40, 0x8d44, 0x9b41, 0x9440, 0x94dc, 0x96cf, 0x9444,
+ 0x9b4a, 0x8b57, 0x9764, 0x96ad, 0x9baa, 0x9b42, 0x9b45, 0x91c3,
+ 0x9657, 0x9369, 0x9b46, 0x9685, 0x8dc8, 0x8fa8, 0x9b47, 0x8e6f,
+ 0x8e6e, 0x88b7, 0x8cc6, 0x90a9, 0x88cf, 0x9b4b, 0x9b4c, 0x9b49,
+ 0x8957, 0x8aad, 0x9b48, 0x96c3, 0x9550, 0x88a6, 0x88f7, 0x8e70,
+ 0x88d0, 0x88a1, 0x9b51, 0x9b4f, 0x96ba, 0x9b52, 0x9b50, 0x9b4e,
+ 0x9050, 0x9b4d, 0x95d8, 0x8ce2, 0x9b56, 0x9b57, 0x8fa9, 0x9b53,
+ 0x984b, 0x946b, 0x9b55, 0x8da5, 0x9b58, 0x9577, 0x9b59, 0x9b54,
+ 0x96b9, 0x947d, 0x9b5a, 0x9551, 0x9b5b, 0x9b5f, 0x9b5c, 0x89c5,
+ 0x9b5e, 0x8eb9, 0x9b5d, 0x8c99, 0x9b6b, 0x9b64, 0x9b61, 0x9284,
+ 0x9b60, 0x9b62, 0x9b63, 0x9b65, 0x9b66, 0x8af0, 0x9b68, 0x9b67,
+ 0x9b69, 0x8fec, 0x9b6c, 0x92da, 0x8964, 0x9b6a, 0x9b6d, 0x9b6e,
+ 0x9b71, 0x9b6f, 0x9b70, 0x8e71, 0x9b72, 0x8d45, 0x9b73, 0x8e9a,
+ 0x91b6, 0x9b74, 0x9b75, 0x8e79, 0x8d46, 0x96d0, 0x8b47, 0x8cc7,
+ 0x9b76, 0x8a77, 0x9b77, 0x91b7, 0x9b78, 0x9ba1, 0x9b79, 0x9b7a,
+ 0x9b7b, 0x9b7d, 0x9b7e, 0x9b80, 0x91ee, 0x8946, 0x8ee7, 0x88c0,
+ 0x9176, 0x8aae, 0x8eb3, 0x8d47, 0x9386, 0x8f40, 0x8aaf, 0x9288,
+ 0x92e8, 0x88b6, 0x8b58, 0x95f3, 0x8ec0, 0x8b71, 0x90e9, 0x8eba,
+ 0x9747, 0x9b81, 0x8b7b, 0x8dc9, 0x8a51, 0x8983, 0x8faa, 0x89c6,
+ 0x9b82, 0x9765, 0x8f68, 0x8ee2, 0x9b83, 0x8af1, 0x93d0, 0x96a7,
+ 0x9b84, 0x9b85, 0x9578, 0x9b87, 0x8aa6, 0x8bf5, 0x9b86, 0x8ab0,
+ 0x9051, 0x9b8b, 0x8e40, 0x89c7, 0x9b8a, 0x9b88, 0x9b8c, 0x9b89,
+ 0x944a, 0x9ecb, 0x9052, 0x9b8d, 0x97be, 0x9b8e, 0x9b90, 0x929e,
+ 0x9b8f, 0x90a1, 0x8e9b, 0x91ce, 0x8ef5, 0x9595, 0x90ea, 0x8ecb,
+ 0x9b91, 0x8fab, 0x9b92, 0x9b93, 0x88d1, 0x91b8, 0x9071, 0x9b94,
+ 0x93b1, 0x8fac, 0x8fad, 0x9b95, 0x90eb, 0x8fae, 0x9b96, 0x9b97,
+ 0x96de, 0x9b98, 0x8bc4, 0x8f41, 0x9b99, 0x9b9a, 0x8eda, 0x904b,
+ 0x93f2, 0x9073, 0x94f6, 0x9441, 0x8bc7, 0x9b9b, 0x8b8f, 0x9b9c,
+ 0x8bfc, 0x93cd, 0x89ae, 0x8e72, 0x9b9d, 0x9ba0, 0x9b9f, 0x8bfb,
+ 0x9b9e, 0x9357, 0x91ae, 0x936a, 0x8ec6, 0x9177, 0x979a, 0x9ba2,
+ 0x9ba3, 0x93d4, 0x8e52, 0x9ba5, 0x9ba6, 0x9ba7, 0x8af2, 0x9ba8,
+ 0x9ba9, 0x89aa, 0x915a, 0x8ae2, 0x9bab, 0x96a6, 0x91d0, 0x8a78,
+ 0x9bad, 0x9baf, 0x8add, 0x9bac, 0x9bae, 0x9bb1, 0x9bb0, 0x9bb2,
+ 0x9bb3, 0x93bb, 0x8bac, 0x89e3, 0x9bb4, 0x9bb9, 0x9bb7, 0x95f5,
+ 0x95f4, 0x9387, 0x9bb6, 0x8f73, 0x9bb5, 0x9092, 0x9bba, 0x8de8,
+ 0x9bc0, 0x9bc1, 0x9bbb, 0x8a52, 0x9bbc, 0x9bc5, 0x9bc4, 0x9bc3,
+ 0x9bbf, 0x9bbe, 0x9bc2, 0x95f6, 0x9bc9, 0x9bc6, 0x9bc8, 0x9792,
+ 0x9bc7, 0x9bbd, 0x9093, 0x9bca, 0x8db5, 0x9bcb, 0x9bcc, 0x9bcf,
+ 0x9bce, 0x9bcd, 0x9388, 0x9bb8, 0x9bd5, 0x9bd1, 0x9bd0, 0x9bd2,
+ 0x9bd3, 0x9bd6, 0x97e4, 0x9bd7, 0x9bd4, 0x9bd8, 0x8ade, 0x9bd9,
+ 0x9bdb, 0x9bda, 0x9bdc, 0x9bdd, 0x90ec, 0x8f42, 0x8f84, 0x9183,
+ 0x8d48, 0x8db6, 0x8d49, 0x8b90, 0x9bde, 0x8db7, 0x8cc8, 0x9bdf,
+ 0x96a4, 0x9462, 0x9be0, 0x8d4a, 0x8aaa, 0x9246, 0x8bd0, 0x8e73,
+ 0x957a, 0x94bf, 0x9be1, 0x8af3, 0x9be4, 0x929f, 0x9be3, 0x9be2,
+ 0x9be5, 0x92e9, 0x9083, 0x8e74, 0x90c8, 0x91d1, 0x8b41, 0x92a0,
+ 0x9be6, 0x9be7, 0x8fed, 0x9658, 0x9bea, 0x9be9, 0x9be8, 0x959d,
+ 0x9bf1, 0x9679, 0x9beb, 0x9bed, 0x968b, 0x9bec, 0x9bee, 0x94a6,
+ 0x9bef, 0x95bc, 0x9bf0, 0x8ab1, 0x95bd, 0x944e, 0x9bf2, 0x9bf3,
+ 0x8d4b, 0x8ab2, 0x9bf4, 0x8cb6, 0x9763, 0x9748, 0x8af4, 0x9bf6,
+ 0x92a1, 0x8d4c, 0x8faf, 0x94dd, 0x8fb0, 0x8f98, 0x92ea, 0x95f7,
+ 0x9358, 0x8d4d, 0x957b, 0x9bf7, 0x9378, 0x8dc0, 0x8cc9, 0x92eb,
+ 0x88c1, 0x8f8e, 0x8d4e, 0x9766, 0x9bf8, 0x9bf9, 0x9470, 0x9bfa,
+ 0x97f5, 0x984c, 0x9bfc, 0x9bfb, 0x8a66, 0x9c40, 0x9c43, 0x9c44,
+ 0x9c42, 0x955f, 0x8fb1, 0x9c46, 0x9c45, 0x9c41, 0x9c47, 0x9c48,
+ 0x9c49, 0x9c4c, 0x9c4a, 0x9c4b, 0x9c4d, 0x8984, 0x92ec, 0x9c4e,
+ 0x8c9a, 0x89f4, 0x9455, 0x9c4f, 0x93f9, 0x95d9, 0x9c50, 0x984d,
+ 0x9c51, 0x95be, 0x9c54, 0x989f, 0x98af, 0x8eae, 0x93f3, 0x9c55,
+ 0x8b7c, 0x92a2, 0x88f8, 0x9c56, 0x95a4, 0x8d4f, 0x926f, 0x92ed,
+ 0x96ed, 0x8cb7, 0x8cca, 0x9c57, 0x9c58, 0x9c5e, 0x8ee3, 0x92a3,
+ 0x8bad, 0x9c59, 0x954a, 0x9265, 0x9c5a, 0x9c5b, 0x8bae, 0x9c5c,
+ 0x9c5d, 0x9c5f, 0x9396, 0x9c60, 0x9c61, 0x9c62, 0x9c53, 0x9c52,
+ 0x9c63, 0x8c60, 0x9546, 0x8dca, 0x9556, 0x92a4, 0x956a, 0x9c64,
+ 0x8fb2, 0x8965, 0x9c65, 0x9c66, 0x96f0, 0x94de, 0x9c69, 0x899d,
+ 0x90aa, 0x9c68, 0x9c67, 0x8c61, 0x91d2, 0x9c6d, 0x9c6b, 0x9c6a,
+ 0x97a5, 0x8ce3, 0x8f99, 0x9c6c, 0x936b, 0x8f5d, 0x93be, 0x9c70,
+ 0x9c6f, 0x9c6e, 0x9c71, 0x8ce4, 0x9c72, 0x959c, 0x8f7a, 0x9c73,
+ 0x94f7, 0x93bf, 0x92a5, 0x934f, 0x9c74, 0x8b4a, 0x9053, 0x954b,
+ 0x8af5, 0x9445, 0x9c75, 0x8e75, 0x9659, 0x965a, 0x899e, 0x9c7a,
+ 0x9289, 0x9c77, 0x89f5, 0x9cab, 0x9c79, 0x944f, 0x9c78, 0x9c76,
+ 0x8d9a, 0x9c7c, 0x9c83, 0x9c89, 0x9c81, 0x937b, 0x9c86, 0x957c,
+ 0x9c80, 0x9c85, 0x97e5, 0x8e76, 0x91d3, 0x9c7d, 0x8b7d, 0x9c88,
+ 0x90ab, 0x8985, 0x9c82, 0x89f6, 0x9c87, 0x8baf, 0x9c84, 0x9c8a,
+ 0x9c8c, 0x9c96, 0x9c94, 0x9c91, 0x9c90, 0x97f6, 0x9c92, 0x8bb0,
+ 0x8d50, 0x8f9a, 0x9c99, 0x9c8b, 0x9c8f, 0x9c7e, 0x89f8, 0x9c93,
+ 0x9c95, 0x9270, 0x8da6, 0x89b6, 0x9c8d, 0x9c98, 0x9c97, 0x8bb1,
+ 0x91a7, 0x8a86, 0x8c62, 0x9c8e, 0x9c9a, 0x9c9d, 0x9c9f, 0x8ebb,
+ 0x9ca5, 0x92ee, 0x9c9b, 0x9ca3, 0x89f7, 0x9ca1, 0x9ca2, 0x9c9e,
+ 0x9ca0, 0x8ce5, 0x9749, 0x8ab3, 0x8978, 0x9ca4, 0x9459, 0x88ab,
+ 0x94df, 0x9c7b, 0x9caa, 0x9cae, 0x96e3, 0x9ca7, 0x9389, 0x9cac,
+ 0x8fee, 0x9cad, 0x93d5, 0x9866, 0x9ca9, 0x9caf, 0x8d9b, 0x90c9,
+ 0x88d2, 0x9ca8, 0x9ca6, 0x9179, 0x9c9c, 0x8e53, 0x91c4, 0x9cbb,
+ 0x917a, 0x9cb6, 0x9cb3, 0x9cb4, 0x8ee4, 0x9cb7, 0x9cba, 0x9cb5,
+ 0x8f44, 0x9cb8, 0x9cb2, 0x96fa, 0x96f9, 0x9cbc, 0x9cbd, 0x88d3,
+ 0x9cb1, 0x8bf0, 0x88a4, 0x8ab4, 0x9cb9, 0x9cc1, 0x9cc0, 0x9cc5,
+ 0x9cc6, 0x9cc4, 0x9cc7, 0x9cbf, 0x9cc3, 0x9cc8, 0x9cc9, 0x9cbe,
+ 0x8e9c, 0x9cc2, 0x91d4, 0x8d51, 0x9cb0, 0x9054, 0x9cd6, 0x95e7,
+ 0x9ccc, 0x9ccd, 0x9cce, 0x9cd5, 0x9cd4, 0x969d, 0x8ab5, 0x9cd2,
+ 0x8c64, 0x8a53, 0x9ccf, 0x97b6, 0x9cd1, 0x88d4, 0x9cd3, 0x9cca,
+ 0x9cd0, 0x9cd7, 0x8c63, 0x9ccb, 0x977c, 0x974a, 0x9cda, 0x9cde,
+ 0x919e, 0x97f7, 0x9cdf, 0x9cdc, 0x9cd9, 0x9cd8, 0x9cdd, 0x95ae,
+ 0x93b2, 0x8c65, 0x9ce0, 0x9cdb, 0x9ce1, 0x8c9b, 0x89af, 0x9ce9,
+ 0x8ab6, 0x9ce7, 0x9ce8, 0x8da7, 0x9ce6, 0x9ce4, 0x9ce3, 0x9cea,
+ 0x9ce2, 0x9cec, 0x89f9, 0x9cee, 0x9ced, 0x92a6, 0x9cf1, 0x9cef,
+ 0x9ce5, 0x8c9c, 0x9cf0, 0x9cf4, 0x9cf3, 0x9cf5, 0x9cf2, 0x9cf6,
+ 0x9cf7, 0x9cf8, 0x95e8, 0x9cfa, 0x9cf9, 0x8f5e, 0x90ac, 0x89e4,
+ 0x89fa, 0x9cfb, 0x88bd, 0x90ca, 0x9cfc, 0xe6c1, 0x9d40, 0x8c81,
+ 0x9d41, 0x90ed, 0x9d42, 0x9d43, 0x8b59, 0x9d44, 0x9d45, 0x9d46,
+ 0x91d5, 0x8ccb, 0x96df, 0x965b, 0x8f8a, 0x9d47, 0x90ee, 0xe7bb,
+ 0x94e0, 0x8ee8, 0x8dcb, 0x9d48, 0x91c5, 0x95a5, 0x91ef, 0x9d4b,
+ 0x9d49, 0x9d4c, 0x9d4a, 0x9d4d, 0x95af, 0x88b5, 0x957d, 0x94e1,
+ 0x9d4e, 0x9d51, 0x8fb3, 0x8b5a, 0x9d4f, 0x9d56, 0x8fb4, 0x9d50,
+ 0x9463, 0x977d, 0x9d52, 0x9d53, 0x9d57, 0x938a, 0x9d54, 0x8d52,
+ 0x90dc, 0x9d65, 0x94b2, 0x91f0, 0x94e2, 0x9dab, 0x95f8, 0x92ef,
+ 0x9695, 0x9d5a, 0x899f, 0x928a, 0x9d63, 0x9253, 0x9d5d, 0x9d64,
+ 0x9d5f, 0x9d66, 0x9d62, 0x9d61, 0x948f, 0x9d5b, 0x89fb, 0x9d59,
+ 0x8b91, 0x91f1, 0x9d55, 0x9d58, 0x8d53, 0x90d9, 0x8fb5, 0x9d60,
+ 0x9471, 0x8b92, 0x8a67, 0x8a87, 0x9040, 0x9d68, 0x9d6d, 0x9d69,
+ 0x8c9d, 0x9d6e, 0x8e41, 0x8d89, 0x8f45, 0x9d5c, 0x8e9d, 0x9d6b,
+ 0x8e77, 0x9d6c, 0x88c2, 0x9d67, 0x92a7, 0x8b93, 0x8bb2, 0x9d6a,
+ 0x88a5, 0x8dc1, 0x9055, 0x92f0, 0x94d2, 0x9d70, 0x917d, 0x91a8,
+ 0x8e4a, 0x9d71, 0x9d73, 0x9d6f, 0x95df, 0x92bb, 0x917b, 0x95f9,
+ 0x8ecc, 0x9d80, 0x9d7e, 0x9098, 0x8c9e, 0x9d78, 0x8fb7, 0x93e6,
+ 0x9450, 0x9d76, 0x917c, 0x8ef6, 0x9d7b, 0x8fb6, 0x9d75, 0x9d7a,
+ 0x9472, 0x9d74, 0x8c40, 0x8a7c, 0x9d7c, 0x97a9, 0x8dcc, 0x9254,
+ 0x9d79, 0x90da, 0x8d54, 0x9084, 0x8986, 0x915b, 0x9d77, 0x8b64,
+ 0x8c66, 0x92cd, 0x9d7d, 0x917e, 0x9d81, 0x9d83, 0x91b5, 0x9d89,
+ 0x9d84, 0x9d86, 0x9560, 0x92f1, 0x9d87, 0x974b, 0x9767, 0x8ab7,
+ 0x88ac, 0x9d85, 0x9d82, 0x8af6, 0x8987, 0x9d88, 0x9768, 0x9d8c,
+ 0x91b9, 0x9d93, 0x9d8d, 0x9d8a, 0x9d91, 0x9d72, 0x9d8e, 0x9d92,
+ 0x94c0, 0x938b, 0x9d8b, 0x9d8f, 0x8c67, 0x8def, 0x90db, 0x9d97,
+ 0x9345, 0x9d94, 0x9680, 0x9d95, 0x9d96, 0x96cc, 0x90a0, 0x8c82,
+ 0x9d9d, 0x8e54, 0x9d9a, 0x9d99, 0x9451, 0x93b3, 0x9350, 0x9d9b,
+ 0x9d9c, 0x958f, 0x9464, 0x8e42, 0x90ef, 0x966f, 0x8a68, 0x9da3,
+ 0x9d9e, 0x9769, 0x9da5, 0x9da1, 0x9da2, 0x9180, 0x9da0, 0x9d5e,
+ 0x9da4, 0x9d9f, 0x9da9, 0x9daa, 0x9346, 0x9dac, 0x8e43, 0x9da7,
+ 0x8b5b, 0x9dad, 0x9da6, 0x9db1, 0x9db0, 0x9daf, 0x9db2, 0x9db4,
+ 0x8fef, 0x9db3, 0x9db7, 0x9db5, 0x9db6, 0x9d90, 0x9db9, 0x9db8,
+ 0x9d98, 0x9dba, 0x9dae, 0x8e78, 0x9dbb, 0x9dbc, 0x9dbe, 0x9dbd,
+ 0x9dbf, 0x89fc, 0x8d55, 0x95fa, 0x90ad, 0x8ccc, 0x9dc1, 0x9dc4,
+ 0x9571, 0x8b7e, 0x9dc3, 0x9dc2, 0x9473, 0x9dc5, 0x8bb3, 0x9dc7,
+ 0x9dc6, 0x8ab8, 0x8e55, 0x93d6, 0x8c68, 0x9094, 0x9dc8, 0x90ae,
+ 0x9347, 0x957e, 0x9dc9, 0x9dca, 0x9dcb, 0x95b6, 0x9b7c, 0x90c4,
+ 0x956b, 0x8dd6, 0x94e3, 0x94c1, 0x936c, 0x97bf, 0x9dcd, 0x8ece,
+ 0x9dce, 0x88b4, 0x8bd2, 0x90cb, 0x9580, 0x9dcf, 0x8e61, 0x9266,
+ 0x8e7a, 0x9056, 0x9dd0, 0x95fb, 0x8997, 0x8e7b, 0x9dd3, 0x9dd1,
+ 0x9dd4, 0x97b7, 0x9dd2, 0x90f9, 0x9dd5, 0x91b0, 0x9dd6, 0x8af8,
+ 0x9dd8, 0x9dd7, 0x9dd9, 0x9dda, 0x8af9, 0x93fa, 0x9255, 0x8b8c,
+ 0x8e7c, 0x9181, 0x8f7b, 0x88ae, 0x9ddb, 0x89a0, 0x9ddf, 0x8d56,
+ 0x9dde, 0x8da9, 0x8fb8, 0x9ddd, 0x8fb9, 0x96be, 0x8da8, 0x88d5,
+ 0x90cc, 0x9de4, 0x90af, 0x8966, 0x8f74, 0x9686, 0x8df0, 0x8fba,
+ 0x90a5, 0x9de3, 0x9de1, 0x9de2, 0x928b, 0x9e45, 0x9de8, 0x8e9e,
+ 0x8d57, 0x9de6, 0x9de7, 0x9057, 0x9de5, 0x8e4e, 0x9dea, 0x9de9,
+ 0x9dee, 0x9def, 0x9deb, 0x8a41, 0x9dec, 0x9ded, 0x94d3, 0x9581,
+ 0x8c69, 0x9df0, 0x90b0, 0x8fbb, 0x9271, 0x8bc5, 0x9df1, 0x9df5,
+ 0x89c9, 0x9df2, 0x9df4, 0x9df3, 0x8f8b, 0x9267, 0x88c3, 0x9df6,
+ 0x9df7, 0x92a8, 0x97ef, 0x8e62, 0x95e9, 0x965c, 0x9e41, 0x9df9,
+ 0x9dfc, 0x9dfb, 0x9df8, 0x9e40, 0x93dc, 0x9dfa, 0x9e42, 0x8f8c,
+ 0x9e43, 0x976a, 0x9498, 0x9e44, 0x9e46, 0x9e47, 0x9e48, 0x8bc8,
+ 0x8967, 0x8d58, 0x9e49, 0x9e4a, 0x8f91, 0x9182, 0x99d6, 0x915d,
+ 0x915c, 0x91d6, 0x8dc5, 0x98f0, 0x8c8e, 0x974c, 0x95fc, 0x959e,
+ 0x9e4b, 0x8df1, 0x92bd, 0x9e4c, 0x984e, 0x965d, 0x92a9, 0x9e4d,
+ 0x8afa, 0x9e4e, 0x9e4f, 0x96d8, 0x96a2, 0x9696, 0x967b, 0x8e44,
+ 0x9e51, 0x8ee9, 0x9670, 0x9e53, 0x9e56, 0x9e55, 0x8af7, 0x8b80,
+ 0x9e52, 0x9e54, 0x9e57, 0x9099, 0x979b, 0x88c7, 0x8dde, 0x91ba,
+ 0x8edb, 0x8ff1, 0x9e5a, 0x936d, 0x9e58, 0x91a9, 0x9e59, 0x8ff0,
+ 0x96db, 0x9e5b, 0x9e5c, 0x9788, 0x9e61, 0x8d59, 0x9474, 0x9e5e,
+ 0x938c, 0x9ddc, 0x9de0, 0x8b6e, 0x9466, 0x9e60, 0x8fbc, 0x94c2,
+ 0x9e66, 0x94f8, 0x9e5d, 0x9e63, 0x9e62, 0x90cd, 0x968d, 0x97d1,
+ 0x9687, 0x89ca, 0x8e7d, 0x9867, 0x9e65, 0x9095, 0x9e64, 0x9e5f,
+ 0x8ccd, 0x9e6b, 0x9e69, 0x89cb, 0x9e67, 0x9e6d, 0x9e73, 0x91c6,
+ 0x95bf, 0x9e75, 0x9541, 0x9e74, 0x9490, 0x965e, 0x8ab9, 0x90f5,
+ 0x8f5f, 0x92d1, 0x974d, 0x9e70, 0x9e6f, 0x9e71, 0x9e6e, 0x9e76,
+ 0x9e6c, 0x9e6a, 0x9e72, 0x9e68, 0x928c, 0x96f6, 0x8ec4, 0x8df2,
+ 0x8db8, 0x968f, 0x8a60, 0x92cc, 0x93c8, 0x8968, 0x90f0, 0x90b2,
+ 0x8c49, 0x9e78, 0x8d5a, 0x8a9c, 0x9e7a, 0x8a94, 0x9e81, 0x9e7d,
+ 0x90f1, 0x8a6a, 0x8daa, 0x8a69, 0x8dcd, 0x9e7b, 0x8c85, 0x8c6a,
+ 0x938d, 0x9e79, 0x88c4, 0x9e7c, 0x9e7e, 0x8bcb, 0x8c4b, 0x8aba,
+ 0x8b6a, 0x9e82, 0x8df7, 0x9691, 0x8e56, 0x9e83, 0x954f, 0x9e8f,
+ 0x89b1, 0x9e84, 0x9e95, 0x9e85, 0x97c0, 0x9e8c, 0x947e, 0x9e94,
+ 0x9e87, 0x88b2, 0x9e89, 0x8d5b, 0x9e8b, 0x9e8a, 0x9e86, 0x9e91,
+ 0x8fbd, 0x9aeb, 0x8ce6, 0x979c, 0x9e88, 0x92f2, 0x8a42, 0x8dab,
+ 0x9e80, 0x9e90, 0x8a81, 0x9e8e, 0x9e92, 0x938e, 0x8afc, 0x9eb0,
+ 0x96c7, 0x9e97, 0x8afb, 0x9e9e, 0x965f, 0x9e9f, 0x9ea1, 0x9ea5,
+ 0x9e99, 0x9249, 0x938f, 0x9ea9, 0x9e9c, 0x9ea6, 0x9ea0, 0x9058,
+ 0x9eaa, 0x90b1, 0x9ea8, 0x8abb, 0x986f, 0x9e96, 0x9ea4, 0x88d6,
+ 0x9e98, 0x96b8, 0x9e9d, 0x9041, 0x92c5, 0x9e93, 0x9ea3, 0x909a,
+ 0x9ead, 0x8a91, 0x8c9f, 0x9eaf, 0x9e9a, 0x9eae, 0x9ea7, 0x9e9b,
+ 0x9eab, 0x9eac, 0x9ebd, 0x93cc, 0x9ea2, 0x9eb9, 0x9ebb, 0x92d6,
+ 0x976b, 0x9596, 0x9eb6, 0x91c8, 0x9ebc, 0x915e, 0x9eb3, 0x9ec0,
+ 0x9ebf, 0x93ed, 0x9ebe, 0x93e8, 0x9ec2, 0x9eb5, 0x8bc6, 0x9eb8,
+ 0x8f7c, 0x9480, 0x9eba, 0x8bc9, 0x9eb2, 0x9eb4, 0x9eb1, 0x984f,
+ 0x8a79, 0x9eb7, 0x9ec1, 0x8a54, 0x8de5, 0x897c, 0x9ed2, 0x9850,
+ 0x9ed5, 0x9059, 0x9ed4, 0x9ed3, 0x9ed0, 0x9ec4, 0x9ee1, 0x9ec3,
+ 0x9ed6, 0x9ece, 0x9ec9, 0x9ec6, 0x9ec7, 0x9ecf, 0xeaa0, 0x9ecc,
+ 0x8d5c, 0x92c6, 0x9184, 0x9eca, 0x9ec5, 0x9ec8, 0x976c, 0x968a,
+ 0x9ecd, 0x9ed7, 0x9edf, 0x9ed8, 0x9ee5, 0x9ee3, 0x9ede, 0x9edd,
+ 0x92ce, 0x9185, 0x9edb, 0x9ed9, 0x9ee0, 0x9ee6, 0x94f3, 0x9eec,
+ 0x9ee7, 0x9eea, 0x9ee4, 0x9294, 0x9557, 0x9eda, 0x9ee2, 0x8fbe,
+ 0x96cd, 0x9ef6, 0x9ee9, 0x8ca0, 0x89a1, 0x8a7e, 0x9ed1, 0x8fbf,
+ 0x9eee, 0x9ef5, 0x8ef7, 0x8a92, 0x924d, 0x9eeb, 0x9ef0, 0x9ef4,
+ 0x8bb4, 0x8b6b, 0x9ef2, 0x8b40, 0x93c9, 0x9ef1, 0x9ef3, 0x9eed,
+ 0x9eef, 0x8a80, 0x9268, 0x9efa, 0x9ef8, 0x8ce7, 0x9ef7, 0x9f40,
+ 0x9e77, 0x9ef9, 0x9efb, 0x9efc, 0x9f4b, 0x9f47, 0x9e8d, 0x9f46,
+ 0x9f45, 0x9f42, 0x9ee8, 0x9f44, 0x9f43, 0x9f49, 0x9845, 0x9f4c,
+ 0x8bf9, 0x9f48, 0x9f4a, 0x94a5, 0x9f4d, 0x9f51, 0x9f4e, 0x9793,
+ 0x9f4f, 0x9edc, 0x9f52, 0x9f53, 0x8954, 0x9f55, 0x8c87, 0x8e9f,
+ 0x8bd3, 0x89a2, 0x977e, 0x9f57, 0x9f56, 0x9f59, 0x8b5c, 0x8bd4,
+ 0x8abc, 0x9f5c, 0x9f5b, 0x9f5d, 0x89cc, 0x9256, 0x9f5e, 0x8abd,
+ 0x9f60, 0x9f5f, 0x9f61, 0x9f62, 0x9f63, 0x8e7e, 0x90b3, 0x8d9f,
+ 0x9590, 0x95e0, 0x9863, 0x8e95, 0x8dce, 0x97f0, 0x9f64, 0x9f65,
+ 0x8e80, 0x9f66, 0x9f67, 0x9f69, 0x9f68, 0x9677, 0x8f7d, 0x8eea,
+ 0x8e63, 0x9f6a, 0x9f6c, 0x9042, 0x9f6b, 0x9f6d, 0x9f6e, 0x9f6f,
+ 0x9f70, 0x9f71, 0x9f73, 0x9f72, 0x9f74, 0x89a3, 0x9269, 0x9f75,
+ 0x8e45, 0x8a6b, 0x9f76, 0x9361, 0x9aca, 0x8b42, 0x9f77, 0x9f78,
+ 0x95ea, 0x9688, 0x93c5, 0x9f79, 0x94e4, 0x94f9, 0x96d1, 0x9f7a,
+ 0x9f7c, 0x9f7b, 0x9f7e, 0x9f7d, 0x9f81, 0x8e81, 0x96af, 0x9f82,
+ 0x9f83, 0x8b43, 0x9f84, 0x9f86, 0x9f85, 0x9085, 0x9558, 0x8969,
+ 0x94c3, 0x92f3, 0x8f60, 0x8b81, 0x94c4, 0x8eac, 0x9f88, 0x8abe,
+ 0x8998, 0x93f0, 0x9f87, 0x8d5d, 0x9272, 0x9f89, 0x9f91, 0x9f8a,
+ 0x91bf, 0x8b82, 0x9f92, 0x8c88, 0x8b44, 0x9f90, 0x9f8e, 0x9f8b,
+ 0x9780, 0x92be, 0x93d7, 0x9f8c, 0x9f94, 0x9f93, 0x8c42, 0x89ab,
+ 0x8db9, 0x9f8d, 0x9f8f, 0x9676, 0x91f2, 0x9697, 0x9f9c, 0x9f9d,
+ 0x89cd, 0x95a6, 0x96fb, 0x9f9f, 0x8ea1, 0x8fc0, 0x9f98, 0x9f9e,
+ 0x8988, 0x8bb5, 0x9f95, 0x9f9a, 0x90f2, 0x9491, 0x94e5, 0x9f97,
+ 0x9640, 0x9f99, 0x9fa2, 0x9fa0, 0x9f9b, 0x9641, 0x9467, 0x8b83,
+ 0x9344, 0x928d, 0x9fa3, 0x9fa1, 0x91d7, 0x9f96, 0x896a, 0x976d,
+ 0x9fae, 0x9fad, 0x90f4, 0x9faa, 0x978c, 0x93b4, 0x9fa4, 0x92c3,
+ 0x896b, 0x8d5e, 0x9fa7, 0x8f46, 0x9fac, 0x9fab, 0x9fa6, 0x9fa9,
+ 0x8a88, 0x9fa8, 0x9468, 0x97ac, 0x8ff2, 0x90f3, 0x9fb4, 0x9fb2,
+ 0x956c, 0x9faf, 0x9fb1, 0x8959, 0x8d5f, 0x9851, 0x8a5c, 0x9582,
+ 0x9781, 0x8a43, 0x905a, 0x9fb3, 0x9fb8, 0x8fc1, 0x974f, 0x9fb5,
+ 0x9fb0, 0x9fb6, 0x97dc, 0x9393, 0x93c0, 0x8a55, 0x8974, 0x9fbc,
+ 0x9fbf, 0x97c1, 0x9784, 0x9fc6, 0x9fc0, 0x9fbd, 0x97d2, 0x9fc3,
+ 0x8f69, 0x9fc5, 0x9fca, 0x9391, 0x9fc8, 0x9fc2, 0x9257, 0x9fc9,
+ 0x9fbe, 0x9fc4, 0x9fcb, 0x88fa, 0x9fc1, 0x9fcc, 0x905b, 0x8f7e,
+ 0x95a3, 0x8dac, 0x9fb9, 0x9fc7, 0x9359, 0x90b4, 0x8a89, 0x8dcf,
+ 0x8fc2, 0x9fbb, 0x8f61, 0x8c6b, 0x9fba, 0x9fd0, 0x8f8d, 0x8cb8,
+ 0x9fdf, 0x9fd9, 0x8b94, 0x936e, 0x9fd4, 0x9fdd, 0x88ad, 0x8951,
+ 0x89b7, 0x9fd6, 0x91aa, 0x9fcd, 0x9fcf, 0x8d60, 0x9fe0, 0x9fdb,
+ 0x9fd3, 0x9fda, 0x96a9, 0x9fd8, 0x9fdc, 0x8cce, 0x8fc3, 0x9258,
+ 0x9fd2, 0x974e, 0x9fd5, 0x9fce, 0x9392, 0x9fd1, 0x9fd7, 0x9870,
+ 0x8ebc, 0x969e, 0x9fe1, 0x94ac, 0x9fed, 0x8cb9, 0x8f80, 0x9fe3,
+ 0x97ad, 0x8d61, 0x9ff0, 0x88ec, 0x9fee, 0x9fe2, 0x9fe8, 0x9fea,
+ 0x976e, 0x9fe5, 0x934d, 0x9fe7, 0x9fef, 0x9fe9, 0x96c5, 0x9fe4,
+ 0x8ea0, 0x9ffc, 0x8a8a, 0x9fe6, 0x9feb, 0x9fec, 0x91ea, 0x91d8,
+ 0x9ff4, 0x9ffa, 0x9ff8, 0x9348, 0xe042, 0x9ff5, 0x9ff6, 0x9fde,
+ 0x8b99, 0x9559, 0x8ebd, 0x8d97, 0x9852, 0x9ff2, 0xe041, 0x8989,
+ 0x9186, 0x9499, 0x8abf, 0x97f8, 0x969f, 0x92d0, 0x9ff9, 0x9ffb,
+ 0x9151, 0xe040, 0x9ff7, 0x9ff1, 0x8ac1, 0x8c89, 0xe04e, 0xe049,
+ 0x90f6, 0x8a83, 0x8f81, 0xe052, 0xe04b, 0x92aa, 0xe048, 0x92d7,
+ 0xe06b, 0xe045, 0xe044, 0xe04d, 0xe047, 0xe046, 0xe04c, 0x909f,
+ 0xe043, 0xe04f, 0xe050, 0x8ac0, 0xe055, 0xe054, 0xe056, 0xe059,
+ 0x9362, 0xe053, 0xe057, 0x8c83, 0x91f7, 0xe051, 0x945a, 0xe058,
+ 0xe05d, 0xe05b, 0xe05e, 0xe061, 0xe05a, 0x8d8a, 0x9447, 0x9fb7,
+ 0x9794, 0xe05c, 0xe060, 0x91f3, 0xe05f, 0xe04a, 0xe889, 0xe064,
+ 0xe068, 0xe066, 0xe062, 0xe063, 0xe067, 0xe065, 0x956d, 0xe06d,
+ 0xe06a, 0xe069, 0xe06c, 0x93d2, 0xe06e, 0x9295, 0x91eb, 0x90a3,
+ 0xe06f, 0xe071, 0xe070, 0x9ff3, 0xe072, 0x93e5, 0xe073, 0x89ce,
+ 0x9394, 0x8a44, 0x8b84, 0x8edc, 0x8dd0, 0x9846, 0x9086, 0x898a,
+ 0xe075, 0xe074, 0xe078, 0x9259, 0xe07b, 0xe076, 0xe07a, 0xe079,
+ 0x935f, 0x88d7, 0x97f3, 0xe07d, 0x8947, 0xe080, 0xe07e, 0xe07c,
+ 0xe077, 0x9642, 0xe082, 0xe081, 0x898b, 0xe084, 0x95b0, 0xe083,
+ 0x96b3, 0x8fc5, 0x9152, 0x8fc4, 0x97f9, 0xe08a, 0x90f7, 0xe086,
+ 0xe08b, 0x898c, 0xe089, 0x9481, 0xe085, 0xe088, 0x8fc6, 0x94cf,
+ 0xe08c, 0x8ecf, 0x90f8, 0xe08f, 0xe087, 0x8c46, 0xe08d, 0x976f,
+ 0xe090, 0xeaa4, 0x8f6e, 0xe091, 0xe092, 0x944d, 0xe094, 0xe095,
+ 0x9452, 0x9395, 0xe097, 0xe099, 0x97d3, 0xe096, 0xe098, 0x898d,
+ 0xe093, 0x9a7a, 0xe09a, 0x9187, 0x8e57, 0xe09c, 0xe09b, 0x9043,
+ 0x99d7, 0xe09d, 0xe09f, 0xe08e, 0xe09e, 0xe0a0, 0x949a, 0xe0a1,
+ 0xe0a2, 0xe0a3, 0xe0a4, 0x92dc, 0xe0a6, 0xe0a5, 0xe0a7, 0xe0a8,
+ 0x8edd, 0x9583, 0x96ea, 0xe0a9, 0xe0aa, 0x9175, 0x8ea2, 0xe0ab,
+ 0xe0ac, 0xe0ad, 0x95d0, 0x94c5, 0xe0ae, 0x9476, 0x92ab, 0xe0af,
+ 0x89e5, 0x8b8d, 0x96c4, 0x96b4, 0x89b2, 0x9853, 0x9671, 0x95a8,
+ 0x90b5, 0xe0b0, 0x93c1, 0x8ca1, 0xe0b1, 0x8dd2, 0xe0b3, 0xe0b2,
+ 0xe0b4, 0xe0b5, 0xe0b6, 0x8b5d, 0xe0b7, 0xe0b8, 0x8ca2, 0x94c6,
+ 0xe0ba, 0x8ff3, 0xe0b9, 0x8bb6, 0xe0bb, 0xe0bd, 0xe0bc, 0xe0be,
+ 0x8ccf, 0xe0bf, 0x8be7, 0x915f, 0x8d9d, 0xe0c1, 0xe0c2, 0xe0c0,
+ 0x8eeb, 0x93c6, 0x8bb7, 0xe0c4, 0x924b, 0xe0c3, 0x9854, 0x9482,
+ 0xe0c7, 0xe0c9, 0xe0c6, 0x96d2, 0xe0c8, 0xe0ca, 0x97c2, 0xe0ce,
+ 0xe0cd, 0x9296, 0x944c, 0x8ca3, 0xe0cc, 0xe0cb, 0x9750, 0x9751,
+ 0xe0cf, 0x898e, 0x8d96, 0x8e82, 0xe0d0, 0xe0d1, 0xe0d3, 0x8f62,
+ 0xe0d5, 0xe0d4, 0xe0d6, 0x8a6c, 0xe0d8, 0xe0d7, 0xe0da, 0xe0d9,
+ 0x8cba, 0x97a6, 0x8bca, 0x89a4, 0x8be8, 0x8adf, 0x97e6, 0xe0dc,
+ 0xe0de, 0xe0df, 0x89cf, 0xe0db, 0x8e58, 0x92bf, 0xe0dd, 0xe0e2,
+ 0x8eec, 0xe0e0, 0x8c5d, 0x94c7, 0xe0e1, 0xe0fc, 0xe0e7, 0x8cbb,
+ 0x8b85, 0xe0e4, 0x979d, 0x97ae, 0x91f4, 0xe0e6, 0xe0e8, 0x97d4,
+ 0x8bd5, 0x94fa, 0x9469, 0xe0e9, 0xe0eb, 0xe0ee, 0xe0ea, 0xe0ed,
+ 0x8ce8, 0x896c, 0xe0ef, 0x9090, 0xe0ec, 0x97da, 0xe0f2, 0xeaa2,
+ 0xe0f0, 0xe0f3, 0xe0e5, 0xe0f1, 0x8dba, 0xe0f4, 0xe0f5, 0x979e,
+ 0xe0f6, 0xe0f7, 0xe0e3, 0xe0f8, 0x8ac2, 0x8ea3, 0xe0f9, 0xe0fa,
+ 0xe0fb, 0x895a, 0xe140, 0x955a, 0xe141, 0x8aa2, 0xe142, 0xe143,
+ 0xe144, 0xe146, 0xe147, 0xe145, 0x9572, 0xe149, 0xe148, 0xe14b,
+ 0xe14a, 0xe14c, 0xe14d, 0xe14f, 0xe14e, 0x8d99, 0xe151, 0xe150,
+ 0x8ac3, 0x9072, 0x935b, 0xe152, 0x90b6, 0x8e59, 0x8999, 0xe153,
+ 0x9770, 0x95e1, 0xe154, 0x9363, 0x9752, 0x8d62, 0x905c, 0x926a,
+ 0x99b2, 0x92ac, 0x89e6, 0xe155, 0xe156, 0xe15b, 0xe159, 0xe158,
+ 0x9dc0, 0x8a45, 0xe157, 0x88d8, 0x94a8, 0x94c8, 0x97af, 0xe15c,
+ 0xe15a, 0x927b, 0x90a4, 0x94a9, 0x954c, 0xe15e, 0x97aa, 0x8c6c,
+ 0xe15f, 0xe15d, 0x94d4, 0xe160, 0xe161, 0x88d9, 0x8ff4, 0xe166,
+ 0xe163, 0x93eb, 0xe162, 0x8b45, 0xe169, 0xe164, 0xe165, 0xe168,
+ 0xe167, 0x9544, 0x9161, 0x9160, 0x8b5e, 0xe16a, 0xe16b, 0xe16c,
+ 0xe16e, 0xe16d, 0x8975, 0xe176, 0x94e6, 0xe170, 0xe172, 0xe174,
+ 0x905d, 0xe175, 0xe173, 0x8ebe, 0xe16f, 0xe171, 0x9561, 0x8fc7,
+ 0xe178, 0xe177, 0xe179, 0x8ea4, 0x8dad, 0x9397, 0xe17a, 0x92c9,
+ 0xe17c, 0x979f, 0xe17b, 0x9189, 0xe182, 0xe184, 0xe185, 0x9273,
+ 0xe183, 0xe180, 0xe17d, 0xe17e, 0xe181, 0xe188, 0xe186, 0xe187,
+ 0xe189, 0xe18b, 0xe18c, 0xe18d, 0xe18e, 0xe18a, 0xe190, 0xe18f,
+ 0xe191, 0x97c3, 0xe194, 0xe192, 0xe193, 0x8ae0, 0x96fc, 0x95c8,
+ 0xe196, 0xe195, 0xe197, 0xe198, 0xe19c, 0xe199, 0xe19a, 0xe19b,
+ 0xe19d, 0xe19e, 0xe19f, 0xe1a0, 0xe1a1, 0x94ad, 0x936f, 0xe1a2,
+ 0x9492, 0x9553, 0xe1a3, 0xe1a4, 0x9349, 0x8a46, 0x8d63, 0xe1a5,
+ 0xe1a6, 0xe1a7, 0x8e48, 0xe1a9, 0xe1a8, 0xe1aa, 0xe1ab, 0x94e7,
+ 0xe1ac, 0xe1ad, 0xea89, 0xe1ae, 0xe1af, 0xe1b0, 0x8e4d, 0xe1b1,
+ 0x9475, 0x967e, 0x896d, 0x8976, 0xe1b2, 0xe1b4, 0xe1b3, 0x9390,
+ 0x90b7, 0x9f58, 0xe1b5, 0x96bf, 0xe1b6, 0x8ac4, 0x94d5, 0xe1b7,
+ 0xe1b8, 0xe1b9, 0x96da, 0x96d3, 0x92bc, 0x918a, 0xe1bb, 0x8f82,
+ 0x8fc8, 0xe1be, 0xe1bd, 0xe1bc, 0x94fb, 0x8ac5, 0x8ca7, 0xe1c4,
+ 0xe1c1, 0x905e, 0x96b0, 0xe1c0, 0xe1c2, 0xe1c3, 0xe1bf, 0xe1c5,
+ 0xe1c6, 0x92ad, 0x8ae1, 0x9285, 0xe1c7, 0xe1c8, 0xe1cb, 0x9087,
+ 0x93c2, 0xe1cc, 0x9672, 0xe1c9, 0xe1ca, 0xe1cf, 0xe1ce, 0xe1cd,
+ 0xe1d1, 0xe1d0, 0xe1d2, 0xe1d4, 0xe1d3, 0x95cb, 0x8f75, 0x97c4,
+ 0xe1d5, 0x93b5, 0xe1d6, 0xe1d7, 0xe1db, 0xe1d9, 0xe1da, 0xe1d8,
+ 0xe1dc, 0xe1dd, 0xe1de, 0xe1df, 0x96b5, 0xe1e0, 0x96ee, 0xe1e1,
+ 0x926d, 0x948a, 0x8be9, 0x925a, 0xe1e2, 0x8bb8, 0x90ce, 0xe1e3,
+ 0x8dbb, 0xe1e4, 0xe1e5, 0x8ca4, 0x8dd3, 0xe1e7, 0x9375, 0x8dd4,
+ 0x8b6d, 0x9643, 0x946a, 0x9376, 0x8d7b, 0xe1e9, 0x8fc9, 0x97b0,
+ 0x8d64, 0x8ca5, 0x94a1, 0xe1eb, 0xe1ed, 0x8ce9, 0xe1ec, 0x92f4,
+ 0xe1ef, 0x8a56, 0xe1ea, 0x94e8, 0x894f, 0x8dea, 0x9871, 0xe1ee,
+ 0xe1f0, 0x95c9, 0x90d7, 0xe1f2, 0xe1f3, 0xe1f1, 0x8a6d, 0xe1f9,
+ 0xe1f8, 0x8ea5, 0xe1fa, 0xe1f5, 0xe1fb, 0xe1f6, 0x94d6, 0xe1f4,
+ 0xe1f7, 0xe241, 0xe240, 0x9681, 0xe1fc, 0x88e9, 0xe243, 0xe242,
+ 0x8fca, 0xe244, 0x9162, 0xe246, 0xe245, 0xe247, 0xe1e6, 0xe1e8,
+ 0xe249, 0xe248, 0x8ea6, 0x97e7, 0x8ed0, 0xe24a, 0x8c56, 0x8b5f,
+ 0x8b46, 0x8e83, 0x9753, 0xe250, 0xe24f, 0x9163, 0xe24c, 0xe24e,
+ 0x8f6a, 0x905f, 0xe24d, 0xe24b, 0x9449, 0x8fcb, 0x955b, 0x8dd5,
+ 0x9398, 0xe251, 0xe252, 0xe268, 0x8bd6, 0x985c, 0x9154, 0xe253,
+ 0x89d0, 0x92f5, 0x959f, 0xe254, 0x8b9a, 0xe255, 0xe257, 0xe258,
+ 0x9448, 0xe259, 0xe25a, 0xe25b, 0x8bd7, 0x89d1, 0x93c3, 0x8f47,
+ 0x8e84, 0xe25c, 0x8f48, 0x89c8, 0x9562, 0xe25d, 0x94e9, 0x9164,
+ 0xe260, 0xe261, 0x9489, 0x9060, 0xe25e, 0x9281, 0xe25f, 0x8fcc,
+ 0x88da, 0x8b48, 0xe262, 0x92f6, 0xe263, 0x90c5, 0x96ab, 0x9542,
+ 0xe264, 0xe265, 0x9274, 0x97c5, 0xe267, 0xe266, 0x8eed, 0xe269,
+ 0x88ee, 0xe26c, 0xe26a, 0x89d2, 0x8c6d, 0xe26b, 0x8d65, 0x8d92,
+ 0x95e4, 0xe26d, 0x9673, 0xe26f, 0x90cf, 0x896e, 0x89b8, 0x88aa,
+ 0xe26e, 0xe270, 0xe271, 0x8ff5, 0xe272, 0x8a6e, 0xe274, 0x8c8a,
+ 0x8b86, 0xe275, 0x8bf3, 0xe276, 0x90fa, 0x93cb, 0x90de, 0x8df3,
+ 0xe277, 0x9282, 0x918b, 0xe279, 0xe27b, 0xe278, 0xe27a, 0x8c41,
+ 0xe27c, 0x8c45, 0x8b87, 0x9771, 0xe27e, 0xe280, 0x894d, 0xe283,
+ 0x8a96, 0xe282, 0xe281, 0xe285, 0xe27d, 0xe286, 0x97a7, 0xe287,
+ 0xe288, 0x9af2, 0xe28a, 0xe289, 0xe28b, 0xe28c, 0x97b3, 0xe28d,
+ 0xe8ed, 0x8fcd, 0xe28e, 0xe28f, 0x8f76, 0x93b6, 0xe290, 0x9247,
+ 0xe291, 0x925b, 0xe292, 0x8ba3, 0x995e, 0x927c, 0x8eb1, 0x8ac6,
+ 0xe293, 0xe2a0, 0xe296, 0x8b88, 0xe295, 0xe2a2, 0xe294, 0x8fce,
+ 0xe298, 0xe299, 0x934a, 0xe29a, 0x8a7d, 0x9079, 0x9584, 0xe29c,
+ 0x91e6, 0xe297, 0xe29b, 0xe29d, 0x8df9, 0xe2a4, 0x954d, 0x94a4,
+ 0x9399, 0x8bd8, 0xe2a3, 0xe2a1, 0x94b3, 0xe29e, 0x927d, 0x939b,
+ 0x939a, 0x8df4, 0xe2b6, 0xe2a6, 0xe2a8, 0xe2ab, 0xe2ac, 0xe2a9,
+ 0xe2aa, 0xe2a7, 0xe2a5, 0xe29f, 0x95cd, 0x89d3, 0xe2b3, 0xe2b0,
+ 0xe2b5, 0xe2b4, 0x9493, 0x96a5, 0x8e5a, 0xe2ae, 0xe2b7, 0xe2b2,
+ 0xe2b1, 0xe2ad, 0xe2af, 0x8ac7, 0x925c, 0x90fb, 0x94a0, 0xe2bc,
+ 0x94a2, 0x90df, 0xe2b9, 0x94cd, 0xe2bd, 0x95d1, 0x927a, 0xe2b8,
+ 0xe2ba, 0xe2bb, 0xe2be, 0x8ec2, 0x93c4, 0xe2c3, 0xe2c2, 0xe2bf,
+ 0x9855, 0xe2c8, 0xe2cc, 0xe2c9, 0xe2c5, 0xe2c6, 0xe2cb, 0xe2c0,
+ 0x99d3, 0xe2c7, 0xe2c1, 0xe2ca, 0xe2d0, 0x8ac8, 0xe2cd, 0xe2ce,
+ 0xe2cf, 0xe2d2, 0xe2d1, 0x94f4, 0xe2d3, 0x97fa, 0x95eb, 0xe2d8,
+ 0xe2d5, 0xe2d4, 0x90d0, 0xe2d7, 0xe2d9, 0xe2d6, 0xe2dd, 0xe2da,
+ 0xe2db, 0xe2c4, 0xe2dc, 0xe2de, 0xe2df, 0x95c4, 0xe2e0, 0x96e0,
+ 0x8bcc, 0x8c48, 0xe2e1, 0x95b2, 0x9088, 0x96ae, 0xe2e2, 0x97b1,
+ 0x9494, 0x9165, 0x9453, 0x8f6c, 0x88be, 0xe2e7, 0xe2e5, 0xe2e3,
+ 0x8a9f, 0x8fcf, 0xe2e8, 0xe2e6, 0xe2e4, 0xe2ec, 0xe2eb, 0xe2ea,
+ 0xe2e9, 0xe2ed, 0xe2ee, 0x90b8, 0xe2ef, 0xe2f1, 0xe2f0, 0x8cd0,
+ 0x9157, 0xe2f3, 0x939c, 0xe2f2, 0xe2f4, 0x95b3, 0x918c, 0x8d66,
+ 0xe2f5, 0x97c6, 0xe2f7, 0xe2f8, 0xe2f9, 0xe2fa, 0x8e85, 0xe2fb,
+ 0x8c6e, 0x8b8a, 0x8b49, 0xe340, 0x96f1, 0x8d67, 0xe2fc, 0xe343,
+ 0x96e4, 0x945b, 0x9552, 0x8f83, 0xe342, 0x8ed1, 0x8d68, 0x8e86,
+ 0x8b89, 0x95b4, 0xe341, 0x9166, 0x9661, 0x8df5, 0x8e87, 0x92db,
+ 0xe346, 0x97dd, 0x8dd7, 0xe347, 0x9061, 0xe349, 0x8fd0, 0x8dae,
+ 0xe348, 0x8f49, 0x8cbc, 0x9167, 0xe344, 0xe34a, 0xe345, 0x8c6f,
+ 0xe34d, 0xe351, 0x8c8b, 0xe34c, 0xe355, 0x8d69, 0x978d, 0x88ba,
+ 0xe352, 0x8b8b, 0xe34f, 0xe350, 0x939d, 0xe34e, 0xe34b, 0x8a47,
+ 0x90e2, 0x8ca6, 0xe357, 0xe354, 0xe356, 0xe353, 0x8c70, 0x91b1,
+ 0xe358, 0x918e, 0xe365, 0xe361, 0xe35b, 0xe35f, 0x8ef8, 0x88db,
+ 0xe35a, 0xe362, 0xe366, 0x8d6a, 0x96d4, 0x92d4, 0xe35c, 0xe364,
+ 0xe359, 0x925d, 0xe35e, 0x88bb, 0x96c8, 0xe35d, 0x8bd9, 0x94ea,
+ 0x918d, 0x97ce, 0x8f8f, 0xe38e, 0xe367, 0x90fc, 0xe363, 0xe368,
+ 0xe36a, 0x92f7, 0xe36d, 0xe369, 0x95d2, 0x8ac9, 0x96c9, 0x88dc,
+ 0xe36c, 0x97fb, 0xe36b, 0x898f, 0x93ea, 0xe36e, 0xe375, 0xe36f,
+ 0xe376, 0xe372, 0x949b, 0x8ec8, 0xe374, 0xe371, 0xe377, 0xe370,
+ 0x8f63, 0x9644, 0x8f6b, 0xe373, 0xe380, 0xe37b, 0xe37e, 0xe37c,
+ 0xe381, 0xe37a, 0xe360, 0x90d1, 0x94c9, 0xe37d, 0xe378, 0x9140,
+ 0x8c71, 0x8f4a, 0x9044, 0x9155, 0xe384, 0xe386, 0xe387, 0xe383,
+ 0xe385, 0xe379, 0xe382, 0xe38a, 0xe389, 0x969a, 0x8c4a, 0xe388,
+ 0xe38c, 0xe38b, 0xe38f, 0xe391, 0x8e5b, 0xe38d, 0xe392, 0xe393,
+ 0xe394, 0xe39a, 0x935a, 0xe396, 0xe395, 0xe397, 0xe398, 0xe399,
+ 0xe39b, 0xe39c, 0x8aca, 0xe39d, 0xe39e, 0xe39f, 0xe3a0, 0xe3a1,
+ 0xe3a2, 0xe3a3, 0xe3a4, 0xe3a6, 0xe3a5, 0xe3a7, 0xe3a8, 0xe3a9,
+ 0xe3ac, 0xe3aa, 0xe3ab, 0x8ddf, 0x8c72, 0x9275, 0x94b1, 0x8f90,
+ 0x946c, 0x94eb, 0xe3ad, 0x9ceb, 0xe3ae, 0xe3b0, 0x9785, 0xe3af,
+ 0xe3b2, 0xe3b1, 0x9772, 0xe3b3, 0x94fc, 0xe3b4, 0xe3b7, 0xe3b6,
+ 0xe3b5, 0xe3b8, 0x8c51, 0x9141, 0x8b60, 0xe3bc, 0xe3b9, 0xe3ba,
+ 0xe3bd, 0xe3be, 0xe3bb, 0x8948, 0x89a5, 0xe3c0, 0xe3c1, 0xe3c2,
+ 0x9782, 0x8f4b, 0xe3c4, 0xe3c3, 0x9089, 0xe3c5, 0xe3c6, 0xe3c7,
+ 0x8ae3, 0x8acb, 0xe3c8, 0xe3c9, 0x967c, 0x9783, 0x9773, 0x9856,
+ 0x8d6c, 0xe3cc, 0x8ed2, 0xe3cb, 0xe3cd, 0x8ea7, 0x91cf, 0xe3ce,
+ 0x8d6b, 0x96d5, 0xe3cf, 0xe3d0, 0xe3d1, 0xe3d2, 0xe3d3, 0x8ea8,
+ 0x96eb, 0xe3d5, 0x925e, 0xe3d4, 0xe3d7, 0xe3d6, 0xe3d8, 0x90b9,
+ 0xe3d9, 0xe3da, 0x95b7, 0xe3db, 0x918f, 0xe3dc, 0xe3dd, 0x97fc,
+ 0xe3e0, 0xe3df, 0xe3de, 0x92ae, 0xe3e1, 0x9045, 0xe3e2, 0xe3e3,
+ 0x9857, 0xe3e4, 0xe3e5, 0xe3e7, 0xe3e6, 0x94a3, 0x93f7, 0x985d,
+ 0x94a7, 0xe3e9, 0x8fd1, 0x9549, 0xe3ea, 0xe3e8, 0x8acc, 0x8cd2,
+ 0x8e88, 0x94ec, 0x8ca8, 0x9662, 0xe3ed, 0xe3eb, 0x8d6d, 0x8d6e,
+ 0x88e7, 0x8de6, 0x9478, 0x88dd, 0xe3f2, 0x925f, 0x9477, 0x91d9,
+ 0xe3f4, 0xe3f0, 0xe3f3, 0xe3ee, 0xe3f1, 0x9645, 0x8cd3, 0x88fb,
+ 0xe3ef, 0xe3f6, 0xe3f7, 0x93b7, 0x8bb9, 0xe445, 0x945c, 0x8e89,
+ 0x8bba, 0x90c6, 0x9865, 0x96ac, 0xe3f5, 0x90d2, 0x8b72, 0xe3f8,
+ 0xe3fa, 0xe3f9, 0xe3fb, 0x9245, 0x945d, 0x92af, 0xe442, 0xe441,
+ 0xe3fc, 0x9074, 0x9585, 0xe444, 0xe443, 0x8d6f, 0x9872, 0xe454,
+ 0xe448, 0xe449, 0x8eee, 0xe447, 0x8d98, 0xe446, 0xe44a, 0x92b0,
+ 0x95a0, 0x9142, 0x91da, 0xe44e, 0xe44f, 0xe44b, 0xe44c, 0xe44d,
+ 0x8d70, 0xe455, 0xe451, 0x9586, 0x968c, 0x9547, 0xe450, 0xe453,
+ 0xe452, 0x9663, 0xe456, 0xe457, 0x9156, 0xe458, 0xe45a, 0xe45e,
+ 0xe45b, 0xe459, 0x945e, 0xe45c, 0xe45d, 0x89b0, 0xe464, 0xe45f,
+ 0xe460, 0xe461, 0x919f, 0xe463, 0xe462, 0xe465, 0xe466, 0xe467,
+ 0x9062, 0x89e7, 0xe468, 0x97d5, 0x8ea9, 0x8f4c, 0x8e8a, 0x9276,
+ 0xe469, 0xe46a, 0x8950, 0xe46b, 0xe46c, 0xe46d, 0xe46e, 0xe46f,
+ 0x8bbb, 0x9da8, 0xe470, 0x90e3, 0xe471, 0x8ec9, 0xe472, 0x98ae,
+ 0xe473, 0x95dc, 0x8ada, 0x9143, 0x8f77, 0x9591, 0x8f4d, 0xe474,
+ 0x8d71, 0xe475, 0x94ca, 0xe484, 0xe477, 0x91c7, 0x9495, 0x8cbd,
+ 0xe476, 0x9144, 0xe478, 0x92f8, 0xe47a, 0xe479, 0xe47c, 0xe47b,
+ 0xe47d, 0xe480, 0xe47e, 0x8acd, 0xe481, 0xe482, 0xe483, 0x8daf,
+ 0x97c7, 0xe485, 0x9046, 0x8990, 0xe486, 0xe487, 0xe488, 0x88f0,
+ 0xe489, 0xe48a, 0x9587, 0x8ec5, 0xe48c, 0x8a48, 0x88b0, 0xe48b,
+ 0xe48e, 0x946d, 0x9063, 0x89d4, 0x9646, 0x8c7c, 0x8bda, 0xe48d,
+ 0x89e8, 0x8aa1, 0x8991, 0xe492, 0x97e8, 0x91db, 0x9563, 0xe49e,
+ 0x89d5, 0xe49c, 0xe49a, 0xe491, 0xe48f, 0xe490, 0x8ee1, 0x8bea,
+ 0x9297, 0x93cf, 0x8970, 0xe494, 0xe493, 0xe499, 0xe495, 0xe498,
+ 0x96ce, 0xe497, 0x89d6, 0x8a9d, 0xe49b, 0xe49d, 0x8c73, 0xe4a1,
+ 0xe4aa, 0xe4ab, 0x88a9, 0xe4b2, 0x88ef, 0xe4a9, 0xe4a8, 0xe4a3,
+ 0xe4a2, 0xe4a0, 0xe49f, 0x9283, 0x91f9, 0xe4a5, 0xe4a4, 0xe4a7,
+ 0x9190, 0x8c74, 0x8960, 0xe4a6, 0x8d72, 0x9191, 0xe4b8, 0xe4b9,
+ 0x89d7, 0x89ac, 0xe4b6, 0xe4ac, 0xe4b4, 0xe4bb, 0xe4b5, 0xe4b3,
+ 0xe496, 0xe4b1, 0xe4ad, 0x8ace, 0xe4af, 0xe4ba, 0xe4b0, 0xe4bc,
+ 0xe4ae, 0x949c, 0x9789, 0xe4b7, 0xe4cd, 0xe4c5, 0x909b, 0x8b65,
+ 0x8bdb, 0xe4c0, 0x89d9, 0x8fd2, 0xe4c3, 0x8dd8, 0x9370, 0xe4c8,
+ 0x95ec, 0xe4bf, 0x89d8, 0x8cd4, 0x9548, 0xe4c9, 0xe4bd, 0xe4c6,
+ 0xe4d0, 0xe4c1, 0xe4c2, 0x93b8, 0xe4c7, 0xe4c4, 0x9647, 0xe4ca,
+ 0x88de, 0xe4be, 0xe4cc, 0xe4cb, 0x948b, 0xe4d2, 0xe4dd, 0x8a9e,
+ 0xe4e0, 0xe4ce, 0xe4d3, 0x978e, 0xe4dc, 0x9774, 0x97a8, 0x9298,
+ 0x8a8b, 0x9592, 0xe4e2, 0x939f, 0x88af, 0xe4db, 0xe4d7, 0x9192,
+ 0xe4d1, 0xe4d9, 0xe4de, 0x944b, 0x88a8, 0xe4d6, 0xe4df, 0x9598,
+ 0xe4da, 0xe4d5, 0x8fd3, 0x8f4e, 0x8eaa, 0x96d6, 0x9566, 0xe4e5,
+ 0xe4ee, 0xe4d8, 0x8a97, 0x8ff6, 0xe4e3, 0xe4e8, 0x9193, 0xe4e4,
+ 0xe4eb, 0x927e, 0xe4ec, 0x9775, 0xe4e1, 0x8a57, 0xe4e7, 0xe4ea,
+ 0x96aa, 0xe4ed, 0xe4e6, 0xe4e9, 0x9648, 0x9840, 0xe4f1, 0xe4f8,
+ 0xe4f0, 0x8ec1, 0xe4cf, 0x95cc, 0x96a0, 0xe4f7, 0xe4f6, 0xe4f2,
+ 0xe4f3, 0x8955, 0xe4f5, 0xe4ef, 0x92d3, 0xe4f4, 0x88fc, 0x91a0,
+ 0x95c1, 0xe4f9, 0xe540, 0x94d7, 0xe4fc, 0x8fd4, 0x8ec7, 0xe542,
+ 0x8bbc, 0xe543, 0x9599, 0xe4fb, 0xe4d4, 0xe4fa, 0x986e, 0x93a0,
+ 0x9593, 0xe54a, 0xe550, 0xe551, 0xe544, 0x9496, 0xe54e, 0xe546,
+ 0xe548, 0xe552, 0xe547, 0xe54b, 0x8992, 0x93e3, 0xe54c, 0xe54f,
+ 0xe545, 0x9145, 0xe549, 0x8e46, 0x9064, 0x8c4f, 0x96f2, 0x96f7,
+ 0x8f92, 0xe556, 0xe554, 0x986d, 0xe553, 0x9795, 0xe555, 0xe557,
+ 0xe558, 0xe55b, 0xe559, 0x93a1, 0xe55a, 0x94cb, 0xe54d, 0x8f93,
+ 0xe55c, 0xe561, 0x9194, 0xe560, 0xe541, 0xe562, 0x9168, 0xe55d,
+ 0xe55f, 0xe55e, 0x9f50, 0x9f41, 0xe564, 0xe563, 0x9796, 0xe1ba,
+ 0xe565, 0xe566, 0xe567, 0x8cd5, 0x8b73, 0xe569, 0x997c, 0x8b95,
+ 0x97b8, 0x8bf1, 0xe56a, 0xe56b, 0x928e, 0xe56c, 0x93f8, 0x88b8,
+ 0x89e1, 0xe571, 0xe572, 0xe56d, 0x8e5c, 0xe56e, 0x9461, 0xe56f,
+ 0xe570, 0xe57a, 0xe574, 0xe577, 0xe573, 0xe575, 0xe576, 0x8ed6,
+ 0xe578, 0x9260, 0x8c75, 0x8a61, 0xe57b, 0x8a5e, 0xe581, 0xe57c,
+ 0xe580, 0x94b8, 0xe57d, 0xe57e, 0x9567, 0x94d8, 0xe582, 0x91fb,
+ 0xe58c, 0xe588, 0x89e9, 0xe586, 0x9649, 0xe587, 0xe584, 0xe585,
+ 0xe58a, 0xe58d, 0xe58b, 0xe589, 0xe583, 0x9277, 0xe594, 0x96a8,
+ 0xe592, 0xe593, 0xe58e, 0xe590, 0xe591, 0xe58f, 0x90e4, 0x9858,
+ 0xe598, 0xe599, 0xe59f, 0x9049, 0xe59b, 0xe59e, 0xe596, 0xe595,
+ 0xe5a0, 0x89da, 0xe59c, 0xe5a1, 0xe59d, 0xe59a, 0x92b1, 0xe597,
+ 0x9488, 0xe5a5, 0x975a, 0xe5a4, 0xe5a3, 0xe5ac, 0xe5a6, 0xe5ae,
+ 0x9786, 0xe5b1, 0xe5a8, 0xe5a9, 0xe5ad, 0xe5b0, 0xe5af, 0xe5a7,
+ 0xe5aa, 0xe5bb, 0xe5b4, 0xe5b2, 0xe5b3, 0xe5b8, 0xe5b9, 0x8a49,
+ 0x8b61, 0xe5b7, 0xe5a2, 0xe5b6, 0xe5ba, 0xe5b5, 0xe5bc, 0xe5be,
+ 0xe5bd, 0xe5c0, 0xe5bf, 0xe579, 0xe5c4, 0xe5c1, 0xe5c2, 0xe5c3,
+ 0xe5c5, 0x8c8c, 0xe5c7, 0xe5c6, 0x8f4f, 0x8d73, 0x9fa5, 0xe5c8,
+ 0x8f70, 0x8a58, 0xe5c9, 0x8971, 0x8fd5, 0xe5ca, 0x8d74, 0xe5cb,
+ 0x88df, 0x955c, 0xe5cc, 0x908a, 0xe5d3, 0xe5d0, 0x928f, 0xe5d1,
+ 0xe5ce, 0x8bdc, 0xe5cd, 0xe5d4, 0x8c55, 0x91dc, 0xe5da, 0xe5d6,
+ 0x91b3, 0xe5d5, 0xe5d8, 0xe5cf, 0xe5d9, 0xe5db, 0x94ed, 0xe5d7,
+ 0xe5dc, 0xe5de, 0x8cd1, 0xe5d2, 0x88bf, 0xe5dd, 0x8dd9, 0x97f4,
+ 0xe5df, 0xe5e0, 0x9195, 0x97a0, 0xe5e1, 0x9754, 0xe5e2, 0xe5e3,
+ 0x95e2, 0xe5e4, 0x8dbe, 0x97a1, 0xe5e9, 0xe5ea, 0x8fd6, 0xe5e8,
+ 0x9787, 0xe5e5, 0xe5e7, 0x90bb, 0x909e, 0xe5e6, 0xe5eb, 0x95a1,
+ 0xe5ed, 0xe5ec, 0x8a8c, 0x964a, 0xe5ee, 0xe5fa, 0xe5f0, 0xe5f1,
+ 0xe5f2, 0xe5f3, 0xe5f7, 0xe5f8, 0xe5f6, 0xe5f4, 0xe5ef, 0xe5f5,
+ 0xe5f9, 0xe8b5, 0x89a6, 0xe5fc, 0x8bdd, 0xe5fb, 0xe641, 0xe640,
+ 0xe643, 0xe642, 0xe644, 0x8f50, 0xe645, 0xe646, 0xe647, 0x90bc,
+ 0x9776, 0xe648, 0x95a2, 0x9465, 0xe649, 0xe64a, 0x8ca9, 0x8b4b,
+ 0xe64b, 0x8e8b, 0x9460, 0xe64c, 0x8a6f, 0xe64d, 0xe64f, 0x9797,
+ 0xe64e, 0x9065, 0xe650, 0xe651, 0xe652, 0x8acf, 0xe653, 0xe654,
+ 0xe655, 0xe656, 0x8a70, 0xe657, 0xe658, 0xe659, 0x89f0, 0x9047,
+ 0xe65a, 0xe65b, 0xe65c, 0x8cbe, 0x92f9, 0xe65d, 0x8c76, 0x9075,
+ 0xe660, 0x93a2, 0xe65f, 0x8c50, 0xe65e, 0x91f5, 0x8b4c, 0xe661,
+ 0xe662, 0x8fd7, 0x8c8d, 0xe663, 0x964b, 0x90dd, 0x8b96, 0x96f3,
+ 0x9169, 0xe664, 0x9066, 0x9290, 0x8fd8, 0xe665, 0xe668, 0xe669,
+ 0x8dbc, 0x91c0, 0xe667, 0x8fd9, 0x955d, 0xe666, 0x8e8c, 0x8972,
+ 0xe66d, 0x8c77, 0x8e8e, 0x8e8d, 0x986c, 0xe66c, 0xe66b, 0x9146,
+ 0x8b6c, 0x9862, 0x8a59, 0x8fda, 0xe66a, 0xe66f, 0xe670, 0xe66e,
+ 0x8cd6, 0x975f, 0x8e8f, 0x9446, 0xe673, 0x90be, 0x9261, 0x9755,
+ 0xe676, 0x8cea, 0x90bd, 0xe672, 0xe677, 0x8ceb, 0xe674, 0xe675,
+ 0xe671, 0x90e0, 0x93c7, 0x924e, 0x89db, 0x94ee, 0x8b62, 0x92b2,
+ 0xe67a, 0xe678, 0x926b, 0x90bf, 0x8ad0, 0xe679, 0x907a, 0x97c8,
+ 0x985f, 0xe67b, 0xe687, 0x92b3, 0xe686, 0xe683, 0xe68b, 0xe684,
+ 0xe680, 0x92fa, 0xe67e, 0xe67c, 0x9740, 0x8e90, 0xe681, 0xe67d,
+ 0xe685, 0x8f94, 0x8cbf, 0x91f8, 0x9664, 0x8979, 0x88e0, 0x93a3,
+ 0xe689, 0xe688, 0x93e4, 0xe68d, 0xe682, 0xe68c, 0xe68e, 0x8caa,
+ 0xe68a, 0x8d75, 0x8ed3, 0xe68f, 0x9777, 0xe692, 0xe695, 0xe693,
+ 0x9554, 0xe690, 0x8bde, 0xe694, 0xe696, 0xe69a, 0xe697, 0xe699,
+ 0xe698, 0xe69b, 0x8eaf, 0xe69d, 0xe69c, 0x9588, 0xe69f, 0x8c78,
+ 0xe69e, 0xe6a0, 0xe6a1, 0x8b63, 0xe3bf, 0x8ff7, 0xe6a2, 0x8cec,
+ 0xe6a3, 0xe6a4, 0x8e5d, 0x9dcc, 0xe6a5, 0xe6a6, 0x8f51, 0xe6a7,
+ 0xe6a8, 0xe6a9, 0xe6aa, 0xe6ab, 0x924a, 0xe6ac, 0xe6ae, 0xe6ad,
+ 0x93a4, 0xe6af, 0x964c, 0xe6b0, 0xe6b1, 0xe6b2, 0xe6b3, 0x93d8,
+ 0x8fdb, 0xe6b4, 0x8d8b, 0x98ac, 0xe6b5, 0xe6b6, 0x955e, 0xe6b7,
+ 0xe6bf, 0xe6b8, 0xe6ba, 0xe6b9, 0xe6bb, 0x9665, 0xe6bc, 0xe6bd,
+ 0xe6be, 0xe6c0, 0x8a4c, 0x92e5, 0x9589, 0x8de0, 0x8d76, 0x956e,
+ 0x89dd, 0x94cc, 0xe6c3, 0x8ad1, 0x90d3, 0xe6c2, 0xe6c7, 0x9299,
+ 0x96e1, 0xe6c5, 0xe6c6, 0x8b4d, 0xe6c8, 0x9483, 0x91dd, 0x94ef,
+ 0x935c, 0xe6c4, 0x9666, 0x89ea, 0xe6ca, 0x9847, 0x92c0, 0x9864,
+ 0x8e91, 0xe6c9, 0x91af, 0xe6da, 0x9147, 0x93f6, 0x956f, 0xe6cd,
+ 0x8e5e, 0x8e92, 0x8fdc, 0x9485, 0x8cab, 0xe6cc, 0xe6cb, 0x958a,
+ 0x8ebf, 0x9371, 0xe6cf, 0xe6d0, 0x8d77, 0xe6ce, 0xe6d1, 0xe6d2,
+ 0xe6d4, 0x91a1, 0xe6d3, 0x8ae4, 0xe6d6, 0xe6d5, 0xe6d7, 0xe6d9,
+ 0xe6db, 0xe6dc, 0x90d4, 0x8ecd, 0xe6dd, 0x8a71, 0xe6de, 0x9196,
+ 0xe6df, 0xe6e0, 0x958b, 0x8b4e, 0xe6e1, 0x92b4, 0x897a, 0xe6e2,
+ 0x8eef, 0x9096, 0x91ab, 0xe6e5, 0xe6e4, 0xe6e3, 0xe6eb, 0xe6e9,
+ 0xe6e6, 0xe6e8, 0xe6e7, 0xe6ea, 0x8b97, 0xe6ee, 0x90d5, 0xe6ef,
+ 0x8cd7, 0xe6ec, 0xe6ed, 0x9848, 0x92b5, 0x9148, 0xe6f0, 0xe6f3,
+ 0xe6f1, 0xe6f2, 0x9778, 0x93a5, 0xe6f6, 0xe6f4, 0xe6f5, 0xe6f7,
+ 0xe748, 0xe6fa, 0xe6fb, 0xe6f9, 0xe6f8, 0x92fb, 0xe740, 0xe744,
+ 0xe741, 0xe6fc, 0xe742, 0xe743, 0xe74a, 0xe745, 0x90d6, 0xe747,
+ 0xe749, 0xe746, 0xe74c, 0x8f52, 0xe74b, 0xe74d, 0xe74e, 0xe751,
+ 0xe750, 0xe74f, 0xe753, 0xe752, 0x96f4, 0xe755, 0xe754, 0xe756,
+ 0xe757, 0xe759, 0xe758, 0x9067, 0xe75a, 0x8beb, 0xe75b, 0xe75d,
+ 0xe75e, 0xe75f, 0xe75c, 0xe760, 0x8ed4, 0xe761, 0x8b4f, 0x8c52,
+ 0x8cac, 0xe762, 0x93ee, 0x935d, 0xe763, 0xe766, 0x8eb2, 0xe765,
+ 0xe764, 0x8c79, 0xe767, 0x8a72, 0xe769, 0x8dda, 0xe768, 0xe771,
+ 0xe76b, 0xe76d, 0x95e3, 0xe76a, 0xe76c, 0xe770, 0xe76e, 0x8b50,
+ 0xe76f, 0xe772, 0x9479, 0x97d6, 0x8f53, 0xe773, 0x9741, 0xe775,
+ 0xe774, 0xe778, 0x9760, 0xe777, 0x8a8d, 0xe776, 0xe77b, 0xe77a,
+ 0xe779, 0x9351, 0xe77c, 0xe77d, 0xe77e, 0x8d8c, 0x8c44, 0xe780,
+ 0xe781, 0xe782, 0x9068, 0xe783, 0x8eab, 0xe784, 0xe785, 0x999f,
+ 0x999e, 0xe786, 0xe390, 0xe787, 0x9243, 0x904a, 0x945f, 0xe788,
+ 0x95d3, 0x92d2, 0x8d9e, 0x9248, 0x8949, 0x9698, 0x9076, 0x8c7d,
+ 0x8bdf, 0x95d4, 0xe789, 0xe78b, 0xe78a, 0x89de, 0x93f4, 0xe78c,
+ 0x9497, 0x9352, 0xe78d, 0x8f71, 0xe78f, 0x96c0, 0xe79e, 0xe791,
+ 0xe792, 0x92c7, 0x91de, 0x9197, 0x93a6, 0xe790, 0x8b74, 0xe799,
+ 0xe796, 0xe7a3, 0x93a7, 0x9280, 0xe793, 0x92fc, 0x9372, 0xe794,
+ 0xe798, 0x9080, 0x9487, 0x92ca, 0x90c0, 0xe797, 0x91ac, 0x91a2,
+ 0xe795, 0x88a7, 0x9841, 0xe79a, 0x91df, 0x8f54, 0x9069, 0xe79c,
+ 0xe79b, 0x88ed, 0xe79d, 0x954e, 0xe7a5, 0x93d9, 0x908b, 0x9278,
+ 0x8bf6, 0xe7a4, 0x9756, 0x895e, 0x95d5, 0x89df, 0xe79f, 0xe7a0,
+ 0xe7a1, 0xe7a2, 0x93b9, 0x9242, 0x88e1, 0xe7a6, 0xe7a7, 0xeaa1,
+ 0x91bb, 0xe7a8, 0x8993, 0x916b, 0x8cad, 0x9779, 0xe7a9, 0x934b,
+ 0x9198, 0x8ed5, 0xe7aa, 0xe7ad, 0x8f85, 0xe7ab, 0x914a, 0x9149,
+ 0x88e2, 0x97c9, 0xe7af, 0x94f0, 0xe7b1, 0xe7b0, 0xe7ae, 0xe284,
+ 0x8ad2, 0xe78e, 0xe7b3, 0xe7b2, 0xe7b4, 0x9757, 0x93df, 0x964d,
+ 0xe7b5, 0x8ed7, 0xe7b6, 0xe7b7, 0xe7b8, 0x9340, 0x88e8, 0x8d78,
+ 0x9859, 0xe7bc, 0x8c53, 0xe7b9, 0xe7ba, 0x9594, 0x8a73, 0x9758,
+ 0x8bbd, 0x9373, 0xe7bd, 0xe7be, 0xe7bf, 0x9341, 0xe7c1, 0xe7c0,
+ 0x93d1, 0xe7c2, 0x8f55, 0x8ede, 0x947a, 0x9291, 0x8ef0, 0x908c,
+ 0xe7c3, 0xe7c4, 0x907c, 0xe7c5, 0xe7c6, 0xe7c7, 0x978f, 0x8f56,
+ 0xe7c9, 0xe7c8, 0x8d79, 0x8d93, 0x8e5f, 0xe7cc, 0x8f86, 0xe7cb,
+ 0xe7ca, 0x91e7, 0x8ced, 0x90c1, 0x94ae, 0x8f58, 0xe7cd, 0x8fdd,
+ 0xe7d0, 0xe7ce, 0xe7cf, 0xe7d2, 0xe7d1, 0x8ff8, 0xe7d3, 0xe7d4,
+ 0xe7d5, 0x94ce, 0x8dd1, 0x8edf, 0xe7d6, 0xe7d7, 0x97a2, 0x8f64,
+ 0x96ec, 0x97ca, 0xe7d8, 0x8be0, 0xe7d9, 0x9342, 0xe7dc, 0x8a98,
+ 0x906a, 0xe7da, 0xe7db, 0x92de, 0x9674, 0x8bfa, 0xe7de, 0xe7df,
+ 0xe7dd, 0xe7e1, 0x93dd, 0x8a62, 0xe7e5, 0xe7e2, 0xe7e4, 0xe7e0,
+ 0xe86e, 0xe7e3, 0x97e9, 0x8cd8, 0xe7ed, 0x9353, 0xe7e8, 0xe7eb,
+ 0xe7e9, 0xe7ee, 0xe7ef, 0xe7e7, 0xe7f4, 0x8994, 0xe7e6, 0x94ab,
+ 0xe7ea, 0x8fde, 0x8d7a, 0x9667, 0x8be2, 0x8f65, 0x93ba, 0x914c,
+ 0xe7f2, 0xe7ec, 0xe7f1, 0x96c1, 0x92b6, 0xe7f3, 0xe7f0, 0x914b,
+ 0xe7f7, 0xe7f6, 0xe7f5, 0x964e, 0x8f9b, 0xe7f8, 0x95dd, 0x8973,
+ 0x9565, 0x9292, 0x8b98, 0xe7fa, 0x8d7c, 0x8e4b, 0xe7f9, 0x908d,
+ 0x908e, 0xe840, 0xe842, 0x8ff9, 0xe841, 0xe843, 0x8bd1, 0x9564,
+ 0x8ee0, 0x9842, 0xe7fc, 0x8df6, 0x985e, 0xe845, 0xe844, 0xe846,
+ 0xe7fb, 0x93e7, 0x9374, 0x92d5, 0xe84b, 0x9262, 0xe847, 0xe848,
+ 0x8c4c, 0xe84a, 0x8cae, 0xe849, 0x8fdf, 0x8a99, 0xe84f, 0x8dbd,
+ 0x9199, 0x92c8, 0x8a5a, 0xe84d, 0xe84e, 0x92c1, 0xe84c, 0xe850,
+ 0xe856, 0xe859, 0xe858, 0x934c, 0xe851, 0xe852, 0xe855, 0xe857,
+ 0x8bbe, 0xe85a, 0xe854, 0xe853, 0xe85e, 0xe85f, 0xe860, 0xe85d,
+ 0xe85c, 0x8fe0, 0x93a8, 0xe85b, 0xe864, 0xe862, 0xe863, 0xe861,
+ 0x91f6, 0xe865, 0xe866, 0xe868, 0x8ad3, 0xe867, 0x96f8, 0xe873,
+ 0xe869, 0xe86c, 0xe86a, 0xe86b, 0xe86d, 0xe86f, 0xe870, 0xe871,
+ 0xe874, 0xe872, 0xe875, 0xe877, 0xe876, 0x92b7, 0x96e5, 0xe878,
+ 0x914d, 0xe879, 0x95c2, 0xe87a, 0x8a4a, 0x895b, 0x8ad5, 0x8ad4,
+ 0xe87b, 0xe87c, 0xe87d, 0xe87e, 0xe880, 0x8ad6, 0x8a74, 0x8d7d,
+ 0x94b4, 0xe882, 0xe881, 0xe883, 0x897b, 0xe886, 0xe885, 0xe884,
+ 0xe887, 0xe88a, 0x88c5, 0xe888, 0xe88c, 0xe88b, 0xe88e, 0xe88d,
+ 0xe88f, 0x93ac, 0xe890, 0xe891, 0xe893, 0xe892, 0x958c, 0xe894,
+ 0xe895, 0x8de3, 0xe896, 0xe897, 0x9668, 0x916a, 0x88a2, 0x91c9,
+ 0xe898, 0x958d, 0xe89b, 0xe899, 0x8d7e, 0xe89a, 0x8cc0, 0x95c3,
+ 0xe89d, 0xe89f, 0xe89e, 0xe8a0, 0x8940, 0x9077, 0x8f9c, 0x8ad7,
+ 0xe8a1, 0x9486, 0xe8a3, 0x8941, 0xe8a2, 0x92c2, 0x97cb, 0x93a9,
+ 0xe89c, 0x97a4, 0x8caf, 0x977a, 0x8bf7, 0x97b2, 0x8c47, 0x91e0,
+ 0xe440, 0xe8a4, 0x8a4b, 0x908f, 0x8a75, 0xe8a6, 0xe8a7, 0xe8a5,
+ 0x8c84, 0x8ddb, 0x8fe1, 0x8942, 0x97d7, 0xe8a9, 0xe7ac, 0xe8a8,
+ 0xe8ac, 0xe8aa, 0xe8ab, 0xe8ad, 0xe8ae, 0x97ea, 0xe8af, 0xe8b0,
+ 0x90c7, 0x94b9, 0x909d, 0x8ae5, 0x9759, 0x89eb, 0x8f57, 0x8cd9,
+ 0xe8b3, 0xe8b2, 0x8e93, 0xe8b4, 0xe8b1, 0x8e47, 0xe8b8, 0xe5ab,
+ 0x99d4, 0x9097, 0xe8b6, 0x97a3, 0x93ef, 0x894a, 0x90e1, 0x8eb4,
+ 0x95b5, 0x895f, 0x97eb, 0x978b, 0xe8b9, 0x9364, 0x8ef9, 0xe8ba,
+ 0xe8bb, 0x906b, 0xe8bc, 0x97ec, 0xe8b7, 0xe8be, 0xe8c0, 0xe8bf,
+ 0xe8bd, 0xe8c1, 0xe8c2, 0x919a, 0x89e0, 0xe8c3, 0x96b6, 0xe8c4,
+ 0xe8c5, 0x9849, 0x9e50, 0xe8c6, 0xe8c7, 0xe8c8, 0xe8cc, 0xe8c9,
+ 0xe8ca, 0xe8cb, 0xe8cd, 0x90c2, 0x96f5, 0x90c3, 0xe8ce, 0x94f1,
+ 0xe8cf, 0xea72, 0x96ca, 0xe8d0, 0xe8d1, 0xe8d2, 0x8a76, 0xe8d4,
+ 0x9078, 0xe8d5, 0x8c43, 0xe8d6, 0xe8da, 0xe8d8, 0xe8d9, 0x8a93,
+ 0xe8d7, 0xe8db, 0xe8dc, 0x88c6, 0xe8dd, 0xe8de, 0x8fe2, 0xe8df,
+ 0x8b66, 0xe8e2, 0xe8e1, 0xe8e0, 0xe691, 0x95da, 0xe8e3, 0xe8e4,
+ 0xe8e5, 0xe8e6, 0xe8e7, 0xe8e8, 0x8ad8, 0xe8e9, 0xe8ea, 0x9442,
+ 0xe8ec, 0x89b9, 0xe8ef, 0xe8ee, 0x8943, 0x8bbf, 0x95c5, 0x92b8,
+ 0x8da0, 0x8d80, 0x8f87, 0x907b, 0xe8f1, 0xe8f0, 0x9761, 0x8ae6,
+ 0x94d0, 0x93da, 0x909c, 0x97cc, 0x8c7a, 0xe8f4, 0xe8f3, 0x966a,
+ 0x93aa, 0x896f, 0xe8f5, 0xe8f2, 0x9570, 0x978a, 0xe8f6, 0xe8f7,
+ 0xe8f9, 0x91e8, 0x8a7a, 0x8a7b, 0xe8f8, 0x8ae7, 0x8cb0, 0x8ae8,
+ 0x935e, 0x97de, 0x8cda, 0xe8fa, 0xe8fb, 0xe8fc, 0xe940, 0xe942,
+ 0xe941, 0x9597, 0xe943, 0xe944, 0xe945, 0xe946, 0xe948, 0xe947,
+ 0xe949, 0x94f2, 0xe3ca, 0x9048, 0x8b51, 0xe94a, 0xe94b, 0x99aa,
+ 0x9f5a, 0x94d1, 0x88f9, 0x88b9, 0x8e94, 0x964f, 0x8ffc, 0xe94c,
+ 0x96dd, 0xe94d, 0x977b, 0x8961, 0x8e60, 0xe94e, 0x89ec, 0xe94f,
+ 0xe950, 0xe952, 0xe953, 0xe955, 0xe951, 0xe954, 0x8ad9, 0xe956,
+ 0xe957, 0xe958, 0xe959, 0xe95a, 0xe95c, 0xe95b, 0xe95e, 0xe961,
+ 0xe95d, 0xe95f, 0xe960, 0xe962, 0x8bc0, 0x8ef1, 0xe963, 0xe964,
+ 0x8d81, 0xe965, 0x8a5d, 0x946e, 0xe966, 0xe967, 0x9279, 0x93e9,
+ 0xe968, 0x949d, 0x91ca, 0x8977, 0x8bec, 0x8bed, 0x9293, 0xe96d,
+ 0x8bee, 0x89ed, 0xe96c, 0xe96a, 0xe96b, 0xe969, 0xe977, 0xe96e,
+ 0xe96f, 0xe970, 0xe971, 0xe973, 0xe972, 0x8f78, 0xe974, 0xe976,
+ 0x8b52, 0xe975, 0x919b, 0x8cb1, 0xe978, 0x91cb, 0xe979, 0x93ab,
+ 0xe97a, 0xe980, 0xe97d, 0xe97c, 0xe97e, 0xe97b, 0xe982, 0xe981,
+ 0xe984, 0x8bc1, 0xe983, 0xe985, 0xe986, 0xe988, 0xe987, 0xe989,
+ 0xe98b, 0xe98a, 0x8d9c, 0xe98c, 0xe98d, 0x8a5b, 0xe98e, 0xe98f,
+ 0x9091, 0xe990, 0xe991, 0xe992, 0xe993, 0x8d82, 0xe994, 0xe995,
+ 0xe996, 0xe997, 0xe998, 0x94af, 0xe99a, 0x9545, 0xe99b, 0xe999,
+ 0xe99d, 0xe99c, 0xe99e, 0xe99f, 0xe9a0, 0xe9a1, 0xe9a2, 0xe9a3,
+ 0xe9a4, 0xe9a5, 0xe9a6, 0xe9a7, 0xe9a8, 0xe9a9, 0xe9aa, 0xe9ab,
+ 0xe9ac, 0x9f54, 0xe9ad, 0xe2f6, 0x8b53, 0x8a40, 0x8db0, 0xe9af,
+ 0xe9ae, 0x96a3, 0xe9b1, 0xe9b2, 0xe9b0, 0xe9b3, 0x9682, 0xe9b4,
+ 0x8b9b, 0x9844, 0xe9b5, 0xe9b7, 0x88bc, 0xe9b8, 0x95a9, 0xe9b6,
+ 0xe9b9, 0xe9ba, 0xe9bb, 0xe9bc, 0xe9bd, 0x968e, 0x8e4c, 0x8df8,
+ 0x914e, 0xe9be, 0xe9c1, 0xe9bf, 0xe9c2, 0x8cef, 0xe9c0, 0xe9c3,
+ 0xe9c4, 0xe9c5, 0xe9c9, 0x8e49, 0x91e2, 0xe9ca, 0xe9c7, 0xe9c6,
+ 0xe9c8, 0x8c7e, 0xe9ce, 0xe9cd, 0xe9cc, 0x88b1, 0xe9d8, 0xe9d4,
+ 0xe9d5, 0xe9d1, 0xe9d7, 0xe9d3, 0x8a82, 0x986b, 0xe9d6, 0xe9d2,
+ 0xe9d0, 0xe9cf, 0xe9da, 0xe9dd, 0xe9dc, 0xe9db, 0x9568, 0xe9d9,
+ 0x88f1, 0xe9de, 0xe9e0, 0x8a8f, 0xe9cb, 0x8956, 0xe9e2, 0xe9e1,
+ 0xe9df, 0x924c, 0x9690, 0x97d8, 0xe9e3, 0xe9e4, 0xe9e5, 0xe9e6,
+ 0xe9e7, 0x92b9, 0xe9e8, 0x94b5, 0xe9ed, 0xe9e9, 0xe9ea, 0x9650,
+ 0x96c2, 0x93ce, 0xe9ee, 0xe9ef, 0x93bc, 0xe9ec, 0xe9eb, 0x89a8,
+ 0xe9f7, 0xe9f6, 0x8995, 0xe9f4, 0xe9f3, 0xe9f1, 0x8a9b, 0xe9f0,
+ 0x8eb0, 0x89a7, 0x8d83, 0xe9fa, 0xe9f9, 0xe9f8, 0xe9f5, 0xe9fb,
+ 0xe9fc, 0xea44, 0xea43, 0xea45, 0x894c, 0xea40, 0xea41, 0x8d94,
+ 0x96b7, 0xea42, 0x9651, 0xea4a, 0xea46, 0xea4b, 0xea48, 0xea47,
+ 0x8c7b, 0xea4c, 0xea4d, 0xea4e, 0xea49, 0xe9f2, 0xea4f, 0x92df,
+ 0xea53, 0xea54, 0xea52, 0xea51, 0xea57, 0xea50, 0xea55, 0xea56,
+ 0xea59, 0xea58, 0xea5b, 0xea5c, 0xea5d, 0x9868, 0xea5a, 0x91e9,
+ 0x8deb, 0xea5e, 0xea5f, 0xea60, 0xea61, 0xea62, 0x8cb2, 0xea63,
+ 0xea64, 0x8ead, 0xea65, 0xea66, 0xea67, 0xea68, 0xea6b, 0xea69,
+ 0x985b, 0xea6a, 0x97ed, 0xea6c, 0x97d9, 0xea6d, 0x949e, 0xea6e,
+ 0xea70, 0xea71, 0xea6f, 0x8d8d, 0x96cb, 0x9683, 0x9bf5, 0x9f80,
+ 0x969b, 0x89a9, 0xea73, 0x8b6f, 0xea74, 0xea75, 0xea76, 0x8d95,
+ 0xea77, 0xe0d2, 0x96d9, 0x91e1, 0xea78, 0xea7a, 0xea79, 0xea7b,
+ 0xea7c, 0xea7d, 0xea7e, 0xea80, 0xea81, 0xea82, 0xea83, 0xea84,
+ 0xea85, 0xea86, 0xea87, 0xea88, 0x9343, 0x8cdb, 0xea8a, 0x916c,
+ 0xea8b, 0xea8c, 0x9540, 0xea8d, 0xea8e, 0xe256, 0xe6d8, 0xe8eb,
+ 0xea8f, 0xea90, 0xea92, 0xea93, 0xea94, 0x97ee, 0xea91, 0xea95,
+ 0xea96, 0xea98, 0xea97, 0xea9a, 0xea9b, 0xea99, 0x97b4, 0xea9c,
+ 0xea9d, 0xe273, 0xea9e, 0x8149, 0x8194, 0x8190, 0x8193, 0x8195,
+ 0x8169, 0x816a, 0x8196, 0x817b, 0x8143, 0x8144, 0x815e, 0x824f,
+ 0x8250, 0x8251, 0x8252, 0x8253, 0x8254, 0x8255, 0x8256, 0x8257,
+ 0x8258, 0x8146, 0x8147, 0x8183, 0x8181, 0x8184, 0x8148, 0x8197,
+ 0x8260, 0x8261, 0x8262, 0x8263, 0x8264, 0x8265, 0x8266, 0x8267,
+ 0x8268, 0x8269, 0x826a, 0x826b, 0x826c, 0x826d, 0x826e, 0x826f,
+ 0x8270, 0x8271, 0x8272, 0x8273, 0x8274, 0x8275, 0x8276, 0x8277,
+ 0x8278, 0x8279, 0x816d, 0x815f, 0x816e, 0x814f, 0x8151, 0x814d,
+ 0x8281, 0x8282, 0x8283, 0x8284, 0x8285, 0x8286, 0x8287, 0x8288,
+ 0x8289, 0x828a, 0x828b, 0x828c, 0x828d, 0x828e, 0x828f, 0x8290,
+ 0x8291, 0x8292, 0x8293, 0x8294, 0x8295, 0x8296, 0x8297, 0x8298,
+ 0x8299, 0x829a, 0x816f, 0x8162, 0x8170, 0x8150, 0x818f,
+};
+
+typedef struct {
+ unsigned short indx; /* index into big table */
+ unsigned short used; /* bitmask of used entries */
+} Summary16;
+
+static const Summary16 jisx0208_uni2indx_page00[16] = {
+ /* 0x0000 */
+ { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 },
+ { 0, 0x0000 }, { 6843, 0x1000 }, { 0, 0x0000 }, { 0, 0x0000 }, /* ZINT: Patched reverse solidus (backslash) mapping U+005C to 0x815F */
+ { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x118c }, { 5, 0x0053 },
+ { 9, 0x0000 }, { 9, 0x0080 }, { 10, 0x0000 }, { 10, 0x0080 },
+};
+static const Summary16 jisx0208_uni2indx_page03[22] = {
+ /* 0x0300 */
+ { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 },
+ { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 },
+ { 11, 0x0000 }, { 11, 0xfffe }, { 26, 0x03fb }, { 35, 0xfffe },
+ { 50, 0x03fb }, { 59, 0x0000 }, { 59, 0x0000 }, { 59, 0x0000 },
+ /* 0x0400 */
+ { 59, 0x0002 }, { 60, 0xffff }, { 76, 0xffff }, { 92, 0xffff },
+ { 108, 0xffff }, { 124, 0x0002 },
+};
+static const Summary16 jisx0208_uni2indx_page20[50] = {
+ /* 0x2000 */
+ { 125, 0x0000 }, { 125, 0x3361 }, { 132, 0x0063 }, { 136, 0x080d },
+ { 140, 0x0000 }, { 140, 0x0000 }, { 140, 0x0000 }, { 140, 0x0000 },
+ { 140, 0x0000 }, { 140, 0x0000 }, { 140, 0x0000 }, { 140, 0x0000 },
+ { 140, 0x0000 }, { 140, 0x0000 }, { 140, 0x0000 }, { 140, 0x0000 },
+ /* 0x2100 */
+ { 140, 0x0008 }, { 141, 0x0000 }, { 141, 0x0800 }, { 142, 0x0000 },
+ { 142, 0x0000 }, { 142, 0x0000 }, { 142, 0x0000 }, { 142, 0x0000 },
+ { 142, 0x0000 }, { 142, 0x000f }, { 146, 0x0000 }, { 146, 0x0000 },
+ { 146, 0x0000 }, { 146, 0x0014 }, { 148, 0x0000 }, { 148, 0x0000 },
+ /* 0x2200 */
+ { 148, 0x098d }, { 154, 0x6404 }, { 158, 0x1f81 }, { 165, 0x2030 },
+ { 168, 0x0000 }, { 168, 0x0004 }, { 169, 0x0cc3 }, { 175, 0x0000 },
+ { 175, 0x00cc }, { 179, 0x0000 }, { 179, 0x0020 }, { 180, 0x0000 },
+ { 180, 0x0000 }, { 180, 0x0000 }, { 180, 0x0000 }, { 180, 0x0000 },
+ /* 0x2300 */
+ { 180, 0x0000 }, { 180, 0x0004 },
+};
+static const Summary16 jisx0208_uni2indx_page25[23] = {
+ /* 0x2500 */
+ { 181, 0x900f }, { 187, 0x3999 }, { 195, 0x9939 }, { 203, 0x9999 },
+ { 211, 0x0804 }, { 213, 0x0000 }, { 213, 0x0000 }, { 213, 0x0000 },
+ { 213, 0x0000 }, { 213, 0x0000 }, { 213, 0x0003 }, { 215, 0x300c },
+ { 219, 0xc8c0 }, { 224, 0x0000 }, { 224, 0x8000 }, { 225, 0x0000 },
+ /* 0x2600 */
+ { 225, 0x0060 }, { 227, 0x0000 }, { 227, 0x0000 }, { 227, 0x0000 },
+ { 227, 0x0005 }, { 229, 0x0000 }, { 229, 0xa400 },
+};
+static const Summary16 jisx0208_uni2indx_page30[16] = {
+ /* 0x3000 */
+ { 232, 0xffef }, { 247, 0x103f }, { 254, 0x0000 }, { 254, 0x0000 },
+ { 254, 0xfffe }, { 269, 0xffff }, { 285, 0xffff }, { 301, 0xffff },
+ { 317, 0xffff }, { 333, 0x780f }, { 341, 0xfffe }, { 356, 0xffff },
+ { 372, 0xffff }, { 388, 0xffff }, { 404, 0xffff }, { 420, 0x787f },
+};
+static const Summary16 jisx0208_uni2indx_page4e[1307] = {
+ /* 0x4e00 */
+ { 431, 0x6f8b }, { 441, 0x43f3 }, { 450, 0x2442 }, { 454, 0x9b46 },
+ { 462, 0xe82c }, { 469, 0xe3e0 }, { 477, 0x0004 }, { 478, 0x400a },
+ { 481, 0x5f65 }, { 491, 0xdb36 }, { 501, 0x7977 }, { 512, 0x0449 },
+ { 516, 0xecd7 }, { 527, 0xe3f0 }, { 536, 0x6038 }, { 541, 0x08c5 },
+ /* 0x4f00 */
+ { 546, 0xe602 }, { 552, 0x3403 }, { 557, 0x8000 }, { 558, 0x3551 },
+ { 565, 0xe0c8 }, { 571, 0x7eab }, { 582, 0x8200 }, { 584, 0x9869 },
+ { 591, 0xa948 }, { 597, 0x2942 }, { 602, 0xe803 }, { 608, 0x8060 },
+ { 611, 0x441c }, { 616, 0xad93 }, { 625, 0xc03a }, { 631, 0x4568 },
+ /* 0x5000 */
+ { 637, 0xaa60 }, { 643, 0x8656 }, { 650, 0x3f7a }, { 661, 0x0240 },
+ { 663, 0x8388 }, { 668, 0x1461 }, { 673, 0x1020 }, { 675, 0x2174 },
+ { 681, 0x2021 }, { 684, 0x0702 }, { 688, 0x3000 }, { 690, 0x40bc },
+ { 696, 0xa624 }, { 702, 0x4462 }, { 707, 0x60a8 }, { 712, 0x0a20 },
+ /* 0x5100 */
+ { 715, 0x0217 }, { 720, 0x8574 }, { 727, 0x0402 }, { 729, 0x9c84 },
+ { 735, 0x7bfb }, { 748, 0x1415 }, { 753, 0x7f24 }, { 762, 0x11e2 },
+ { 768, 0xb665 }, { 777, 0x02ef }, { 785, 0x1f75 }, { 795, 0x20ff },
+ { 804, 0x3a70 }, { 811, 0x3840 }, { 815, 0x26c3 }, { 822, 0x6763 },
+ /* 0x5200 */
+ { 831, 0x4dd9 }, { 840, 0x2092 }, { 844, 0x46b0 }, { 850, 0x0fc9 },
+ { 858, 0xbc98 }, { 866, 0x4850 }, { 870, 0x8638 }, { 876, 0xa03f },
+ { 884, 0x2388 }, { 889, 0x8816 }, { 894, 0x3e09 }, { 901, 0x5232 },
+ { 907, 0x22aa }, { 913, 0xe3a4 }, { 921, 0x00dd }, { 927, 0xc72c },
+ /* 0x5300 */
+ { 935, 0xa166 }, { 942, 0x26e1 }, { 949, 0x840b }, { 954, 0x8f0a },
+ { 961, 0x27eb }, { 971, 0x559e }, { 980, 0xc241 }, { 985, 0x89bb },
+ { 994, 0x0014 }, { 996, 0x8540 }, { 1000, 0x6361 }, { 1007, 0x0849 },
+ { 1011, 0x7f0c }, { 1020, 0x8ad0 }, { 1026, 0xff3e }, { 1039, 0x05cf },
+ /* 0x5400 */
+ { 1047, 0xff1a }, { 1058, 0xa803 }, { 1063, 0x7a41 }, { 1070, 0x7b40 },
+ { 1077, 0x4745 }, { 1084, 0x8002 }, { 1086, 0x0500 }, { 1088, 0x38eb },
+ { 1097, 0xd851 }, { 1104, 0x0005 }, { 1106, 0x9934 }, { 1113, 0x710c },
+ { 1119, 0x0397 }, { 1126, 0x0100 }, { 1127, 0x6366 }, { 1135, 0x2404 },
+ /* 0x5500 */
+ { 1138, 0x80d0 }, { 1142, 0x0051 }, { 1145, 0xc000 }, { 1147, 0x430a },
+ { 1152, 0x9071 }, { 1158, 0x30c8 }, { 1163, 0x0008 }, { 1164, 0x5800 },
+ { 1167, 0x0e99 }, { 1174, 0xf700 }, { 1181, 0x5f80 }, { 1188, 0x0041 },
+ { 1190, 0x00b0 }, { 1193, 0x9410 }, { 1197, 0x0018 }, { 1199, 0x6280 },
+ /* 0x5600 */
+ { 1203, 0x0240 }, { 1205, 0x09d0 }, { 1210, 0x8200 }, { 1212, 0x0156 },
+ { 1217, 0x5004 }, { 1220, 0x0801 }, { 1222, 0x1d10 }, { 1227, 0x0510 },
+ { 1230, 0x84c1 }, { 1235, 0x0010 }, { 1236, 0x4025 }, { 1240, 0x1050 },
+ { 1243, 0x410f }, { 1249, 0x4d8a }, { 1256, 0x4009 }, { 1259, 0xa60d },
+ /* 0x5700 */
+ { 1266, 0xab19 }, { 1274, 0x914c }, { 1280, 0x21c0 }, { 1284, 0x0981 },
+ { 1288, 0xc485 }, { 1294, 0x0003 }, { 1296, 0x0652 }, { 1301, 0x8000 },
+ { 1302, 0x0b04 }, { 1306, 0x0008 }, { 1307, 0x041d }, { 1312, 0x0009 },
+ { 1314, 0x4849 }, { 1319, 0x905c }, { 1325, 0x0009 }, { 1327, 0x1690 },
+ /* 0x5800 */
+ { 1332, 0x0c65 }, { 1338, 0x2220 }, { 1341, 0x8412 }, { 1345, 0x2433 },
+ { 1351, 0x0c03 }, { 1355, 0x4796 }, { 1363, 0x0a04 }, { 1366, 0x4225 },
+ { 1371, 0x0028 }, { 1373, 0x9088 }, { 1377, 0x4900 }, { 1380, 0x4f08 },
+ { 1386, 0x14a2 }, { 1391, 0xd3aa }, { 1400, 0xd830 }, { 1406, 0x3e87 },
+ /* 0x5900 */
+ { 1415, 0x8604 }, { 1419, 0x1f61 }, { 1427, 0x7ea4 }, { 1436, 0x4186 },
+ { 1441, 0xc390 }, { 1447, 0x05b3 }, { 1454, 0x57a5 }, { 1463, 0x2118 },
+ { 1467, 0x241e }, { 1473, 0x2a48 }, { 1478, 0x1128 }, { 1482, 0x4a04 },
+ { 1486, 0x0a40 }, { 1489, 0x161b }, { 1496, 0x0d60 }, { 1501, 0x8840 },
+ /* 0x5a00 */
+ { 1504, 0x020a }, { 1507, 0x9502 }, { 1512, 0x8221 }, { 1516, 0x1060 },
+ { 1519, 0x0243 }, { 1523, 0x0400 }, { 1524, 0x1444 }, { 1528, 0x8000 },
+ { 1529, 0x0000 }, { 1529, 0x0c04 }, { 1532, 0x0000 }, { 1532, 0x7000 },
+ { 1535, 0x1a06 }, { 1540, 0x00c1 }, { 1543, 0x024a }, { 1547, 0x0c00 },
+ /* 0x5b00 */
+ { 1549, 0x1a00 }, { 1552, 0x0040 }, { 1553, 0x1404 }, { 1556, 0x4045 },
+ { 1560, 0x0029 }, { 1563, 0xbdb3 }, { 1574, 0x0a78 }, { 1580, 0x052b },
+ { 1586, 0xbba9 }, { 1596, 0xbfa0 }, { 1605, 0x407c }, { 1611, 0x8379 },
+ { 1619, 0x12fc }, { 1627, 0xe81d }, { 1635, 0x4bf6 }, { 1645, 0xc569 },
+ /* 0x5c00 */
+ { 1653, 0xeff6 }, { 1666, 0x044a }, { 1670, 0x2115 }, { 1675, 0xff02 },
+ { 1684, 0xed63 }, { 1694, 0x402b }, { 1699, 0xd033 }, { 1706, 0x0242 },
+ { 1709, 0x1000 }, { 1710, 0x0013 }, { 1713, 0x1b02 }, { 1718, 0x59ca },
+ { 1726, 0x00a0 }, { 1728, 0x0200 }, { 1729, 0xa703 }, { 1736, 0x2c41 },
+ /* 0x5d00 */
+ { 1741, 0x4880 }, { 1744, 0x8ff2 }, { 1754, 0x0204 }, { 1756, 0x0000 },
+ { 1756, 0x5800 }, { 1759, 0x1005 }, { 1762, 0x9200 }, { 1765, 0x0048 },
+ { 1767, 0x1894 }, { 1772, 0x2001 }, { 1774, 0x5004 }, { 1777, 0x3480 },
+ { 1781, 0x3200 }, { 1784, 0x684c }, { 1790, 0x49ea }, { 1798, 0x68be },
+ /* 0x5e00 */
+ { 1807, 0x184c }, { 1812, 0x2e42 }, { 1818, 0xa820 }, { 1822, 0x21c9 },
+ { 1828, 0x50b9 }, { 1835, 0x80b0 }, { 1839, 0x001e }, { 1843, 0xff7c },
+ { 1856, 0x849a }, { 1862, 0x14e0 }, { 1867, 0x28c1 }, { 1872, 0x01e0 },
+ { 1876, 0x870e }, { 1883, 0xac49 }, { 1890, 0x130f }, { 1897, 0xdddb },
+ /* 0x5f00 */
+ { 1909, 0xbe1a }, { 1918, 0x89fb }, { 1928, 0xa2e0 }, { 1934, 0x51a2 },
+ { 1940, 0x5502 }, { 1945, 0x32ca }, { 1952, 0x3e46 }, { 1960, 0x928b },
+ { 1967, 0x1dbf }, { 1978, 0x438f }, { 1986, 0x6703 }, { 1993, 0x3218 },
+ { 1998, 0x3028 }, { 2002, 0x33c0 }, { 2008, 0x0811 }, { 2011, 0xa923 },
+ /* 0x6000 */
+ { 2018, 0xc000 }, { 2020, 0x3a65 }, { 2028, 0x8fe3 }, { 2038, 0x0402 },
+ { 2040, 0x2c4e }, { 2047, 0x8625 }, { 2053, 0xbf3d }, { 2065, 0x00a1 },
+ { 2068, 0x3a1a }, { 2075, 0x8cd4 }, { 2082, 0x06c9 }, { 2088, 0x317c },
+ { 2096, 0x00e0 }, { 2099, 0x950a }, { 2105, 0x018b }, { 2110, 0x0edb },
+ /* 0x6100 */
+ { 2119, 0xe34b }, { 2128, 0x8c20 }, { 2132, 0x1182 }, { 2136, 0xf010 },
+ { 2141, 0x7d94 }, { 2150, 0xa728 }, { 2157, 0xc9ac }, { 2165, 0x40fb },
+ { 2173, 0x4484 }, { 2177, 0x0653 }, { 2183, 0x5a90 }, { 2189, 0x4444 },
+ { 2193, 0x3fc8 }, { 2202, 0x0001 }, { 2203, 0x0048 }, { 2205, 0xf5d4 },
+ /* 0x6200 */
+ { 2215, 0x7701 }, { 2222, 0xec57 }, { 2232, 0xc442 }, { 2237, 0x891d },
+ { 2244, 0x6b83 }, { 2252, 0x4928 }, { 2257, 0x4109 }, { 2261, 0xd242 },
+ { 2267, 0x061d }, { 2273, 0x59fe }, { 2284, 0x1800 }, { 2286, 0x3a22 },
+ { 2292, 0xb7e4 }, { 2302, 0x3b9f }, { 2313, 0xf003 }, { 2319, 0xc0ea },
+ /* 0x6300 */
+ { 2326, 0x1386 }, { 2332, 0x8202 }, { 2335, 0x8980 }, { 2339, 0xe400 },
+ { 2343, 0xb200 }, { 2347, 0x10a1 }, { 2351, 0x4b80 }, { 2356, 0x0cc4 },
+ { 2361, 0xd309 }, { 2368, 0x8944 }, { 2373, 0x1faf }, { 2384, 0x4834 },
+ { 2389, 0x8259 }, { 2395, 0x0c45 }, { 2400, 0x420a }, { 2404, 0x0450 },
+ /* 0x6400 */
+ { 2407, 0xa040 }, { 2410, 0x10c8 }, { 2414, 0x3140 }, { 2418, 0x4450 },
+ { 2422, 0x4004 }, { 2424, 0x0100 }, { 2425, 0x8280 }, { 2428, 0x0540 },
+ { 2431, 0x0108 }, { 2433, 0x442c }, { 2438, 0x6a30 }, { 2444, 0x1a05 },
+ { 2449, 0x20a6 }, { 2454, 0x0514 }, { 2458, 0x90cf }, { 2466, 0x6456 },
+ /* 0x6500 */
+ { 2473, 0x0021 }, { 2475, 0x3100 }, { 2478, 0x9c18 }, { 2484, 0xcbf0 },
+ { 2493, 0xa120 }, { 2497, 0x63e2 }, { 2505, 0x104c }, { 2509, 0x01b5 },
+ { 2515, 0x538c }, { 2522, 0x9a83 }, { 2529, 0xb8b2 }, { 2537, 0x3281 },
+ { 2542, 0x987a }, { 2550, 0x0a84 }, { 2554, 0x33e7 }, { 2564, 0x0c02 },
+ /* 0x6600 */
+ { 2567, 0xd4cc }, { 2575, 0x9018 }, { 2579, 0xa1a1 }, { 2585, 0x9070 },
+ { 2590, 0x8a1e }, { 2597, 0xe004 }, { 2601, 0xc3d4 }, { 2609, 0x0451 },
+ { 2613, 0x439a }, { 2620, 0x21c2 }, { 2625, 0x4844 }, { 2629, 0x5310 },
+ { 2634, 0x0292 }, { 2638, 0x3640 }, { 2643, 0x0241 }, { 2646, 0xf3bd },
+ /* 0x6700 */
+ { 2658, 0xab09 }, { 2665, 0xe8f0 }, { 2673, 0x7dc0 }, { 2681, 0xa5d2 },
+ { 2689, 0xc242 }, { 2694, 0xd24b }, { 2702, 0xa43f }, { 2711, 0xd0af },
+ { 2720, 0x1aa0 }, { 2725, 0x34a1 }, { 2731, 0x8247 }, { 2737, 0x03d8 },
+ { 2743, 0xc452 }, { 2749, 0x651b }, { 2757, 0xd294 }, { 2764, 0xc83a },
+ /* 0x6800 */
+ { 2771, 0x001c }, { 2774, 0x40c8 }, { 2778, 0x0e06 }, { 2783, 0x3314 },
+ { 2789, 0x614f }, { 2797, 0xb21b }, { 2805, 0x0088 }, { 2807, 0xc0d0 },
+ { 2812, 0xa02a }, { 2817, 0xa898 }, { 2823, 0xa1c5 }, { 2830, 0x166b },
+ { 2838, 0x2e50 }, { 2844, 0x85b4 }, { 2851, 0xc08b }, { 2857, 0x0604 },
+ /* 0x6900 */
+ { 2860, 0xf933 }, { 2870, 0x1e04 }, { 2875, 0x056e }, { 2882, 0xa251 },
+ { 2888, 0x0400 }, { 2889, 0x7638 }, { 2897, 0xec07 }, { 2905, 0x73b8 },
+ { 2914, 0x4406 }, { 2918, 0x1832 }, { 2923, 0x4081 }, { 2926, 0xc816 },
+ { 2932, 0x7c8a }, { 2940, 0x6309 }, { 2946, 0x2980 }, { 2950, 0xaa04 },
+ /* 0x6a00 */
+ { 2955, 0x1c24 }, { 2960, 0xca9c }, { 2968, 0x4e0e }, { 2975, 0x2760 },
+ { 2981, 0x0990 }, { 2985, 0x8300 }, { 2988, 0x0046 }, { 2991, 0x8104 },
+ { 2994, 0x6011 }, { 2998, 0x1081 }, { 3001, 0x540d }, { 3007, 0x0908 },
+ { 3010, 0x000e }, { 3013, 0xcc0a }, { 3019, 0x0500 }, { 3021, 0x0c00 },
+ /* 0x6b00 */
+ { 3023, 0x0430 }, { 3026, 0xa044 }, { 3030, 0x008b }, { 3034, 0x6784 },
+ { 3041, 0x5288 }, { 3046, 0x8a19 }, { 3052, 0x865e }, { 3060, 0x8b18 },
+ { 3066, 0x2e59 }, { 3074, 0x4160 }, { 3078, 0x8c10 }, { 3082, 0x9cbe },
+ { 3092, 0x6861 }, { 3098, 0x891c }, { 3104, 0x9800 }, { 3107, 0x0008 },
+ /* 0x6c00 */
+ { 3108, 0x8100 }, { 3110, 0x089a }, { 3115, 0x0018 }, { 3117, 0x4190 },
+ { 3121, 0x4007 }, { 3125, 0xe4a1 }, { 3132, 0x0505 }, { 3136, 0x640d },
+ { 3142, 0x310e }, { 3148, 0x0e4d }, { 3155, 0x4806 }, { 3159, 0xff0a },
+ { 3169, 0x1632 }, { 3175, 0x2aa8 }, { 3181, 0x852e }, { 3188, 0x000b },
+ /* 0x6d00 */
+ { 3191, 0x1800 }, { 3193, 0xca84 }, { 3199, 0x0e20 }, { 3203, 0x696c },
+ { 3211, 0x0032 }, { 3214, 0x1600 }, { 3217, 0x5658 }, { 3224, 0x0390 },
+ { 3228, 0x5120 }, { 3232, 0x1a28 }, { 3237, 0x8000 }, { 3238, 0x1124 },
+ { 3242, 0x18e1 }, { 3248, 0x4326 }, { 3254, 0x5d52 }, { 3262, 0x0eaa },
+ /* 0x6e00 */
+ { 3269, 0x0fa0 }, { 3275, 0xae28 }, { 3282, 0xfa7b }, { 3294, 0x4500 },
+ { 3297, 0x6408 }, { 3301, 0x8940 }, { 3305, 0xc880 }, { 3309, 0xc044 },
+ { 3313, 0x9005 }, { 3317, 0xb141 }, { 3323, 0x8424 }, { 3327, 0x24c4 },
+ { 3332, 0x1a34 }, { 3338, 0x603a }, { 3344, 0x9000 }, { 3346, 0xc194 },
+ /* 0x6f00 */
+ { 3352, 0x8246 }, { 3357, 0x003a }, { 3361, 0x180d }, { 3366, 0xc106 },
+ { 3371, 0x0022 }, { 3373, 0x9910 }, { 3378, 0xe050 }, { 3383, 0x1511 },
+ { 3388, 0x4057 }, { 3394, 0x0082 }, { 3396, 0x041a }, { 3400, 0x020a },
+ { 3403, 0x004f }, { 3408, 0x8930 }, { 3413, 0xd813 }, { 3420, 0x444a },
+ /* 0x7000 */
+ { 3425, 0x8a02 }, { 3429, 0xed22 }, { 3437, 0x10c0 }, { 3440, 0x4005 },
+ { 3443, 0x1000 }, { 3444, 0x0102 }, { 3446, 0x8808 }, { 3449, 0x3101 },
+ { 3453, 0x4600 }, { 3456, 0x0204 }, { 3458, 0xf000 }, { 3462, 0x0708 },
+ { 3466, 0x8900 }, { 3469, 0xa200 }, { 3472, 0x0000 }, { 3472, 0x2202 },
+ /* 0x7100 */
+ { 3475, 0x0200 }, { 3476, 0x1610 }, { 3480, 0x0042 }, { 3482, 0x1040 },
+ { 3484, 0x5200 }, { 3487, 0x0260 }, { 3490, 0x52f4 }, { 3498, 0x2000 },
+ { 3499, 0x8510 }, { 3503, 0x8230 }, { 3507, 0x1100 }, { 3509, 0x4202 },
+ { 3512, 0x4308 }, { 3516, 0x80b5 }, { 3522, 0x70e1 }, { 3529, 0x9a20 },
+ /* 0x7200 */
+ { 3534, 0x2040 }, { 3536, 0x0801 }, { 3538, 0x3500 }, { 3542, 0xfc65 },
+ { 3552, 0x19c1 }, { 3558, 0xab04 }, { 3564, 0x0286 }, { 3568, 0x6214 },
+ { 3573, 0x0087 }, { 3577, 0x0044 }, { 3579, 0x9085 }, { 3584, 0x0244 },
+ { 3587, 0x405c }, { 3592, 0x0a85 }, { 3597, 0x3207 }, { 3603, 0x3380 },
+ /* 0x7300 */
+ { 3608, 0x0400 }, { 3609, 0xb8c0 }, { 3615, 0xce20 }, { 3621, 0xc0d0 },
+ { 3626, 0xc030 }, { 3630, 0x0080 }, { 3631, 0x0508 }, { 3634, 0x0d25 },
+ { 3640, 0x0a90 }, { 3644, 0x0040 }, { 3645, 0x0200 }, { 3646, 0x080c },
+ { 3649, 0x6505 }, { 3655, 0x4000 }, { 3656, 0x6421 }, { 3661, 0x4102 },
+ /* 0x7400 */
+ { 3664, 0x0268 }, { 3668, 0x0000 }, { 3668, 0x0024 }, { 3670, 0x847c },
+ { 3677, 0x0002 }, { 3678, 0xde20 }, { 3685, 0x8619 }, { 3691, 0x4049 },
+ { 3695, 0x0808 }, { 3697, 0x4000 }, { 3698, 0x0084 }, { 3700, 0x2001 },
+ { 3702, 0x8400 }, { 3704, 0x1010 }, { 3706, 0x42cd }, { 3713, 0x01c7 },
+ /* 0x7500 */
+ { 3719, 0x7038 }, { 3725, 0xd52a }, { 3733, 0x1968 }, { 3739, 0x1d8f },
+ { 3748, 0xbe50 }, { 3756, 0x3e12 }, { 3763, 0x2ef5 }, { 3773, 0x81d9 },
+ { 3780, 0xcec4 }, { 3788, 0x2412 }, { 3792, 0x0828 }, { 3795, 0x732e },
+ { 3804, 0x24ac }, { 3810, 0x4b34 }, { 3817, 0x020c }, { 3820, 0xd41d },
+ /* 0x7600 */
+ { 3828, 0x2a02 }, { 3832, 0x8000 }, { 3833, 0x0097 }, { 3838, 0x0811 },
+ { 3841, 0x11c4 }, { 3846, 0x1144 }, { 3850, 0x1786 }, { 3857, 0x7d45 },
+ { 3866, 0x49d9 }, { 3874, 0x0649 }, { 3879, 0x4000 }, { 3880, 0x8791 },
+ { 3887, 0x254c }, { 3893, 0xd8c4 }, { 3900, 0x44ba }, { 3907, 0x4914 },
+ /* 0x7700 */
+ { 3912, 0x1b92 }, { 3919, 0xc800 }, { 3922, 0x0271 }, { 3927, 0x1580 },
+ { 3931, 0x0081 }, { 3933, 0x0c00 }, { 3935, 0x096a }, { 3941, 0xc200 },
+ { 3944, 0x4800 }, { 3946, 0x4002 }, { 3948, 0x3021 }, { 3952, 0xba49 },
+ { 3960, 0x2080 }, { 3962, 0x1c80 }, { 3966, 0xe2ac }, { 3974, 0x1008 },
+ /* 0x7800 */
+ { 3976, 0x1004 }, { 3978, 0x0034 }, { 3981, 0x00e1 }, { 3985, 0x8414 },
+ { 3989, 0x0020 }, { 3990, 0x2000 }, { 3991, 0x9800 }, { 3994, 0x1014 },
+ { 3997, 0x70c2 }, { 4003, 0x04aa }, { 4008, 0x8688 }, { 4013, 0x5420 },
+ { 4017, 0x0c62 }, { 4022, 0x0413 }, { 4026, 0x9180 }, { 4030, 0x2010 },
+ /* 0x7900 */
+ { 4032, 0x4082 }, { 4035, 0x0206 }, { 4038, 0x1c40 }, { 4042, 0x5400 },
+ { 4045, 0x0383 }, { 4050, 0xe4e9 }, { 4059, 0x2125 }, { 4064, 0x8480 },
+ { 4067, 0xe433 }, { 4075, 0x2000 }, { 4076, 0x44c0 }, { 4080, 0xe609 },
+ { 4087, 0x0a03 }, { 4091, 0x8126 }, { 4096, 0x12da }, { 4103, 0x0801 },
+ /* 0x7a00 */
+ { 4105, 0x6901 }, { 4110, 0x9790 }, { 4117, 0x4001 }, { 4119, 0xf886 },
+ { 4127, 0xe24d }, { 4135, 0x0081 }, { 4137, 0x0a0e }, { 4142, 0xa651 },
+ { 4149, 0x011a }, { 4153, 0x81ec }, { 4160, 0xc600 }, { 4164, 0x8441 },
+ { 4168, 0xadb8 }, { 4177, 0xb62c }, { 4185, 0xa46f }, { 4194, 0x8741 },
+ /* 0x7b00 */
+ { 4200, 0x8d54 }, { 4207, 0x4b02 }, { 4212, 0x1161 }, { 4217, 0x0268 },
+ { 4221, 0xbb60 }, { 4229, 0x2057 }, { 4235, 0x50a0 }, { 4239, 0x0433 },
+ { 4244, 0xa8c0 }, { 4249, 0xb7b4 }, { 4259, 0x2402 }, { 4262, 0x0112 },
+ { 4265, 0x9ad3 }, { 4274, 0x2000 }, { 4275, 0x2271 }, { 4281, 0x00c8 },
+ /* 0x7c00 */
+ { 4284, 0x2081 }, { 4287, 0x809e }, { 4293, 0x0c8a }, { 4298, 0xe180 },
+ { 4303, 0xb009 }, { 4308, 0x8151 }, { 4313, 0x1031 }, { 4317, 0x4028 },
+ { 4320, 0x2a0e }, { 4326, 0x89a5 }, { 4333, 0x69b6 }, { 4342, 0x620e },
+ { 4348, 0x4425 }, { 4353, 0xd144 }, { 4359, 0x8085 }, { 4363, 0x4d54 },
+ /* 0x7d00 */
+ { 4370, 0x2c75 }, { 4378, 0x1fb1 }, { 4387, 0xd807 }, { 4394, 0x862d },
+ { 4401, 0xd87c }, { 4410, 0x4841 }, { 4414, 0x414e }, { 4420, 0x226e },
+ { 4427, 0x8200 }, { 4429, 0x9e08 }, { 4435, 0xf80c }, { 4442, 0xed37 },
+ { 4453, 0x8c80 }, { 4457, 0x7526 }, { 4465, 0x9313 }, { 4472, 0x0814 },
+ /* 0x7e00 */
+ { 4475, 0x0e32 }, { 4481, 0xc804 }, { 4485, 0x484e }, { 4491, 0x6ea6 },
+ { 4500, 0x2c4a }, { 4506, 0x6670 }, { 4513, 0x26c0 }, { 4518, 0xba01 },
+ { 4524, 0xd30c }, { 4531, 0x185d }, { 4538, 0x0000 }, { 4538, 0x0000 },
+ { 4538, 0x0000 }, { 4538, 0x0000 }, { 4538, 0x0000 }, { 4538, 0x0000 },
+ /* 0x7f00 */
+ { 4538, 0x0000 }, { 4538, 0x0000 }, { 4538, 0x0000 }, { 4538, 0x0540 },
+ { 4541, 0x7020 }, { 4545, 0x8133 }, { 4551, 0x4f81 }, { 4558, 0x03a5 },
+ { 4564, 0x55ec }, { 4573, 0x6410 }, { 4577, 0xc318 }, { 4583, 0x2344 },
+ { 4588, 0x1462 }, { 4593, 0x0034 }, { 4596, 0x0a43 }, { 4601, 0x1a09 },
+ /* 0x8000 */
+ { 4606, 0x187b }, { 4614, 0x13a5 }, { 4621, 0x0102 }, { 4623, 0xa848 },
+ { 4628, 0x0440 }, { 4630, 0xc544 }, { 4636, 0x8106 }, { 4640, 0xe2dd },
+ { 4650, 0x1af0 }, { 4657, 0x2d48 }, { 4663, 0xb626 }, { 4671, 0x0416 },
+ { 4675, 0x5058 }, { 4680, 0x6e40 }, { 4686, 0x8032 }, { 4690, 0x3112 },
+ /* 0x8100 */
+ { 4695, 0x07e4 }, { 4702, 0x0c00 }, { 4704, 0x8208 }, { 4707, 0x420a },
+ { 4711, 0x4840 }, { 4714, 0x803b }, { 4720, 0x4860 }, { 4724, 0x8713 },
+ { 4731, 0x850d }, { 4737, 0x3428 }, { 4742, 0x0319 }, { 4747, 0xe529 },
+ { 4755, 0x2345 }, { 4761, 0x870a }, { 4767, 0x25a9 }, { 4774, 0x5c18 },
+ /* 0x8200 */
+ { 4780, 0x77a6 }, { 4790, 0xd9c5 }, { 4799, 0x5e00 }, { 4804, 0x03e8 },
+ { 4810, 0x0081 }, { 4812, 0xa700 }, { 4817, 0xcd54 }, { 4825, 0x41c6 },
+ { 4831, 0x2800 }, { 4833, 0xa204 }, { 4837, 0xb860 }, { 4843, 0x2b0a },
+ { 4849, 0x0020 }, { 4850, 0xda9e }, { 4860, 0x08ea }, { 4866, 0x0e1a },
+ /* 0x8300 */
+ { 4872, 0x427c }, { 4879, 0x11c0 }, { 4883, 0x8908 }, { 4887, 0x0376 },
+ { 4894, 0x8621 }, { 4899, 0x0105 }, { 4902, 0x0000 }, { 4902, 0x18a8 },
+ { 4907, 0x46a0 }, { 4912, 0xc448 }, { 4917, 0x0d05 }, { 4922, 0x2022 },
+ { 4925, 0x5422 }, { 4930, 0x9148 }, { 4935, 0x8a01 }, { 4939, 0x2897 },
+ /* 0x8400 */
+ { 4946, 0x7898 }, { 4953, 0x0008 }, { 4954, 0x1605 }, { 4959, 0x3122 },
+ { 4964, 0x4240 }, { 4967, 0x0880 }, { 4969, 0xfa4e }, { 4979, 0x06a2 },
+ { 4984, 0x0814 }, { 4987, 0x9211 }, { 4992, 0x2002 }, { 4994, 0x9b04 },
+ { 5000, 0x2e52 }, { 5007, 0x0643 }, { 5012, 0x5000 }, { 5014, 0x9010 },
+ /* 0x8500 */
+ { 5017, 0x0041 }, { 5019, 0x85ba }, { 5027, 0x3042 }, { 5031, 0x2020 },
+ { 5033, 0x4f0b }, { 5041, 0x05a0 }, { 5045, 0x2708 }, { 5050, 0x4080 },
+ { 5052, 0x0591 }, { 5057, 0x1a93 }, { 5064, 0xdf50 }, { 5073, 0x0600 },
+ { 5075, 0xa202 }, { 5079, 0x3021 }, { 5083, 0x0630 }, { 5087, 0x4e80 },
+ /* 0x8600 */
+ { 5092, 0x0cc4 }, { 5097, 0x04c8 }, { 5101, 0xa004 }, { 5104, 0x8001 },
+ { 5106, 0x6000 }, { 5108, 0xd431 }, { 5115, 0x0880 }, { 5117, 0x0a02 },
+ { 5120, 0x1c00 }, { 5123, 0x0028 }, { 5125, 0x8e18 }, { 5131, 0x0041 },
+ { 5133, 0x6ad0 }, { 5140, 0xca10 }, { 5145, 0xf210 }, { 5151, 0x4b00 },
+ /* 0x8700 */
+ { 5155, 0x274d }, { 5163, 0x1506 }, { 5168, 0x0220 }, { 5170, 0x8890 },
+ { 5174, 0x5a00 }, { 5178, 0x82a8 }, { 5183, 0x4549 }, { 5189, 0x8150 },
+ { 5193, 0x2004 }, { 5195, 0x8000 }, { 5196, 0x8804 }, { 5199, 0x2c08 },
+ { 5203, 0x08d1 }, { 5208, 0x0005 }, { 5210, 0x8001 }, { 5212, 0x4ac4 },
+ /* 0x8800 */
+ { 5218, 0xe020 }, { 5222, 0x0062 }, { 5225, 0x008e }, { 5229, 0x0a42 },
+ { 5233, 0x3055 }, { 5239, 0x6a8c }, { 5246, 0x090e }, { 5251, 0xe0a5 },
+ { 5258, 0x2906 }, { 5263, 0x42c4 }, { 5268, 0x4814 }, { 5272, 0x80b3 },
+ { 5278, 0x803e }, { 5284, 0xb330 }, { 5291, 0x0102 }, { 5293, 0x731c },
+ /* 0x8900 */
+ { 5301, 0x1494 }, { 5306, 0x600d }, { 5311, 0x0c20 }, { 5314, 0x0940 },
+ { 5317, 0x301a }, { 5322, 0xc040 }, { 5325, 0xa451 }, { 5331, 0xc094 },
+ { 5336, 0x8dca }, { 5344, 0x05c8 }, { 5349, 0x96c2 }, { 5356, 0xa40c },
+ { 5361, 0x0001 }, { 5362, 0x3404 }, { 5366, 0x00c8 }, { 5369, 0x0110 },
+ /* 0x8a00 */
+ { 5371, 0x550d }, { 5378, 0xa9c9 }, { 5386, 0x2428 }, { 5390, 0x1c5a },
+ { 5397, 0x0142 }, { 5400, 0x4837 }, { 5407, 0x7a4d }, { 5416, 0x100f },
+ { 5421, 0x32b4 }, { 5428, 0x452a }, { 5434, 0x317b }, { 5443, 0x9205 },
+ { 5448, 0xb894 }, { 5455, 0x5c44 }, { 5461, 0x68d7 }, { 5470, 0x458a },
+ /* 0x8b00 */
+ { 5476, 0x5097 }, { 5483, 0x2ed1 }, { 5491, 0x1943 }, { 5497, 0x4208 },
+ { 5500, 0xd202 }, { 5505, 0x9d40 }, { 5511, 0x9840 }, { 5515, 0x2097 },
+ { 5521, 0x5409 }, { 5526, 0x064d }, { 5532, 0x0000 }, { 5532, 0x0000 },
+ { 5532, 0x0000 }, { 5532, 0x0000 }, { 5532, 0x0000 }, { 5532, 0x0000 },
+ /* 0x8c00 */
+ { 5532, 0x0000 }, { 5532, 0x0000 }, { 5532, 0x0000 }, { 5532, 0x8480 },
+ { 5535, 0x5542 }, { 5541, 0x0421 }, { 5544, 0x1c06 }, { 5549, 0x1700 },
+ { 5553, 0x7624 }, { 5560, 0x6110 }, { 5564, 0xff87 }, { 5576, 0xb9dd },
+ { 5587, 0x659f }, { 5597, 0x5c0a }, { 5603, 0x245d }, { 5610, 0x3c00 },
+ /* 0x8d00 */
+ { 5614, 0xadb0 }, { 5622, 0x0059 }, { 5626, 0x0000 }, { 5626, 0x0000 },
+ { 5626, 0x0000 }, { 5626, 0x0000 }, { 5626, 0x28d0 }, { 5631, 0x009b },
+ { 5636, 0x0422 }, { 5639, 0x0200 }, { 5640, 0x0108 }, { 5642, 0x4408 },
+ { 5645, 0x9804 }, { 5649, 0xac40 }, { 5654, 0x8d0a }, { 5660, 0x9028 },
+ /* 0x8e00 */
+ { 5664, 0x8700 }, { 5668, 0xe001 }, { 5672, 0x0400 }, { 5673, 0x0031 },
+ { 5676, 0x1794 }, { 5683, 0x8221 }, { 5687, 0x0019 }, { 5690, 0x1054 },
+ { 5694, 0x2cb2 }, { 5701, 0x021a }, { 5705, 0x9c02 }, { 5710, 0x4003 },
+ { 5713, 0x3d60 }, { 5720, 0x8804 }, { 5723, 0x080c }, { 5726, 0x7900 },
+ /* 0x8f00 */
+ { 5731, 0x1628 }, { 5736, 0xba3c }, { 5745, 0x8640 }, { 5749, 0xcb08 },
+ { 5755, 0x7274 }, { 5763, 0x9080 }, { 5766, 0x001e }, { 5770, 0x0000 },
+ { 5770, 0x0000 }, { 5770, 0xd800 }, { 5774, 0xe188 }, { 5780, 0x9c87 },
+ { 5788, 0x4034 }, { 5792, 0x0412 }, { 5795, 0xae64 }, { 5803, 0x2791 },
+ /* 0x9000 */
+ { 5810, 0xe86b }, { 5819, 0xe6fb }, { 5831, 0x408f }, { 5837, 0x5366 },
+ { 5845, 0xeea6 }, { 5855, 0x537f }, { 5866, 0xe32b }, { 5875, 0xb5e4 },
+ { 5884, 0x869f }, { 5893, 0x0002 }, { 5894, 0x8548 }, { 5899, 0x0122 },
+ { 5902, 0x4402 }, { 5905, 0x0800 }, { 5906, 0x2116 }, { 5911, 0x20a0 },
+ /* 0x9100 */
+ { 5914, 0x0004 }, { 5915, 0x0204 }, { 5917, 0x2000 }, { 5918, 0x0005 },
+ { 5920, 0x7e00 }, { 5926, 0x0154 }, { 5930, 0x162c }, { 5936, 0x01ac },
+ { 5941, 0x2a84 }, { 5946, 0x1085 }, { 5950, 0x8c14 }, { 5955, 0x0530 },
+ { 5959, 0xfbc3 }, { 5970, 0xb943 }, { 5978, 0x00ca }, { 5982, 0x9060 },
+ /* 0x9200 */
+ { 5986, 0x6000 }, { 5988, 0x4032 }, { 5992, 0x1200 }, { 5994, 0x8090 },
+ { 5997, 0x0b30 }, { 6002, 0x4c81 }, { 6007, 0x0054 }, { 6010, 0x4002 },
+ { 6012, 0x0029 }, { 6015, 0x1d6a }, { 6023, 0x2000 }, { 6024, 0x0280 },
+ { 6026, 0x8000 }, { 6027, 0x0004 }, { 6028, 0x2610 }, { 6032, 0x150c },
+ /* 0x9300 */
+ { 6037, 0x8040 }, { 6039, 0x0701 }, { 6043, 0xd94d }, { 6052, 0x0c24 },
+ { 6056, 0x2810 }, { 6059, 0x1850 }, { 6063, 0x5001 }, { 6066, 0x5020 },
+ { 6069, 0x1000 }, { 6070, 0x04d0 }, { 6074, 0x7080 }, { 6078, 0x0201 },
+ { 6080, 0x0108 }, { 6082, 0x21c3 }, { 6088, 0x0132 }, { 6092, 0x0000 },
+ /* 0x9400 */
+ { 6092, 0x0088 }, { 6094, 0x0719 }, { 6100, 0x0802 }, { 6102, 0x0560 },
+ { 6106, 0x0012 }, { 6108, 0x4c0e }, { 6114, 0x0405 }, { 6117, 0xf0a1 },
+ { 6124, 0x0002 }, { 6125, 0x0000 }, { 6125, 0x0000 }, { 6125, 0x0000 },
+ { 6125, 0x0000 }, { 6125, 0x0000 }, { 6125, 0x0000 }, { 6125, 0x0000 },
+ /* 0x9500 */
+ { 6125, 0x0000 }, { 6125, 0x0000 }, { 6125, 0x0000 }, { 6125, 0x0000 },
+ { 6125, 0x0000 }, { 6125, 0x0000 }, { 6125, 0x0000 }, { 6125, 0x0080 },
+ { 6126, 0x8e8d }, { 6134, 0x035a }, { 6140, 0x21bd }, { 6148, 0x5a04 },
+ { 6153, 0x3488 }, { 6158, 0x1170 }, { 6163, 0x0026 }, { 6166, 0x0000 },
+ /* 0x9600 */
+ { 6166, 0x0000 }, { 6166, 0x1000 }, { 6167, 0xc502 }, { 6172, 0x8804 },
+ { 6175, 0xb815 }, { 6182, 0xf801 }, { 6188, 0x147c }, { 6195, 0x25ed },
+ { 6204, 0xed60 }, { 6212, 0x1bb0 }, { 6219, 0x0589 }, { 6224, 0x1bd7 },
+ { 6234, 0x7af3 }, { 6245, 0x1a62 }, { 6251, 0x0d0c }, { 6256, 0x0ac5 },
+ /* 0x9700 */
+ { 6262, 0xe5d1 }, { 6271, 0x524a }, { 6277, 0x0490 }, { 6280, 0x6305 },
+ { 6286, 0x0354 }, { 6291, 0x5244 }, { 6296, 0x2b57 }, { 6305, 0x1612 },
+ { 6310, 0xa872 }, { 6317, 0x1101 }, { 6320, 0x2949 }, { 6326, 0x0018 },
+ { 6328, 0x0948 }, { 6332, 0x1008 }, { 6334, 0x6000 }, { 6336, 0x886c },
+ /* 0x9800 */
+ { 6342, 0x916e }, { 6350, 0x058f }, { 6357, 0x3012 }, { 6361, 0x3990 },
+ { 6367, 0xf840 }, { 6373, 0x4930 }, { 6378, 0x8880 }, { 6381, 0x001b },
+ { 6385, 0x0000 }, { 6385, 0x0000 }, { 6385, 0x8500 }, { 6388, 0x0042 },
+ { 6390, 0x0058 }, { 6393, 0x9800 }, { 6396, 0xea04 }, { 6402, 0x7014 },
+ /* 0x9900 */
+ { 6407, 0x1628 }, { 6412, 0x611d }, { 6419, 0x5113 }, { 6425, 0x6000 },
+ { 6427, 0x1a24 }, { 6432, 0x00a7 }, { 6437, 0x0000 }, { 6437, 0x0000 },
+ { 6437, 0x0000 }, { 6437, 0x03c0 }, { 6441, 0x7120 }, { 6446, 0x1018 },
+ { 6449, 0x0172 }, { 6454, 0xa927 }, { 6462, 0x6004 }, { 6465, 0x8906 },
+ /* 0x9a00 */
+ { 6470, 0xc022 }, { 6474, 0x020c }, { 6477, 0x0900 }, { 6479, 0x4081 },
+ { 6482, 0x202d }, { 6487, 0x8ca0 }, { 6492, 0x0e34 }, { 6498, 0x0000 },
+ { 6498, 0x0000 }, { 6498, 0x0000 }, { 6498, 0x2100 }, { 6500, 0x1101 },
+ { 6503, 0x8011 }, { 6506, 0xc11a }, { 6512, 0xec4c }, { 6520, 0x0892 },
+ /* 0x9b00 */
+ { 6524, 0x0040 }, { 6525, 0x8500 }, { 6528, 0xc7ac }, { 6537, 0x1806 },
+ { 6541, 0xe03e }, { 6549, 0x0512 }, { 6553, 0x8000 }, { 6554, 0x0010 },
+ { 6555, 0x4008 }, { 6557, 0x80ce }, { 6563, 0x6d01 }, { 6569, 0x0210 },
+ { 6571, 0x8641 }, { 6576, 0x0856 }, { 6581, 0x011e }, { 6586, 0x0027 },
+ /* 0x9c00 */
+ { 6590, 0x3750 }, { 6597, 0x083d }, { 6603, 0xe032 }, { 6609, 0x4e05 },
+ { 6615, 0x01c0 }, { 6618, 0x0484 }, { 6621, 0x0081 }, { 6623, 0x0140 },
+ { 6625, 0x0000 }, { 6625, 0x0000 }, { 6625, 0x0000 }, { 6625, 0x0000 },
+ { 6625, 0x0000 }, { 6625, 0x0000 }, { 6625, 0x1aa0 }, { 6630, 0x0059 },
+ /* 0x9d00 */
+ { 6634, 0x43c8 }, { 6640, 0x8824 }, { 6644, 0x1d48 }, { 6650, 0xc800 },
+ { 6653, 0x0152 }, { 6657, 0x7203 }, { 6663, 0x9013 }, { 6668, 0x0404 },
+ { 6670, 0x8280 }, { 6673, 0x0400 }, { 6674, 0x8a10 }, { 6678, 0x0d14 },
+ { 6683, 0x8056 }, { 6688, 0x0208 }, { 6690, 0xa040 }, { 6693, 0x2704 },
+ /* 0x9e00 */
+ { 6698, 0x0000 }, { 6698, 0x4c00 }, { 6701, 0x0000 }, { 6701, 0x0000 },
+ { 6701, 0x0000 }, { 6701, 0x0000 }, { 6701, 0x0000 }, { 6701, 0xa320 },
+ { 6706, 0x1902 }, { 6710, 0xa0ae }, { 6717, 0x2660 }, { 6722, 0xdf00 },
+ { 6729, 0xf010 }, { 6734, 0x7b15 }, { 6743, 0x8121 }, { 6747, 0x3ad0 },
+ /* 0x9f00 */
+ { 6754, 0x4180 }, { 6757, 0x0028 }, { 6759, 0x1003 }, { 6762, 0x4800 },
+ { 6764, 0xcc00 }, { 6768, 0x8014 }, { 6771, 0x14cf }, { 6779, 0x00c4 },
+ { 6782, 0x2000 }, { 6783, 0x3020 }, { 6786, 0x0001 },
+};
+
+static const Summary16 jisx0208_uni2indx_pageff[15] = {
+ /* 0xff00 */
+ { 6787, 0xdf7a }, { 6799, 0xffff }, { 6815, 0xffff }, { 6831, 0xffff },
+ { 6847, 0xffff }, { 6863, 0x3fff }, { 6877, 0x0000 }, { 6877, 0x0000 },
+ { 6877, 0x0000 }, { 6877, 0x0000 }, { 6877, 0x0000 }, { 6877, 0x0000 },
+ { 6877, 0x0000 }, { 6877, 0x0000 }, { 6877, 0x0028 },
+};
+
+static int jisx0208_wctomb(unsigned int* r, unsigned int wc) {
+ const Summary16 *summary = NULL;
+ if (wc < 0x0100) {
+ summary = &jisx0208_uni2indx_page00[(wc>>4)];
+ } else if (wc >= 0x0300 && wc < 0x0460) {
+ summary = &jisx0208_uni2indx_page03[(wc>>4)-0x030];
+ } else if (wc >= 0x2000 && wc < 0x2320) {
+ summary = &jisx0208_uni2indx_page20[(wc>>4)-0x200];
+ } else if (wc >= 0x2500 && wc < 0x2670) {
+ summary = &jisx0208_uni2indx_page25[(wc>>4)-0x250];
+ } else if (wc >= 0x3000 && wc < 0x3100) {
+ summary = &jisx0208_uni2indx_page30[(wc>>4)-0x300];
+ } else if (wc >= 0x4e00 && wc < 0x9fb0) {
+ summary = &jisx0208_uni2indx_page4e[(wc>>4)-0x4e0];
+ } else if (wc >= 0xff00 && wc < 0xfff0) {
+ summary = &jisx0208_uni2indx_pageff[(wc>>4)-0xff0];
+ }
+ if (summary) {
+ unsigned short used = summary->used;
+ unsigned int i = wc & 0x0f;
+ if (used & ((unsigned short) 1 << i)) {
+ /* Keep in 'used' only the bits 0..i-1. */
+ used &= ((unsigned short) 1 << i) - 1;
+ /* Add 'summary->indx' and the number of bits set in 'used'. */
+ used = (used & 0x5555) + ((used & 0xaaaa) >> 1);
+ used = (used & 0x3333) + ((used & 0xcccc) >> 2);
+ used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4);
+ used = (used & 0x00ff) + (used >> 8);
+ *r = jisx0208_2charset[summary->indx + used];
+ return 2;
+ }
+ }
+ return 0;
+}
+
+/*
+ * SHIFT_JIS (libiconv-1.16/lib/sjis.h)
+ */
+
+/* Returns 1 or 2 on success, 0 if no mapping */
+INTERNAL int sjis_wctomb_zint(unsigned int* r, unsigned int wc) {
+ int ret;
+
+ /* Try JIS X 0201-1976. */
+ ret = jisx0201_wctomb(r, wc);
+ if (ret) {
+ return ret;
+ }
+
+ /* Try JIS X 0208-1990. */
+ /* ZINT: Note leaving mapping of full-width reverse solidus U+FF3C to 0x815F (duplicate of patched U+005C) to avoid having to regen tables */
+ ret = jisx0208_wctomb(r, wc);
+ if (ret) {
+ return ret;
+ }
+
+ /* User-defined range. See
+ * Ken Lunde's "CJKV Information Processing", table 4-66, p. 206. */
+ /* ZINT: https://file.allitebooks.com/20160708/CJKV%20Information%20Processing.pdf (table 4-86, p. 286, 2nd ed.) */
+ if (wc >= 0xe000 && wc < 0xe758) {
+ unsigned char c1, c2;
+ c1 = (unsigned int) (wc - 0xe000) / 188;
+ c2 = (unsigned int) (wc - 0xe000) % 188;
+ *r = ((c1 + 0xf0) << 8) | (c2 < 0x3f ? c2 + 0x40 : c2 + 0x41);
+ return 2;
+ }
+
+ return 0;
+}
+
+/* Convert UTF-8 string to Shift JIS and place in array of ints */
+INTERNAL int sjis_utf8tomb(struct zint_symbol *symbol, const unsigned char source[], size_t* p_length, unsigned int* jisdata) {
+ int error_number;
+ unsigned int i, length;
+#ifndef _MSC_VER
+ unsigned int utfdata[*p_length + 1];
+#else
+ unsigned int* utfdata = (unsigned int*) _alloca((*p_length + 1) * sizeof(unsigned int));
+#endif
+
+ error_number = utf8_to_unicode(symbol, source, utfdata, p_length, 1 /*disallow_4byte*/);
+ if (error_number != 0) {
+ return error_number;
+ }
+
+ for (i = 0, length = *p_length; i < length; i++) {
+ if (!sjis_wctomb_zint(jisdata + i, utfdata[i])) {
+ strcpy(symbol->errtxt, "800: Invalid character in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ }
+
+ return 0;
+}
+
+/* Convert UTF-8 string to single byte ECI and place in array of ints */
+INTERNAL int sjis_utf8tosb(int eci, const unsigned char source[], size_t* p_length, unsigned int* jisdata, int full_multibyte) {
+ int error_number;
+#ifndef _MSC_VER
+ unsigned char single_byte[*p_length + 1];
+#else
+ unsigned char* single_byte = (unsigned char*) _alloca(*p_length + 1);
+#endif
+
+ error_number = utf_to_eci(eci, source, single_byte, p_length);
+ if (error_number != 0) {
+ // Note not setting `symbol->errtxt`, up to caller
+ return error_number;
+ }
+
+ sjis_cpy(single_byte, p_length, jisdata, full_multibyte);
+
+ return 0;
+}
+
+/* If `full_multibyte` set, copy byte input stream to array of ints, putting double-bytes that match QR Kanji mode in a single entry.
+ * If `full_multibyte` not set, do a straight copy */
+INTERNAL void sjis_cpy(const unsigned char source[], size_t* p_length, unsigned int* jisdata, int full_multibyte) {
+ unsigned int i, j, jis, length;
+ unsigned char c;
+
+ if (full_multibyte) {
+ for (i = 0, j = 0, length = *p_length; i < length; i++, j++) {
+ c = source[i];
+ if (((c >= 0x81 && c <= 0x9F) || (c >= 0xE0 && c <= 0xEB)) && length - i >= 2) {
+ jis = (c << 8) | source[i + 1];
+ if ((jis >= 0x8140 && jis <= 0x9FFC) || (jis >= 0xE040 && jis <= 0xEBBF)) {
+ /* This may or may not be valid Shift JIS, but don't care as long as it can be encoded in QR Kanji mode */
+ jisdata[j] = jis;
+ i++;
+ } else {
+ jisdata[j] = c;
+ }
+ } else {
+ jisdata[j] = c;
+ }
+ }
+ *p_length = j;
+ } else {
+ /* Straight copy */
+ for (i = 0, length = *p_length; i < length; i++) {
+ jisdata[i] = source[i];
+ }
+ }
+}
diff --git a/backend/sjis.h b/backend/sjis.h
index d5dd6e1..b019a1b 100644
--- a/backend/sjis.h
+++ b/backend/sjis.h
@@ -1,7 +1,7 @@
-/* sjis.h - Unicode to Shift JIS lookup table
+/* sjis.h - Unicode to Shift JIS
libzint - the open source barcode library
- Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2009-2020 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -27,6860 +27,23 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
-/* 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.
-*/
+#ifndef SJIS_H
+#define SJIS_H
-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, // <cjk>
- 0x4E01,0x929A, // <cjk>
- 0x4E03,0x8EB5, // <cjk>
- 0x4E07,0x969C, // <cjk>
- 0x4E08,0x8FE4, // <cjk>
- 0x4E09,0x8E4F, // <cjk>
- 0x4E0A,0x8FE3, // <cjk>
- 0x4E0B,0x89BA, // <cjk>
- 0x4E0D,0x9573, // <cjk>
- 0x4E0E,0x975E, // <cjk>
- 0x4E10,0x98A0, // <cjk>
- 0x4E11,0x894E, // <cjk>
- 0x4E14,0x8A8E, // <cjk>
- 0x4E15,0x98A1, // <cjk>
- 0x4E16,0x90A2, // <cjk>
- 0x4E17,0x99C0, // <cjk>
- 0x4E18,0x8B75, // <cjk>
- 0x4E19,0x95B8, // <cjk>
- 0x4E1E,0x8FE5, // <cjk>
- 0x4E21,0x97BC, // <cjk>
- 0x4E26,0x95C0, // <cjk>
- 0x4E2A,0x98A2, // <cjk>
- 0x4E2D,0x9286, // <cjk>
- 0x4E31,0x98A3, // <cjk>
- 0x4E32,0x8BF8, // <cjk>
- 0x4E36,0x98A4, // <cjk>
- 0x4E38,0x8ADB, // <cjk>
- 0x4E39,0x924F, // <cjk>
- 0x4E3B,0x8EE5, // <cjk>
- 0x4E3C,0x98A5, // <cjk>
- 0x4E3F,0x98A6, // <cjk>
- 0x4E42,0x98A7, // <cjk>
- 0x4E43,0x9454, // <cjk>
- 0x4E45,0x8B76, // <cjk>
- 0x4E4B,0x9456, // <cjk>
- 0x4E4D,0x93E1, // <cjk>
- 0x4E4E,0x8CC1, // <cjk>
- 0x4E4F,0x9652, // <cjk>
- 0x4E55,0xE568, // <cjk>
- 0x4E56,0x98A8, // <cjk>
- 0x4E57,0x8FE6, // <cjk>
- 0x4E58,0x98A9, // <cjk>
- 0x4E59,0x89B3, // <cjk>
- 0x4E5D,0x8BE3, // <cjk>
- 0x4E5E,0x8CEE, // <cjk>
- 0x4E5F,0x96E7, // <cjk>
- 0x4E62,0x9BA4, // <cjk>
- 0x4E71,0x9790, // <cjk>
- 0x4E73,0x93FB, // <cjk>
- 0x4E7E,0x8AA3, // <cjk>
- 0x4E80,0x8B54, // <cjk>
- 0x4E82,0x98AA, // <cjk>
- 0x4E85,0x98AB, // <cjk>
- 0x4E86,0x97B9, // <cjk>
- 0x4E88,0x975C, // <cjk>
- 0x4E89,0x9188, // <cjk>
- 0x4E8A,0x98AD, // <cjk>
- 0x4E8B,0x8E96, // <cjk>
- 0x4E8C,0x93F1, // <cjk>
- 0x4E8E,0x98B0, // <cjk>
- 0x4E91,0x895D, // <cjk>
- 0x4E92,0x8CDD, // <cjk>
- 0x4E94,0x8CDC, // <cjk>
- 0x4E95,0x88E4, // <cjk>
- 0x4E98,0x986A, // <cjk>
- 0x4E99,0x9869, // <cjk>
- 0x4E9B,0x8DB1, // <cjk>
- 0x4E9C,0x889F, // <cjk>
- 0x4E9E,0x98B1, // <cjk>
- 0x4E9F,0x98B2, // <cjk>
- 0x4EA0,0x98B3, // <cjk>
- 0x4EA1,0x9653, // <cjk>
- 0x4EA2,0x98B4, // <cjk>
- 0x4EA4,0x8CF0, // <cjk>
- 0x4EA5,0x88E5, // <cjk>
- 0x4EA6,0x9692, // <cjk>
- 0x4EA8,0x8B9C, // <cjk>
- 0x4EAB,0x8B9D, // <cjk>
- 0x4EAC,0x8B9E, // <cjk>
- 0x4EAD,0x92E0, // <cjk>
- 0x4EAE,0x97BA, // <cjk>
- 0x4EB0,0x98B5, // <cjk>
- 0x4EB3,0x98B6, // <cjk>
- 0x4EB6,0x98B7, // <cjk>
- 0x4EBA,0x906C, // <cjk>
- 0x4EC0,0x8F59, // <cjk>
- 0x4EC1,0x906D, // <cjk>
- 0x4EC2,0x98BC, // <cjk>
- 0x4EC4,0x98BA, // <cjk>
- 0x4EC6,0x98BB, // <cjk>
- 0x4EC7,0x8B77, // <cjk>
- 0x4ECA,0x8DA1, // <cjk>
- 0x4ECB,0x89EE, // <cjk>
- 0x4ECD,0x98B9, // <cjk>
- 0x4ECE,0x98B8, // <cjk>
- 0x4ECF,0x95A7, // <cjk>
- 0x4ED4,0x8E65, // <cjk>
- 0x4ED5,0x8E64, // <cjk>
- 0x4ED6,0x91BC, // <cjk>
- 0x4ED7,0x98BD, // <cjk>
- 0x4ED8,0x9574, // <cjk>
- 0x4ED9,0x90E5, // <cjk>
- 0x4EDD,0x8157, // <cjk>
- 0x4EDE,0x98BE, // <cjk>
- 0x4EDF,0x98C0, // <cjk>
- 0x4EE3,0x91E3, // <cjk>
- 0x4EE4,0x97DF, // <cjk>
- 0x4EE5,0x88C8, // <cjk>
- 0x4EED,0x98BF, // <cjk>
- 0x4EEE,0x89BC, // <cjk>
- 0x4EF0,0x8BC2, // <cjk>
- 0x4EF2,0x9287, // <cjk>
- 0x4EF6,0x8C8F, // <cjk>
- 0x4EF7,0x98C1, // <cjk>
- 0x4EFB,0x9443, // <cjk>
- 0x4F01,0x8AE9, // <cjk>
- 0x4F09,0x98C2, // <cjk>
- 0x4F0A,0x88C9, // <cjk>
- 0x4F0D,0x8CDE, // <cjk>
- 0x4F0E,0x8AEA, // <cjk>
- 0x4F0F,0x959A, // <cjk>
- 0x4F10,0x94B0, // <cjk>
- 0x4F11,0x8B78, // <cjk>
- 0x4F1A,0x89EF, // <cjk>
- 0x4F1C,0x98E5, // <cjk>
- 0x4F1D,0x9360, // <cjk>
- 0x4F2F,0x948C, // <cjk>
- 0x4F30,0x98C4, // <cjk>
- 0x4F34,0x94BA, // <cjk>
- 0x4F36,0x97E0, // <cjk>
- 0x4F38,0x904C, // <cjk>
- 0x4F3A,0x8E66, // <cjk>
- 0x4F3C,0x8E97, // <cjk>
- 0x4F3D,0x89BE, // <cjk>
- 0x4F43,0x92CF, // <cjk>
- 0x4F46,0x9241, // <cjk>
- 0x4F47,0x98C8, // <cjk>
- 0x4F4D,0x88CA, // <cjk>
- 0x4F4E,0x92E1, // <cjk>
- 0x4F4F,0x8F5A, // <cjk>
- 0x4F50,0x8DB2, // <cjk>
- 0x4F51,0x9743, // <cjk>
- 0x4F53,0x91CC, // <cjk>
- 0x4F55,0x89BD, // <cjk>
- 0x4F57,0x98C7, // <cjk>
- 0x4F59,0x975D, // <cjk>
- 0x4F5A,0x98C3, // <cjk>
- 0x4F5B,0x98C5, // <cjk>
- 0x4F5C,0x8DEC, // <cjk>
- 0x4F5D,0x98C6, // <cjk>
- 0x4F5E,0x9B43, // <cjk>
- 0x4F69,0x98CE, // <cjk>
- 0x4F6F,0x98D1, // <cjk>
- 0x4F70,0x98CF, // <cjk>
- 0x4F73,0x89C0, // <cjk>
- 0x4F75,0x95B9, // <cjk>
- 0x4F76,0x98C9, // <cjk>
- 0x4F7B,0x98CD, // <cjk>
- 0x4F7C,0x8CF1, // <cjk>
- 0x4F7F,0x8E67, // <cjk>
- 0x4F83,0x8AA4, // <cjk>
- 0x4F86,0x98D2, // <cjk>
- 0x4F88,0x98CA, // <cjk>
- 0x4F8B,0x97E1, // <cjk>
- 0x4F8D,0x8E98, // <cjk>
- 0x4F8F,0x98CB, // <cjk>
- 0x4F91,0x98D0, // <cjk>
- 0x4F96,0x98D3, // <cjk>
- 0x4F98,0x98CC, // <cjk>
- 0x4F9B,0x8B9F, // <cjk>
- 0x4F9D,0x88CB, // <cjk>
- 0x4FA0,0x8BA0, // <cjk>
- 0x4FA1,0x89BF, // <cjk>
- 0x4FAB,0x9B44, // <cjk>
- 0x4FAD,0x9699, // <cjk>
- 0x4FAE,0x958E, // <cjk>
- 0x4FAF,0x8CF2, // <cjk>
- 0x4FB5,0x904E, // <cjk>
- 0x4FB6,0x97B5, // <cjk>
- 0x4FBF,0x95D6, // <cjk>
- 0x4FC2,0x8C57, // <cjk>
- 0x4FC3,0x91A3, // <cjk>
- 0x4FC4,0x89E2, // <cjk>
- 0x4FCA,0x8F72, // <cjk>
- 0x4FCE,0x98D7, // <cjk>
- 0x4FD0,0x98DC, // <cjk>
- 0x4FD1,0x98DA, // <cjk>
- 0x4FD4,0x98D5, // <cjk>
- 0x4FD7,0x91AD, // <cjk>
- 0x4FD8,0x98D8, // <cjk>
- 0x4FDA,0x98DB, // <cjk>
- 0x4FDB,0x98D9, // <cjk>
- 0x4FDD,0x95DB, // <cjk>
- 0x4FDF,0x98D6, // <cjk>
- 0x4FE1,0x904D, // <cjk>
- 0x4FE3,0x9693, // <cjk>
- 0x4FE4,0x98DD, // <cjk>
- 0x4FE5,0x98DE, // <cjk>
- 0x4FEE,0x8F43, // <cjk>
- 0x4FEF,0x98EB, // <cjk>
- 0x4FF3,0x946F, // <cjk>
- 0x4FF5,0x9555, // <cjk>
- 0x4FF6,0x98E6, // <cjk>
- 0x4FF8,0x95EE, // <cjk>
- 0x4FFA,0x89B4, // <cjk>
- 0x4FFE,0x98EA, // <cjk>
- 0x5005,0x98E4, // <cjk>
- 0x5006,0x98ED, // <cjk>
- 0x5009,0x9171, // <cjk>
- 0x500B,0x8CC2, // <cjk>
- 0x500D,0x947B, // <cjk>
- 0x500F,0xE0C5, // <cjk>
- 0x5011,0x98EC, // <cjk>
- 0x5012,0x937C, // <cjk>
- 0x5014,0x98E1, // <cjk>
- 0x5016,0x8CF4, // <cjk>
- 0x5019,0x8CF3, // <cjk>
- 0x501A,0x98DF, // <cjk>
- 0x501F,0x8ED8, // <cjk>
- 0x5021,0x98E7, // <cjk>
- 0x5023,0x95ED, // <cjk>
- 0x5024,0x926C, // <cjk>
- 0x5025,0x98E3, // <cjk>
- 0x5026,0x8C91, // <cjk>
- 0x5028,0x98E0, // <cjk>
- 0x5029,0x98E8, // <cjk>
- 0x502A,0x98E2, // <cjk>
- 0x502B,0x97CF, // <cjk>
- 0x502C,0x98E9, // <cjk>
- 0x502D,0x9860, // <cjk>
- 0x5036,0x8BE4, // <cjk>
- 0x5039,0x8C90, // <cjk>
- 0x5043,0x98EE, // <cjk>
- 0x5047,0x98EF, // <cjk>
- 0x5048,0x98F3, // <cjk>
- 0x5049,0x88CC, // <cjk>
- 0x504F,0x95CE, // <cjk>
- 0x5050,0x98F2, // <cjk>
- 0x5055,0x98F1, // <cjk>
- 0x5056,0x98F5, // <cjk>
- 0x505A,0x98F4, // <cjk>
- 0x505C,0x92E2, // <cjk>
- 0x5065,0x8C92, // <cjk>
- 0x506C,0x98F6, // <cjk>
- 0x5072,0x8EC3, // <cjk>
- 0x5074,0x91A4, // <cjk>
- 0x5075,0x92E3, // <cjk>
- 0x5076,0x8BF4, // <cjk>
- 0x5078,0x98F7, // <cjk>
- 0x507D,0x8B55, // <cjk>
- 0x5080,0x98F8, // <cjk>
- 0x5085,0x98FA, // <cjk>
- 0x508D,0x9654, // <cjk>
- 0x5091,0x8C86, // <cjk>
- 0x5098,0x8E50, // <cjk>
- 0x5099,0x94F5, // <cjk>
- 0x509A,0x98F9, // <cjk>
- 0x50AC,0x8DC3, // <cjk>
- 0x50AD,0x9762, // <cjk>
- 0x50B2,0x98FC, // <cjk>
- 0x50B3,0x9942, // <cjk>
- 0x50B4,0x98FB, // <cjk>
- 0x50B5,0x8DC2, // <cjk>
- 0x50B7,0x8F9D, // <cjk>
- 0x50BE,0x8C58, // <cjk>
- 0x50C2,0x9943, // <cjk>
- 0x50C5,0x8BCD, // <cjk>
- 0x50C9,0x9940, // <cjk>
- 0x50CA,0x9941, // <cjk>
- 0x50CD,0x93AD, // <cjk>
- 0x50CF,0x919C, // <cjk>
- 0x50D1,0x8BA1, // <cjk>
- 0x50D5,0x966C, // <cjk>
- 0x50D6,0x9944, // <cjk>
- 0x50DA,0x97BB, // <cjk>
- 0x50DE,0x9945, // <cjk>
- 0x50E3,0x9948, // <cjk>
- 0x50E5,0x9946, // <cjk>
- 0x50E7,0x916D, // <cjk>
- 0x50ED,0x9947, // <cjk>
- 0x50EE,0x9949, // <cjk>
- 0x50F5,0x994B, // <cjk>
- 0x50F9,0x994A, // <cjk>
- 0x50FB,0x95C6, // <cjk>
- 0x5100,0x8B56, // <cjk>
- 0x5101,0x994D, // <cjk>
- 0x5102,0x994E, // <cjk>
- 0x5104,0x89AD, // <cjk>
- 0x5109,0x994C, // <cjk>
- 0x5112,0x8EF2, // <cjk>
- 0x5114,0x9951, // <cjk>
- 0x5115,0x9950, // <cjk>
- 0x5116,0x994F, // <cjk>
- 0x5118,0x98D4, // <cjk>
- 0x511A,0x9952, // <cjk>
- 0x511F,0x8F9E, // <cjk>
- 0x5121,0x9953, // <cjk>
- 0x512A,0x9744, // <cjk>
- 0x5132,0x96D7, // <cjk>
- 0x5137,0x9955, // <cjk>
- 0x513A,0x9954, // <cjk>
- 0x513B,0x9957, // <cjk>
- 0x513C,0x9956, // <cjk>
- 0x513F,0x9958, // <cjk>
- 0x5140,0x9959, // <cjk>
- 0x5141,0x88F2, // <cjk>
- 0x5143,0x8CB3, // <cjk>
- 0x5144,0x8C5A, // <cjk>
- 0x5146,0x929B, // <cjk>
- 0x5147,0x8BA2, // <cjk>
- 0x5148,0x90E6, // <cjk>
- 0x5149,0x8CF5, // <cjk>
- 0x514B,0x8D8E, // <cjk>
- 0x514D,0x96C6, // <cjk>
- 0x514E,0x9365, // <cjk>
- 0x5150,0x8E99, // <cjk>
- 0x5152,0x995A, // <cjk>
- 0x5154,0x995C, // <cjk>
- 0x515A,0x937D, // <cjk>
- 0x515C,0x8A95, // <cjk>
- 0x5162,0x995D, // <cjk>
- 0x5165,0x93FC, // <cjk>
- 0x5168,0x9153, // <cjk>
- 0x5169,0x995F, // <cjk>
- 0x516A,0x9960, // <cjk>
- 0x516B,0x94AA, // <cjk>
- 0x516C,0x8CF6, // <cjk>
- 0x516D,0x985A, // <cjk>
- 0x516E,0x9961, // <cjk>
- 0x5171,0x8BA4, // <cjk>
- 0x5175,0x95BA, // <cjk>
- 0x5176,0x91B4, // <cjk>
- 0x5177,0x8BEF, // <cjk>
- 0x5178,0x9354, // <cjk>
- 0x517C,0x8C93, // <cjk>
- 0x5180,0x9962, // <cjk>
- 0x5182,0x9963, // <cjk>
- 0x5185,0x93E0, // <cjk>
- 0x5186,0x897E, // <cjk>
- 0x5189,0x9966, // <cjk>
- 0x518A,0x8DFB, // <cjk>
- 0x518C,0x9965, // <cjk>
- 0x518D,0x8DC4, // <cjk>
- 0x518F,0x9967, // <cjk>
- 0x5190,0xE3EC, // <cjk>
- 0x5191,0x9968, // <cjk>
- 0x5192,0x9660, // <cjk>
- 0x5193,0x9969, // <cjk>
- 0x5195,0x996A, // <cjk>
- 0x5196,0x996B, // <cjk>
- 0x5197,0x8FE7, // <cjk>
- 0x5199,0x8ECA, // <cjk>
- 0x51A0,0x8AA5, // <cjk>
- 0x51A2,0x996E, // <cjk>
- 0x51A4,0x996C, // <cjk>
- 0x51A5,0x96BB, // <cjk>
- 0x51A6,0x996D, // <cjk>
- 0x51A8,0x9579, // <cjk>
- 0x51A9,0x996F, // <cjk>
- 0x51AA,0x9970, // <cjk>
- 0x51AB,0x9971, // <cjk>
- 0x51AC,0x937E, // <cjk>
- 0x51B0,0x9975, // <cjk>
- 0x51B1,0x9973, // <cjk>
- 0x51B2,0x9974, // <cjk>
- 0x51B3,0x9972, // <cjk>
- 0x51B4,0x8DE1, // <cjk>
- 0x51B5,0x9976, // <cjk>
- 0x51B6,0x96E8, // <cjk>
- 0x51B7,0x97E2, // <cjk>
- 0x51BD,0x9977, // <cjk>
- 0x51C4,0x90A6, // <cjk>
- 0x51C5,0x9978, // <cjk>
- 0x51C6,0x8F79, // <cjk>
- 0x51C9,0x9979, // <cjk>
- 0x51CB,0x929C, // <cjk>
- 0x51CC,0x97BD, // <cjk>
- 0x51CD,0x9380, // <cjk>
- 0x51D6,0x99C3, // <cjk>
- 0x51DB,0x997A, // <cjk>
- 0x51DC,0xEAA3, // <cjk>
- 0x51DD,0x8BC3, // <cjk>
- 0x51E0,0x997B, // <cjk>
- 0x51E1,0x967D, // <cjk>
- 0x51E6,0x8F88, // <cjk>
- 0x51E7,0x91FA, // <cjk>
- 0x51E9,0x997D, // <cjk>
- 0x51EA,0x93E2, // <cjk>
- 0x51ED,0x997E, // <cjk>
- 0x51F0,0x9980, // <cjk>
- 0x51F1,0x8A4D, // <cjk>
- 0x51F5,0x9981, // <cjk>
- 0x51F6,0x8BA5, // <cjk>
- 0x51F8,0x93CA, // <cjk>
- 0x51F9,0x899A, // <cjk>
- 0x51FA,0x8F6F, // <cjk>
- 0x51FD,0x949F, // <cjk>
- 0x51FE,0x9982, // <cjk>
- 0x5200,0x9381, // <cjk>
- 0x5203,0x906E, // <cjk>
- 0x5204,0x9983, // <cjk>
- 0x5206,0x95AA, // <cjk>
- 0x5207,0x90D8, // <cjk>
- 0x5208,0x8AA0, // <cjk>
- 0x520A,0x8AA7, // <cjk>
- 0x520B,0x9984, // <cjk>
- 0x520E,0x9986, // <cjk>
- 0x5211,0x8C59, // <cjk>
- 0x5214,0x9985, // <cjk>
- 0x5217,0x97F1, // <cjk>
- 0x521D,0x8F89, // <cjk>
- 0x5224,0x94BB, // <cjk>
- 0x5225,0x95CA, // <cjk>
- 0x5227,0x9987, // <cjk>
- 0x5229,0x9798, // <cjk>
- 0x522A,0x9988, // <cjk>
- 0x522E,0x9989, // <cjk>
- 0x5230,0x939E, // <cjk>
- 0x5233,0x998A, // <cjk>
- 0x5236,0x90A7, // <cjk>
- 0x5237,0x8DFC, // <cjk>
- 0x5238,0x8C94, // <cjk>
- 0x5239,0x998B, // <cjk>
- 0x523A,0x8E68, // <cjk>
- 0x523B,0x8D8F, // <cjk>
- 0x5243,0x92E4, // <cjk>
- 0x5244,0x998D, // <cjk>
- 0x5247,0x91A5, // <cjk>
- 0x524A,0x8DED, // <cjk>
- 0x524B,0x998E, // <cjk>
- 0x524C,0x998F, // <cjk>
- 0x524D,0x914F, // <cjk>
- 0x524F,0x998C, // <cjk>
- 0x5254,0x9991, // <cjk>
- 0x5256,0x9655, // <cjk>
- 0x525B,0x8D84, // <cjk>
- 0x525E,0x9990, // <cjk>
- 0x5263,0x8C95, // <cjk>
- 0x5264,0x8DDC, // <cjk>
- 0x5265,0x948D, // <cjk>
- 0x5269,0x9994, // <cjk>
- 0x526A,0x9992, // <cjk>
- 0x526F,0x959B, // <cjk>
- 0x5270,0x8FE8, // <cjk>
- 0x5271,0x999B, // <cjk>
- 0x5272,0x8A84, // <cjk>
- 0x5273,0x9995, // <cjk>
- 0x5274,0x9993, // <cjk>
- 0x5275,0x916E, // <cjk>
- 0x527D,0x9997, // <cjk>
- 0x527F,0x9996, // <cjk>
- 0x5283,0x8A63, // <cjk>
- 0x5287,0x8C80, // <cjk>
- 0x5288,0x999C, // <cjk>
- 0x5289,0x97AB, // <cjk>
- 0x528D,0x9998, // <cjk>
- 0x5291,0x999D, // <cjk>
- 0x5292,0x999A, // <cjk>
- 0x5294,0x9999, // <cjk>
- 0x529B,0x97CD, // <cjk>
- 0x529F,0x8CF7, // <cjk>
- 0x52A0,0x89C1, // <cjk>
- 0x52A3,0x97F2, // <cjk>
- 0x52A9,0x8F95, // <cjk>
- 0x52AA,0x9377, // <cjk>
- 0x52AB,0x8D85, // <cjk>
- 0x52AC,0x99A0, // <cjk>
- 0x52AD,0x99A1, // <cjk>
- 0x52B1,0x97E3, // <cjk>
- 0x52B4,0x984A, // <cjk>
- 0x52B5,0x99A3, // <cjk>
- 0x52B9,0x8CF8, // <cjk>
- 0x52BC,0x99A2, // <cjk>
- 0x52BE,0x8A4E, // <cjk>
- 0x52C1,0x99A4, // <cjk>
- 0x52C3,0x9675, // <cjk>
- 0x52C5,0x92BA, // <cjk>
- 0x52C7,0x9745, // <cjk>
- 0x52C9,0x95D7, // <cjk>
- 0x52CD,0x99A5, // <cjk>
- 0x52D2,0xE8D3, // <cjk>
- 0x52D5,0x93AE, // <cjk>
- 0x52D7,0x99A6, // <cjk>
- 0x52D8,0x8AA8, // <cjk>
- 0x52D9,0x96B1, // <cjk>
- 0x52DD,0x8F9F, // <cjk>
- 0x52DE,0x99A7, // <cjk>
- 0x52DF,0x95E5, // <cjk>
- 0x52E0,0x99AB, // <cjk>
- 0x52E2,0x90A8, // <cjk>
- 0x52E3,0x99A8, // <cjk>
- 0x52E4,0x8BCE, // <cjk>
- 0x52E6,0x99A9, // <cjk>
- 0x52E7,0x8AA9, // <cjk>
- 0x52F2,0x8C4D, // <cjk>
- 0x52F3,0x99AC, // <cjk>
- 0x52F5,0x99AD, // <cjk>
- 0x52F8,0x99AE, // <cjk>
- 0x52F9,0x99AF, // <cjk>
- 0x52FA,0x8ED9, // <cjk>
- 0x52FE,0x8CF9, // <cjk>
- 0x52FF,0x96DC, // <cjk>
- 0x5301,0x96E6, // <cjk>
- 0x5302,0x93F5, // <cjk>
- 0x5305,0x95EF, // <cjk>
- 0x5306,0x99B0, // <cjk>
- 0x5308,0x99B1, // <cjk>
- 0x530D,0x99B3, // <cjk>
- 0x530F,0x99B5, // <cjk>
- 0x5310,0x99B4, // <cjk>
- 0x5315,0x99B6, // <cjk>
- 0x5316,0x89BB, // <cjk>
- 0x5317,0x966B, // <cjk>
- 0x5319,0x8DFA, // <cjk>
- 0x531A,0x99B7, // <cjk>
- 0x531D,0x9178, // <cjk>
- 0x5320,0x8FA0, // <cjk>
- 0x5321,0x8BA7, // <cjk>
- 0x5323,0x99B8, // <cjk>
- 0x532A,0x94D9, // <cjk>
- 0x532F,0x99B9, // <cjk>
- 0x5331,0x99BA, // <cjk>
- 0x5333,0x99BB, // <cjk>
- 0x5338,0x99BC, // <cjk>
- 0x5339,0x9543, // <cjk>
- 0x533A,0x8BE6, // <cjk>
- 0x533B,0x88E3, // <cjk>
- 0x533F,0x93BD, // <cjk>
- 0x5340,0x99BD, // <cjk>
- 0x5341,0x8F5C, // <cjk>
- 0x5343,0x90E7, // <cjk>
- 0x5345,0x99BF, // <cjk>
- 0x5346,0x99BE, // <cjk>
- 0x5347,0x8FA1, // <cjk>
- 0x5348,0x8CDF, // <cjk>
- 0x5349,0x99C1, // <cjk>
- 0x534A,0x94BC, // <cjk>
- 0x534D,0x99C2, // <cjk>
- 0x5351,0x94DA, // <cjk>
- 0x5352,0x91B2, // <cjk>
- 0x5353,0x91EC, // <cjk>
- 0x5354,0x8BA6, // <cjk>
- 0x5357,0x93EC, // <cjk>
- 0x5358,0x9250, // <cjk>
- 0x535A,0x948E, // <cjk>
- 0x535C,0x966D, // <cjk>
- 0x535E,0x99C4, // <cjk>
- 0x5360,0x90E8, // <cjk>
- 0x5366,0x8C54, // <cjk>
- 0x5369,0x99C5, // <cjk>
- 0x536E,0x99C6, // <cjk>
- 0x536F,0x894B, // <cjk>
- 0x5370,0x88F3, // <cjk>
- 0x5371,0x8AEB, // <cjk>
- 0x5373,0x91A6, // <cjk>
- 0x5374,0x8B70, // <cjk>
- 0x5375,0x9791, // <cjk>
- 0x5377,0x99C9, // <cjk>
- 0x5378,0x89B5, // <cjk>
- 0x537B,0x99C8, // <cjk>
- 0x537F,0x8BA8, // <cjk>
- 0x5382,0x99CA, // <cjk>
- 0x5384,0x96EF, // <cjk>
- 0x5396,0x99CB, // <cjk>
- 0x5398,0x97D0, // <cjk>
- 0x539A,0x8CFA, // <cjk>
- 0x539F,0x8CB4, // <cjk>
- 0x53A0,0x99CC, // <cjk>
- 0x53A5,0x99CE, // <cjk>
- 0x53A6,0x99CD, // <cjk>
- 0x53A8,0x907E, // <cjk>
- 0x53A9,0x8958, // <cjk>
- 0x53AD,0x897D, // <cjk>
- 0x53AE,0x99CF, // <cjk>
- 0x53B0,0x99D0, // <cjk>
- 0x53B3,0x8CB5, // <cjk>
- 0x53B6,0x99D1, // <cjk>
- 0x53BB,0x8B8E, // <cjk>
- 0x53C2,0x8E51, // <cjk>
- 0x53C3,0x99D2, // <cjk>
- 0x53C8,0x9694, // <cjk>
- 0x53C9,0x8DB3, // <cjk>
- 0x53CA,0x8B79, // <cjk>
- 0x53CB,0x9746, // <cjk>
- 0x53CC,0x916F, // <cjk>
- 0x53CD,0x94BD, // <cjk>
- 0x53CE,0x8EFB, // <cjk>
- 0x53D4,0x8F66, // <cjk>
- 0x53D6,0x8EE6, // <cjk>
- 0x53D7,0x8EF3, // <cjk>
- 0x53D9,0x8F96, // <cjk>
- 0x53DB,0x94BE, // <cjk>
- 0x53DF,0x99D5, // <cjk>
- 0x53E1,0x8962, // <cjk>
- 0x53E2,0x9170, // <cjk>
- 0x53E3,0x8CFB, // <cjk>
- 0x53E4,0x8CC3, // <cjk>
- 0x53E5,0x8BE5, // <cjk>
- 0x53E8,0x99D9, // <cjk>
- 0x53E9,0x9240, // <cjk>
- 0x53EA,0x91FC, // <cjk>
- 0x53EB,0x8BA9, // <cjk>
- 0x53EC,0x8FA2, // <cjk>
- 0x53ED,0x99DA, // <cjk>
- 0x53EE,0x99D8, // <cjk>
- 0x53EF,0x89C2, // <cjk>
- 0x53F0,0x91E4, // <cjk>
- 0x53F1,0x8EB6, // <cjk>
- 0x53F2,0x8E6A, // <cjk>
- 0x53F3,0x8945, // <cjk>
- 0x53F6,0x8A90, // <cjk>
- 0x53F7,0x8D86, // <cjk>
- 0x53F8,0x8E69, // <cjk>
- 0x53FA,0x99DB, // <cjk>
- 0x5401,0x99DC, // <cjk>
- 0x5403,0x8B68, // <cjk>
- 0x5404,0x8A65, // <cjk>
- 0x5408,0x8D87, // <cjk>
- 0x5409,0x8B67, // <cjk>
- 0x540A,0x92DD, // <cjk>
- 0x540B,0x8944, // <cjk>
- 0x540C,0x93AF, // <cjk>
- 0x540D,0x96BC, // <cjk>
- 0x540E,0x8D40, // <cjk>
- 0x540F,0x9799, // <cjk>
- 0x5410,0x9366, // <cjk>
- 0x5411,0x8CFC, // <cjk>
- 0x541B,0x8C4E, // <cjk>
- 0x541D,0x99E5, // <cjk>
- 0x541F,0x8BE1, // <cjk>
- 0x5420,0x9669, // <cjk>
- 0x5426,0x94DB, // <cjk>
- 0x5429,0x99E4, // <cjk>
- 0x542B,0x8ADC, // <cjk>
- 0x542C,0x99DF, // <cjk>
- 0x542D,0x99E0, // <cjk>
- 0x542E,0x99E2, // <cjk>
- 0x5436,0x99E3, // <cjk>
- 0x5438,0x8B7A, // <cjk>
- 0x5439,0x9081, // <cjk>
- 0x543B,0x95AB, // <cjk>
- 0x543C,0x99E1, // <cjk>
- 0x543D,0x99DD, // <cjk>
- 0x543E,0x8CE1, // <cjk>
- 0x5440,0x99DE, // <cjk>
- 0x5442,0x9843, // <cjk>
- 0x5446,0x95F0, // <cjk>
- 0x5448,0x92E6, // <cjk>
- 0x5449,0x8CE0, // <cjk>
- 0x544A,0x8D90, // <cjk>
- 0x544E,0x99E6, // <cjk>
- 0x5451,0x93DB, // <cjk>
- 0x545F,0x99EA, // <cjk>
- 0x5468,0x8EFC, // <cjk>
- 0x546A,0x8EF4, // <cjk>
- 0x5470,0x99ED, // <cjk>
- 0x5471,0x99EB, // <cjk>
- 0x5473,0x96A1, // <cjk>
- 0x5475,0x99E8, // <cjk>
- 0x5476,0x99F1, // <cjk>
- 0x5477,0x99EC, // <cjk>
- 0x547B,0x99EF, // <cjk>
- 0x547C,0x8CC4, // <cjk>
- 0x547D,0x96BD, // <cjk>
- 0x5480,0x99F0, // <cjk>
- 0x5484,0x99F2, // <cjk>
- 0x5486,0x99F4, // <cjk>
- 0x548B,0x8DEE, // <cjk>
- 0x548C,0x9861, // <cjk>
- 0x548E,0x99E9, // <cjk>
- 0x548F,0x99E7, // <cjk>
- 0x5490,0x99F3, // <cjk>
- 0x5492,0x99EE, // <cjk>
- 0x54A2,0x99F6, // <cjk>
- 0x54A4,0x9A42, // <cjk>
- 0x54A5,0x99F8, // <cjk>
- 0x54A8,0x99FC, // <cjk>
- 0x54AB,0x9A40, // <cjk>
- 0x54AC,0x99F9, // <cjk>
- 0x54AF,0x9A5D, // <cjk>
- 0x54B2,0x8DE7, // <cjk>
- 0x54B3,0x8A50, // <cjk>
- 0x54B8,0x99F7, // <cjk>
- 0x54BC,0x9A44, // <cjk>
- 0x54BD,0x88F4, // <cjk>
- 0x54BE,0x9A43, // <cjk>
- 0x54C0,0x88A3, // <cjk>
- 0x54C1,0x9569, // <cjk>
- 0x54C2,0x9A41, // <cjk>
- 0x54C4,0x99FA, // <cjk>
- 0x54C7,0x99F5, // <cjk>
- 0x54C8,0x99FB, // <cjk>
- 0x54C9,0x8DC6, // <cjk>
- 0x54D8,0x9A45, // <cjk>
- 0x54E1,0x88F5, // <cjk>
- 0x54E2,0x9A4E, // <cjk>
- 0x54E5,0x9A46, // <cjk>
- 0x54E6,0x9A47, // <cjk>
- 0x54E8,0x8FA3, // <cjk>
- 0x54E9,0x9689, // <cjk>
- 0x54ED,0x9A4C, // <cjk>
- 0x54EE,0x9A4B, // <cjk>
- 0x54F2,0x934E, // <cjk>
- 0x54FA,0x9A4D, // <cjk>
- 0x54FD,0x9A4A, // <cjk>
- 0x5504,0x8953, // <cjk>
- 0x5506,0x8DB4, // <cjk>
- 0x5507,0x904F, // <cjk>
- 0x550F,0x9A48, // <cjk>
- 0x5510,0x9382, // <cjk>
- 0x5514,0x9A49, // <cjk>
- 0x5516,0x88A0, // <cjk>
- 0x552E,0x9A53, // <cjk>
- 0x552F,0x9742, // <cjk>
- 0x5531,0x8FA5, // <cjk>
- 0x5533,0x9A59, // <cjk>
- 0x5538,0x9A58, // <cjk>
- 0x5539,0x9A4F, // <cjk>
- 0x553E,0x91C1, // <cjk>
- 0x5540,0x9A50, // <cjk>
- 0x5544,0x91ED, // <cjk>
- 0x5545,0x9A55, // <cjk>
- 0x5546,0x8FA4, // <cjk>
- 0x554C,0x9A52, // <cjk>
- 0x554F,0x96E2, // <cjk>
- 0x5556,0x9A56, // <cjk>
- 0x5557,0x9A57, // <cjk>
- 0x555C,0x9A54, // <cjk>
- 0x555D,0x9A5A, // <cjk>
- 0x5563,0x9A51, // <cjk>
- 0x557B,0x9A60, // <cjk>
- 0x557C,0x9A65, // <cjk>
- 0x557E,0x9A61, // <cjk>
- 0x5580,0x9A5C, // <cjk>
- 0x5583,0x9A66, // <cjk>
- 0x5584,0x9150, // <cjk>
- 0x5587,0x9A68, // <cjk>
- 0x5589,0x8D41, // <cjk>
- 0x558A,0x9A5E, // <cjk>
- 0x558B,0x929D, // <cjk>
- 0x5598,0x9A62, // <cjk>
- 0x559A,0x8AAB, // <cjk>
- 0x559C,0x8AEC, // <cjk>
- 0x559D,0x8A85, // <cjk>
- 0x559E,0x9A63, // <cjk>
- 0x559F,0x9A5F, // <cjk>
- 0x55A7,0x8C96, // <cjk>
- 0x55A8,0x9A69, // <cjk>
- 0x55A9,0x9A67, // <cjk>
- 0x55AA,0x9172, // <cjk>
- 0x55AB,0x8B69, // <cjk>
- 0x55AC,0x8BAA, // <cjk>
- 0x55AE,0x9A64, // <cjk>
- 0x55B0,0x8BF2, // <cjk>
- 0x55B6,0x8963, // <cjk>
- 0x55C4,0x9A6D, // <cjk>
- 0x55C5,0x9A6B, // <cjk>
- 0x55C7,0x9AA5, // <cjk>
- 0x55D4,0x9A70, // <cjk>
- 0x55DA,0x9A6A, // <cjk>
- 0x55DC,0x9A6E, // <cjk>
- 0x55DF,0x9A6C, // <cjk>
- 0x55E3,0x8E6B, // <cjk>
- 0x55E4,0x9A6F, // <cjk>
- 0x55F7,0x9A72, // <cjk>
- 0x55F9,0x9A77, // <cjk>
- 0x55FD,0x9A75, // <cjk>
- 0x55FE,0x9A74, // <cjk>
- 0x5606,0x9251, // <cjk>
- 0x5609,0x89C3, // <cjk>
- 0x5614,0x9A71, // <cjk>
- 0x5616,0x9A73, // <cjk>
- 0x5617,0x8FA6, // <cjk>
- 0x5618,0x8952, // <cjk>
- 0x561B,0x9A76, // <cjk>
- 0x5629,0x89DC, // <cjk>
- 0x562F,0x9A82, // <cjk>
- 0x5631,0x8FFA, // <cjk>
- 0x5632,0x9A7D, // <cjk>
- 0x5634,0x9A7B, // <cjk>
- 0x5636,0x9A7C, // <cjk>
- 0x5638,0x9A7E, // <cjk>
- 0x5642,0x895C, // <cjk>
- 0x564C,0x9158, // <cjk>
- 0x564E,0x9A78, // <cjk>
- 0x5650,0x9A79, // <cjk>
- 0x565B,0x8A9A, // <cjk>
- 0x5664,0x9A81, // <cjk>
- 0x5668,0x8AED, // <cjk>
- 0x566A,0x9A84, // <cjk>
- 0x566B,0x9A80, // <cjk>
- 0x566C,0x9A83, // <cjk>
- 0x5674,0x95AC, // <cjk>
- 0x5678,0x93D3, // <cjk>
- 0x567A,0x94B6, // <cjk>
- 0x5680,0x9A86, // <cjk>
- 0x5686,0x9A85, // <cjk>
- 0x5687,0x8A64, // <cjk>
- 0x568A,0x9A87, // <cjk>
- 0x568F,0x9A8A, // <cjk>
- 0x5694,0x9A89, // <cjk>
- 0x56A0,0x9A88, // <cjk>
- 0x56A2,0x9458, // <cjk>
- 0x56A5,0x9A8B, // <cjk>
- 0x56AE,0x9A8C, // <cjk>
- 0x56B4,0x9A8E, // <cjk>
- 0x56B6,0x9A8D, // <cjk>
- 0x56BC,0x9A90, // <cjk>
- 0x56C0,0x9A93, // <cjk>
- 0x56C1,0x9A91, // <cjk>
- 0x56C2,0x9A8F, // <cjk>
- 0x56C3,0x9A92, // <cjk>
- 0x56C8,0x9A94, // <cjk>
- 0x56CE,0x9A95, // <cjk>
- 0x56D1,0x9A96, // <cjk>
- 0x56D3,0x9A97, // <cjk>
- 0x56D7,0x9A98, // <cjk>
- 0x56D8,0x9964, // <cjk>
- 0x56DA,0x8EFA, // <cjk>
- 0x56DB,0x8E6C, // <cjk>
- 0x56DE,0x89F1, // <cjk>
- 0x56E0,0x88F6, // <cjk>
- 0x56E3,0x9263, // <cjk>
- 0x56EE,0x9A99, // <cjk>
- 0x56F0,0x8DA2, // <cjk>
- 0x56F2,0x88CD, // <cjk>
- 0x56F3,0x907D, // <cjk>
- 0x56F9,0x9A9A, // <cjk>
- 0x56FA,0x8CC5, // <cjk>
- 0x56FD,0x8D91, // <cjk>
- 0x56FF,0x9A9C, // <cjk>
- 0x5700,0x9A9B, // <cjk>
- 0x5703,0x95DE, // <cjk>
- 0x5704,0x9A9D, // <cjk>
- 0x5708,0x9A9F, // <cjk>
- 0x5709,0x9A9E, // <cjk>
- 0x570B,0x9AA0, // <cjk>
- 0x570D,0x9AA1, // <cjk>
- 0x570F,0x8C97, // <cjk>
- 0x5712,0x8980, // <cjk>
- 0x5713,0x9AA2, // <cjk>
- 0x5716,0x9AA4, // <cjk>
- 0x5718,0x9AA3, // <cjk>
- 0x571C,0x9AA6, // <cjk>
- 0x571F,0x9379, // <cjk>
- 0x5726,0x9AA7, // <cjk>
- 0x5727,0x88B3, // <cjk>
- 0x5728,0x8DDD, // <cjk>
- 0x572D,0x8C5C, // <cjk>
- 0x5730,0x926E, // <cjk>
- 0x5737,0x9AA8, // <cjk>
- 0x5738,0x9AA9, // <cjk>
- 0x573B,0x9AAB, // <cjk>
- 0x5740,0x9AAC, // <cjk>
- 0x5742,0x8DE2, // <cjk>
- 0x5747,0x8BCF, // <cjk>
- 0x574A,0x9656, // <cjk>
- 0x574E,0x9AAA, // <cjk>
- 0x574F,0x9AAD, // <cjk>
- 0x5750,0x8DBF, // <cjk>
- 0x5751,0x8D42, // <cjk>
- 0x5761,0x9AB1, // <cjk>
- 0x5764,0x8DA3, // <cjk>
- 0x5766,0x9252, // <cjk>
- 0x5769,0x9AAE, // <cjk>
- 0x576A,0x92D8, // <cjk>
- 0x577F,0x9AB2, // <cjk>
- 0x5782,0x9082, // <cjk>
- 0x5788,0x9AB0, // <cjk>
- 0x5789,0x9AB3, // <cjk>
- 0x578B,0x8C5E, // <cjk>
- 0x5793,0x9AB4, // <cjk>
- 0x57A0,0x9AB5, // <cjk>
- 0x57A2,0x8D43, // <cjk>
- 0x57A3,0x8A5F, // <cjk>
- 0x57A4,0x9AB7, // <cjk>
- 0x57AA,0x9AB8, // <cjk>
- 0x57B0,0x9AB9, // <cjk>
- 0x57B3,0x9AB6, // <cjk>
- 0x57C0,0x9AAF, // <cjk>
- 0x57C3,0x9ABA, // <cjk>
- 0x57C6,0x9ABB, // <cjk>
- 0x57CB,0x9684, // <cjk>
- 0x57CE,0x8FE9, // <cjk>
- 0x57D2,0x9ABD, // <cjk>
- 0x57D3,0x9ABE, // <cjk>
- 0x57D4,0x9ABC, // <cjk>
- 0x57D6,0x9AC0, // <cjk>
- 0x57DC,0x9457, // <cjk>
- 0x57DF,0x88E6, // <cjk>
- 0x57E0,0x9575, // <cjk>
- 0x57E3,0x9AC1, // <cjk>
- 0x57F4,0x8FFB, // <cjk>
- 0x57F7,0x8EB7, // <cjk>
- 0x57F9,0x947C, // <cjk>
- 0x57FA,0x8AEE, // <cjk>
- 0x57FC,0x8DE9, // <cjk>
- 0x5800,0x9678, // <cjk>
- 0x5802,0x93B0, // <cjk>
- 0x5805,0x8C98, // <cjk>
- 0x5806,0x91CD, // <cjk>
- 0x580A,0x9ABF, // <cjk>
- 0x580B,0x9AC2, // <cjk>
- 0x5815,0x91C2, // <cjk>
- 0x5819,0x9AC3, // <cjk>
- 0x581D,0x9AC4, // <cjk>
- 0x5821,0x9AC6, // <cjk>
- 0x5824,0x92E7, // <cjk>
- 0x582A,0x8AAC, // <cjk>
- 0x582F,0xEA9F, // <cjk>
- 0x5830,0x8981, // <cjk>
- 0x5831,0x95F1, // <cjk>
- 0x5834,0x8FEA, // <cjk>
- 0x5835,0x9367, // <cjk>
- 0x583A,0x8DE4, // <cjk>
- 0x583D,0x9ACC, // <cjk>
- 0x5840,0x95BB, // <cjk>
- 0x5841,0x97DB, // <cjk>
- 0x584A,0x89F2, // <cjk>
- 0x584B,0x9AC8, // <cjk>
- 0x5851,0x9159, // <cjk>
- 0x5852,0x9ACB, // <cjk>
- 0x5854,0x9383, // <cjk>
- 0x5857,0x9368, // <cjk>
- 0x5858,0x9384, // <cjk>
- 0x5859,0x94B7, // <cjk>
- 0x585A,0x92CB, // <cjk>
- 0x585E,0x8DC7, // <cjk>
- 0x5862,0x9AC7, // <cjk>
- 0x5869,0x8996, // <cjk>
- 0x586B,0x9355, // <cjk>
- 0x5870,0x9AC9, // <cjk>
- 0x5872,0x9AC5, // <cjk>
- 0x5875,0x906F, // <cjk>
- 0x5879,0x9ACD, // <cjk>
- 0x587E,0x8F6D, // <cjk>
- 0x5883,0x8BAB, // <cjk>
- 0x5885,0x9ACE, // <cjk>
- 0x5893,0x95E6, // <cjk>
- 0x5897,0x919D, // <cjk>
- 0x589C,0x92C4, // <cjk>
- 0x589F,0x9AD0, // <cjk>
- 0x58A8,0x966E, // <cjk>
- 0x58AB,0x9AD1, // <cjk>
- 0x58AE,0x9AD6, // <cjk>
- 0x58B3,0x95AD, // <cjk>
- 0x58B8,0x9AD5, // <cjk>
- 0x58B9,0x9ACF, // <cjk>
- 0x58BA,0x9AD2, // <cjk>
- 0x58BB,0x9AD4, // <cjk>
- 0x58BE,0x8DA4, // <cjk>
- 0x58C1,0x95C7, // <cjk>
- 0x58C5,0x9AD7, // <cjk>
- 0x58C7,0x9264, // <cjk>
- 0x58CA,0x89F3, // <cjk>
- 0x58CC,0x8FEB, // <cjk>
- 0x58D1,0x9AD9, // <cjk>
- 0x58D3,0x9AD8, // <cjk>
- 0x58D5,0x8D88, // <cjk>
- 0x58D7,0x9ADA, // <cjk>
- 0x58D8,0x9ADC, // <cjk>
- 0x58D9,0x9ADB, // <cjk>
- 0x58DC,0x9ADE, // <cjk>
- 0x58DE,0x9AD3, // <cjk>
- 0x58DF,0x9AE0, // <cjk>
- 0x58E4,0x9ADF, // <cjk>
- 0x58E5,0x9ADD, // <cjk>
- 0x58EB,0x8E6D, // <cjk>
- 0x58EC,0x9070, // <cjk>
- 0x58EE,0x9173, // <cjk>
- 0x58EF,0x9AE1, // <cjk>
- 0x58F0,0x90BA, // <cjk>
- 0x58F1,0x88EB, // <cjk>
- 0x58F2,0x9484, // <cjk>
- 0x58F7,0x92D9, // <cjk>
- 0x58F9,0x9AE3, // <cjk>
- 0x58FA,0x9AE2, // <cjk>
- 0x58FB,0x9AE4, // <cjk>
- 0x58FC,0x9AE5, // <cjk>
- 0x58FD,0x9AE6, // <cjk>
- 0x5902,0x9AE7, // <cjk>
- 0x5909,0x95CF, // <cjk>
- 0x590A,0x9AE8, // <cjk>
- 0x590F,0x89C4, // <cjk>
- 0x5910,0x9AE9, // <cjk>
- 0x5916,0x8A4F, // <cjk>
- 0x5918,0x99C7, // <cjk>
- 0x5919,0x8F67, // <cjk>
- 0x591A,0x91BD, // <cjk>
- 0x591B,0x9AEA, // <cjk>
- 0x591C,0x96E9, // <cjk>
- 0x5922,0x96B2, // <cjk>
- 0x5925,0x9AEC, // <cjk>
- 0x5927,0x91E5, // <cjk>
- 0x5929,0x9356, // <cjk>
- 0x592A,0x91BE, // <cjk>
- 0x592B,0x9576, // <cjk>
- 0x592C,0x9AED, // <cjk>
- 0x592D,0x9AEE, // <cjk>
- 0x592E,0x899B, // <cjk>
- 0x5931,0x8EB8, // <cjk>
- 0x5932,0x9AEF, // <cjk>
- 0x5937,0x88CE, // <cjk>
- 0x5938,0x9AF0, // <cjk>
- 0x593E,0x9AF1, // <cjk>
- 0x5944,0x8982, // <cjk>
- 0x5947,0x8AEF, // <cjk>
- 0x5948,0x93DE, // <cjk>
- 0x5949,0x95F2, // <cjk>
- 0x594E,0x9AF5, // <cjk>
- 0x594F,0x9174, // <cjk>
- 0x5950,0x9AF4, // <cjk>
- 0x5951,0x8C5F, // <cjk>
- 0x5954,0x967A, // <cjk>
- 0x5955,0x9AF3, // <cjk>
- 0x5957,0x9385, // <cjk>
- 0x5958,0x9AF7, // <cjk>
- 0x595A,0x9AF6, // <cjk>
- 0x5960,0x9AF9, // <cjk>
- 0x5962,0x9AF8, // <cjk>
- 0x5965,0x899C, // <cjk>
- 0x5967,0x9AFA, // <cjk>
- 0x5968,0x8FA7, // <cjk>
- 0x5969,0x9AFC, // <cjk>
- 0x596A,0x9244, // <cjk>
- 0x596C,0x9AFB, // <cjk>
- 0x596E,0x95B1, // <cjk>
- 0x5973,0x8F97, // <cjk>
- 0x5974,0x937A, // <cjk>
- 0x5978,0x9B40, // <cjk>
- 0x597D,0x8D44, // <cjk>
- 0x5981,0x9B41, // <cjk>
- 0x5982,0x9440, // <cjk>
- 0x5983,0x94DC, // <cjk>
- 0x5984,0x96CF, // <cjk>
- 0x598A,0x9444, // <cjk>
- 0x598D,0x9B4A, // <cjk>
- 0x5993,0x8B57, // <cjk>
- 0x5996,0x9764, // <cjk>
- 0x5999,0x96AD, // <cjk>
- 0x599B,0x9BAA, // <cjk>
- 0x599D,0x9B42, // <cjk>
- 0x59A3,0x9B45, // <cjk>
- 0x59A5,0x91C3, // <cjk>
- 0x59A8,0x9657, // <cjk>
- 0x59AC,0x9369, // <cjk>
- 0x59B2,0x9B46, // <cjk>
- 0x59B9,0x9685, // <cjk>
- 0x59BB,0x8DC8, // <cjk>
- 0x59BE,0x8FA8, // <cjk>
- 0x59C6,0x9B47, // <cjk>
- 0x59C9,0x8E6F, // <cjk>
- 0x59CB,0x8E6E, // <cjk>
- 0x59D0,0x88B7, // <cjk>
- 0x59D1,0x8CC6, // <cjk>
- 0x59D3,0x90A9, // <cjk>
- 0x59D4,0x88CF, // <cjk>
- 0x59D9,0x9B4B, // <cjk>
- 0x59DA,0x9B4C, // <cjk>
- 0x59DC,0x9B49, // <cjk>
- 0x59E5,0x8957, // <cjk>
- 0x59E6,0x8AAD, // <cjk>
- 0x59E8,0x9B48, // <cjk>
- 0x59EA,0x96C3, // <cjk>
- 0x59EB,0x9550, // <cjk>
- 0x59F6,0x88A6, // <cjk>
- 0x59FB,0x88F7, // <cjk>
- 0x59FF,0x8E70, // <cjk>
- 0x5A01,0x88D0, // <cjk>
- 0x5A03,0x88A1, // <cjk>
- 0x5A09,0x9B51, // <cjk>
- 0x5A11,0x9B4F, // <cjk>
- 0x5A18,0x96BA, // <cjk>
- 0x5A1A,0x9B52, // <cjk>
- 0x5A1C,0x9B50, // <cjk>
- 0x5A1F,0x9B4E, // <cjk>
- 0x5A20,0x9050, // <cjk>
- 0x5A25,0x9B4D, // <cjk>
- 0x5A29,0x95D8, // <cjk>
- 0x5A2F,0x8CE2, // <cjk>
- 0x5A35,0x9B56, // <cjk>
- 0x5A36,0x9B57, // <cjk>
- 0x5A3C,0x8FA9, // <cjk>
- 0x5A40,0x9B53, // <cjk>
- 0x5A41,0x984B, // <cjk>
- 0x5A46,0x946B, // <cjk>
- 0x5A49,0x9B55, // <cjk>
- 0x5A5A,0x8DA5, // <cjk>
- 0x5A62,0x9B58, // <cjk>
- 0x5A66,0x9577, // <cjk>
- 0x5A6A,0x9B59, // <cjk>
- 0x5A6C,0x9B54, // <cjk>
- 0x5A7F,0x96B9, // <cjk>
- 0x5A92,0x947D, // <cjk>
- 0x5A9A,0x9B5A, // <cjk>
- 0x5A9B,0x9551, // <cjk>
- 0x5ABD,0x9B5F, // <cjk>
- 0x5ABE,0x9B5C, // <cjk>
- 0x5AC1,0x89C5, // <cjk>
- 0x5AC2,0x9B5E, // <cjk>
- 0x5AC9,0x8EB9, // <cjk>
- 0x5ACB,0x9B5D, // <cjk>
- 0x5ACC,0x8C99, // <cjk>
- 0x5AD0,0x9B6B, // <cjk>
- 0x5AD6,0x9B64, // <cjk>
- 0x5AD7,0x9B61, // <cjk>
- 0x5AE1,0x9284, // <cjk>
- 0x5AE3,0x9B60, // <cjk>
- 0x5AE6,0x9B62, // <cjk>
- 0x5AE9,0x9B63, // <cjk>
- 0x5AFA,0x9B65, // <cjk>
- 0x5AFB,0x9B66, // <cjk>
- 0x5B09,0x8AF0, // <cjk>
- 0x5B0B,0x9B68, // <cjk>
- 0x5B0C,0x9B67, // <cjk>
- 0x5B16,0x9B69, // <cjk>
- 0x5B22,0x8FEC, // <cjk>
- 0x5B2A,0x9B6C, // <cjk>
- 0x5B2C,0x92DA, // <cjk>
- 0x5B30,0x8964, // <cjk>
- 0x5B32,0x9B6A, // <cjk>
- 0x5B36,0x9B6D, // <cjk>
- 0x5B3E,0x9B6E, // <cjk>
- 0x5B40,0x9B71, // <cjk>
- 0x5B43,0x9B6F, // <cjk>
- 0x5B45,0x9B70, // <cjk>
- 0x5B50,0x8E71, // <cjk>
- 0x5B51,0x9B72, // <cjk>
- 0x5B54,0x8D45, // <cjk>
- 0x5B55,0x9B73, // <cjk>
- 0x5B57,0x8E9A, // <cjk>
- 0x5B58,0x91B6, // <cjk>
- 0x5B5A,0x9B74, // <cjk>
- 0x5B5B,0x9B75, // <cjk>
- 0x5B5C,0x8E79, // <cjk>
- 0x5B5D,0x8D46, // <cjk>
- 0x5B5F,0x96D0, // <cjk>
- 0x5B63,0x8B47, // <cjk>
- 0x5B64,0x8CC7, // <cjk>
- 0x5B65,0x9B76, // <cjk>
- 0x5B66,0x8A77, // <cjk>
- 0x5B69,0x9B77, // <cjk>
- 0x5B6B,0x91B7, // <cjk>
- 0x5B70,0x9B78, // <cjk>
- 0x5B71,0x9BA1, // <cjk>
- 0x5B73,0x9B79, // <cjk>
- 0x5B75,0x9B7A, // <cjk>
- 0x5B78,0x9B7B, // <cjk>
- 0x5B7A,0x9B7D, // <cjk>
- 0x5B80,0x9B7E, // <cjk>
- 0x5B83,0x9B80, // <cjk>
- 0x5B85,0x91EE, // <cjk>
- 0x5B87,0x8946, // <cjk>
- 0x5B88,0x8EE7, // <cjk>
- 0x5B89,0x88C0, // <cjk>
- 0x5B8B,0x9176, // <cjk>
- 0x5B8C,0x8AAE, // <cjk>
- 0x5B8D,0x8EB3, // <cjk>
- 0x5B8F,0x8D47, // <cjk>
- 0x5B95,0x9386, // <cjk>
- 0x5B97,0x8F40, // <cjk>
- 0x5B98,0x8AAF, // <cjk>
- 0x5B99,0x9288, // <cjk>
- 0x5B9A,0x92E8, // <cjk>
- 0x5B9B,0x88B6, // <cjk>
- 0x5B9C,0x8B58, // <cjk>
- 0x5B9D,0x95F3, // <cjk>
- 0x5B9F,0x8EC0, // <cjk>
- 0x5BA2,0x8B71, // <cjk>
- 0x5BA3,0x90E9, // <cjk>
- 0x5BA4,0x8EBA, // <cjk>
- 0x5BA5,0x9747, // <cjk>
- 0x5BA6,0x9B81, // <cjk>
- 0x5BAE,0x8B7B, // <cjk>
- 0x5BB0,0x8DC9, // <cjk>
- 0x5BB3,0x8A51, // <cjk>
- 0x5BB4,0x8983, // <cjk>
- 0x5BB5,0x8FAA, // <cjk>
- 0x5BB6,0x89C6, // <cjk>
- 0x5BB8,0x9B82, // <cjk>
- 0x5BB9,0x9765, // <cjk>
- 0x5BBF,0x8F68, // <cjk>
- 0x5BC2,0x8EE2, // <cjk>
- 0x5BC3,0x9B83, // <cjk>
- 0x5BC4,0x8AF1, // <cjk>
- 0x5BC5,0x93D0, // <cjk>
- 0x5BC6,0x96A7, // <cjk>
- 0x5BC7,0x9B84, // <cjk>
- 0x5BC9,0x9B85, // <cjk>
- 0x5BCC,0x9578, // <cjk>
- 0x5BD0,0x9B87, // <cjk>
- 0x5BD2,0x8AA6, // <cjk>
- 0x5BD3,0x8BF5, // <cjk>
- 0x5BD4,0x9B86, // <cjk>
- 0x5BDB,0x8AB0, // <cjk>
- 0x5BDD,0x9051, // <cjk>
- 0x5BDE,0x9B8B, // <cjk>
- 0x5BDF,0x8E40, // <cjk>
- 0x5BE1,0x89C7, // <cjk>
- 0x5BE2,0x9B8A, // <cjk>
- 0x5BE4,0x9B88, // <cjk>
- 0x5BE5,0x9B8C, // <cjk>
- 0x5BE6,0x9B89, // <cjk>
- 0x5BE7,0x944A, // <cjk>
- 0x5BE8,0x9ECB, // <cjk>
- 0x5BE9,0x9052, // <cjk>
- 0x5BEB,0x9B8D, // <cjk>
- 0x5BEE,0x97BE, // <cjk>
- 0x5BF0,0x9B8E, // <cjk>
- 0x5BF3,0x9B90, // <cjk>
- 0x5BF5,0x929E, // <cjk>
- 0x5BF6,0x9B8F, // <cjk>
- 0x5BF8,0x90A1, // <cjk>
- 0x5BFA,0x8E9B, // <cjk>
- 0x5BFE,0x91CE, // <cjk>
- 0x5BFF,0x8EF5, // <cjk>
- 0x5C01,0x9595, // <cjk>
- 0x5C02,0x90EA, // <cjk>
- 0x5C04,0x8ECB, // <cjk>
- 0x5C05,0x9B91, // <cjk>
- 0x5C06,0x8FAB, // <cjk>
- 0x5C07,0x9B92, // <cjk>
- 0x5C08,0x9B93, // <cjk>
- 0x5C09,0x88D1, // <cjk>
- 0x5C0A,0x91B8, // <cjk>
- 0x5C0B,0x9071, // <cjk>
- 0x5C0D,0x9B94, // <cjk>
- 0x5C0E,0x93B1, // <cjk>
- 0x5C0F,0x8FAC, // <cjk>
- 0x5C11,0x8FAD, // <cjk>
- 0x5C13,0x9B95, // <cjk>
- 0x5C16,0x90EB, // <cjk>
- 0x5C1A,0x8FAE, // <cjk>
- 0x5C20,0x9B96, // <cjk>
- 0x5C22,0x9B97, // <cjk>
- 0x5C24,0x96DE, // <cjk>
- 0x5C28,0x9B98, // <cjk>
- 0x5C2D,0x8BC4, // <cjk>
- 0x5C31,0x8F41, // <cjk>
- 0x5C38,0x9B99, // <cjk>
- 0x5C39,0x9B9A, // <cjk>
- 0x5C3A,0x8EDA, // <cjk>
- 0x5C3B,0x904B, // <cjk>
- 0x5C3C,0x93F2, // <cjk>
- 0x5C3D,0x9073, // <cjk>
- 0x5C3E,0x94F6, // <cjk>
- 0x5C3F,0x9441, // <cjk>
- 0x5C40,0x8BC7, // <cjk>
- 0x5C41,0x9B9B, // <cjk>
- 0x5C45,0x8B8F, // <cjk>
- 0x5C46,0x9B9C, // <cjk>
- 0x5C48,0x8BFC, // <cjk>
- 0x5C4A,0x93CD, // <cjk>
- 0x5C4B,0x89AE, // <cjk>
- 0x5C4D,0x8E72, // <cjk>
- 0x5C4E,0x9B9D, // <cjk>
- 0x5C4F,0x9BA0, // <cjk>
- 0x5C50,0x9B9F, // <cjk>
- 0x5C51,0x8BFB, // <cjk>
- 0x5C53,0x9B9E, // <cjk>
- 0x5C55,0x9357, // <cjk>
- 0x5C5E,0x91AE, // <cjk>
- 0x5C60,0x936A, // <cjk>
- 0x5C61,0x8EC6, // <cjk>
- 0x5C64,0x9177, // <cjk>
- 0x5C65,0x979A, // <cjk>
- 0x5C6C,0x9BA2, // <cjk>
- 0x5C6E,0x9BA3, // <cjk>
- 0x5C6F,0x93D4, // <cjk>
- 0x5C71,0x8E52, // <cjk>
- 0x5C76,0x9BA5, // <cjk>
- 0x5C79,0x9BA6, // <cjk>
- 0x5C8C,0x9BA7, // <cjk>
- 0x5C90,0x8AF2, // <cjk>
- 0x5C91,0x9BA8, // <cjk>
- 0x5C94,0x9BA9, // <cjk>
- 0x5CA1,0x89AA, // <cjk>
- 0x5CA8,0x915A, // <cjk>
- 0x5CA9,0x8AE2, // <cjk>
- 0x5CAB,0x9BAB, // <cjk>
- 0x5CAC,0x96A6, // <cjk>
- 0x5CB1,0x91D0, // <cjk>
- 0x5CB3,0x8A78, // <cjk>
- 0x5CB6,0x9BAD, // <cjk>
- 0x5CB7,0x9BAF, // <cjk>
- 0x5CB8,0x8ADD, // <cjk>
- 0x5CBB,0x9BAC, // <cjk>
- 0x5CBC,0x9BAE, // <cjk>
- 0x5CBE,0x9BB1, // <cjk>
- 0x5CC5,0x9BB0, // <cjk>
- 0x5CC7,0x9BB2, // <cjk>
- 0x5CD9,0x9BB3, // <cjk>
- 0x5CE0,0x93BB, // <cjk>
- 0x5CE1,0x8BAC, // <cjk>
- 0x5CE8,0x89E3, // <cjk>
- 0x5CE9,0x9BB4, // <cjk>
- 0x5CEA,0x9BB9, // <cjk>
- 0x5CED,0x9BB7, // <cjk>
- 0x5CEF,0x95F5, // <cjk>
- 0x5CF0,0x95F4, // <cjk>
- 0x5CF6,0x9387, // <cjk>
- 0x5CFA,0x9BB6, // <cjk>
- 0x5CFB,0x8F73, // <cjk>
- 0x5CFD,0x9BB5, // <cjk>
- 0x5D07,0x9092, // <cjk>
- 0x5D0B,0x9BBA, // <cjk>
- 0x5D0E,0x8DE8, // <cjk>
- 0x5D11,0x9BC0, // <cjk>
- 0x5D14,0x9BC1, // <cjk>
- 0x5D15,0x9BBB, // <cjk>
- 0x5D16,0x8A52, // <cjk>
- 0x5D17,0x9BBC, // <cjk>
- 0x5D18,0x9BC5, // <cjk>
- 0x5D19,0x9BC4, // <cjk>
- 0x5D1A,0x9BC3, // <cjk>
- 0x5D1B,0x9BBF, // <cjk>
- 0x5D1F,0x9BBE, // <cjk>
- 0x5D22,0x9BC2, // <cjk>
- 0x5D29,0x95F6, // <cjk>
- 0x5D4B,0x9BC9, // <cjk>
- 0x5D4C,0x9BC6, // <cjk>
- 0x5D4E,0x9BC8, // <cjk>
- 0x5D50,0x9792, // <cjk>
- 0x5D52,0x9BC7, // <cjk>
- 0x5D5C,0x9BBD, // <cjk>
- 0x5D69,0x9093, // <cjk>
- 0x5D6C,0x9BCA, // <cjk>
- 0x5D6F,0x8DB5, // <cjk>
- 0x5D73,0x9BCB, // <cjk>
- 0x5D76,0x9BCC, // <cjk>
- 0x5D82,0x9BCF, // <cjk>
- 0x5D84,0x9BCE, // <cjk>
- 0x5D87,0x9BCD, // <cjk>
- 0x5D8B,0x9388, // <cjk>
- 0x5D8C,0x9BB8, // <cjk>
- 0x5D90,0x9BD5, // <cjk>
- 0x5D9D,0x9BD1, // <cjk>
- 0x5DA2,0x9BD0, // <cjk>
- 0x5DAC,0x9BD2, // <cjk>
- 0x5DAE,0x9BD3, // <cjk>
- 0x5DB7,0x9BD6, // <cjk>
- 0x5DBA,0x97E4, // <cjk>
- 0x5DBC,0x9BD7, // <cjk>
- 0x5DBD,0x9BD4, // <cjk>
- 0x5DC9,0x9BD8, // <cjk>
- 0x5DCC,0x8ADE, // <cjk>
- 0x5DCD,0x9BD9, // <cjk>
- 0x5DD2,0x9BDB, // <cjk>
- 0x5DD3,0x9BDA, // <cjk>
- 0x5DD6,0x9BDC, // <cjk>
- 0x5DDB,0x9BDD, // <cjk>
- 0x5DDD,0x90EC, // <cjk>
- 0x5DDE,0x8F42, // <cjk>
- 0x5DE1,0x8F84, // <cjk>
- 0x5DE3,0x9183, // <cjk>
- 0x5DE5,0x8D48, // <cjk>
- 0x5DE6,0x8DB6, // <cjk>
- 0x5DE7,0x8D49, // <cjk>
- 0x5DE8,0x8B90, // <cjk>
- 0x5DEB,0x9BDE, // <cjk>
- 0x5DEE,0x8DB7, // <cjk>
- 0x5DF1,0x8CC8, // <cjk>
- 0x5DF2,0x9BDF, // <cjk>
- 0x5DF3,0x96A4, // <cjk>
- 0x5DF4,0x9462, // <cjk>
- 0x5DF5,0x9BE0, // <cjk>
- 0x5DF7,0x8D4A, // <cjk>
- 0x5DFB,0x8AAA, // <cjk>
- 0x5DFD,0x9246, // <cjk>
- 0x5DFE,0x8BD0, // <cjk>
- 0x5E02,0x8E73, // <cjk>
- 0x5E03,0x957A, // <cjk>
- 0x5E06,0x94BF, // <cjk>
- 0x5E0B,0x9BE1, // <cjk>
- 0x5E0C,0x8AF3, // <cjk>
- 0x5E11,0x9BE4, // <cjk>
- 0x5E16,0x929F, // <cjk>
- 0x5E19,0x9BE3, // <cjk>
- 0x5E1A,0x9BE2, // <cjk>
- 0x5E1B,0x9BE5, // <cjk>
- 0x5E1D,0x92E9, // <cjk>
- 0x5E25,0x9083, // <cjk>
- 0x5E2B,0x8E74, // <cjk>
- 0x5E2D,0x90C8, // <cjk>
- 0x5E2F,0x91D1, // <cjk>
- 0x5E30,0x8B41, // <cjk>
- 0x5E33,0x92A0, // <cjk>
- 0x5E36,0x9BE6, // <cjk>
- 0x5E37,0x9BE7, // <cjk>
- 0x5E38,0x8FED, // <cjk>
- 0x5E3D,0x9658, // <cjk>
- 0x5E40,0x9BEA, // <cjk>
- 0x5E43,0x9BE9, // <cjk>
- 0x5E44,0x9BE8, // <cjk>
- 0x5E45,0x959D, // <cjk>
- 0x5E47,0x9BF1, // <cjk>
- 0x5E4C,0x9679, // <cjk>
- 0x5E4E,0x9BEB, // <cjk>
- 0x5E54,0x9BED, // <cjk>
- 0x5E55,0x968B, // <cjk>
- 0x5E57,0x9BEC, // <cjk>
- 0x5E5F,0x9BEE, // <cjk>
- 0x5E61,0x94A6, // <cjk>
- 0x5E62,0x9BEF, // <cjk>
- 0x5E63,0x95BC, // <cjk>
- 0x5E64,0x9BF0, // <cjk>
- 0x5E72,0x8AB1, // <cjk>
- 0x5E73,0x95BD, // <cjk>
- 0x5E74,0x944E, // <cjk>
- 0x5E75,0x9BF2, // <cjk>
- 0x5E76,0x9BF3, // <cjk>
- 0x5E78,0x8D4B, // <cjk>
- 0x5E79,0x8AB2, // <cjk>
- 0x5E7A,0x9BF4, // <cjk>
- 0x5E7B,0x8CB6, // <cjk>
- 0x5E7C,0x9763, // <cjk>
- 0x5E7D,0x9748, // <cjk>
- 0x5E7E,0x8AF4, // <cjk>
- 0x5E7F,0x9BF6, // <cjk>
- 0x5E81,0x92A1, // <cjk>
- 0x5E83,0x8D4C, // <cjk>
- 0x5E84,0x8FAF, // <cjk>
- 0x5E87,0x94DD, // <cjk>
- 0x5E8A,0x8FB0, // <cjk>
- 0x5E8F,0x8F98, // <cjk>
- 0x5E95,0x92EA, // <cjk>
- 0x5E96,0x95F7, // <cjk>
- 0x5E97,0x9358, // <cjk>
- 0x5E9A,0x8D4D, // <cjk>
- 0x5E9C,0x957B, // <cjk>
- 0x5EA0,0x9BF7, // <cjk>
- 0x5EA6,0x9378, // <cjk>
- 0x5EA7,0x8DC0, // <cjk>
- 0x5EAB,0x8CC9, // <cjk>
- 0x5EAD,0x92EB, // <cjk>
- 0x5EB5,0x88C1, // <cjk>
- 0x5EB6,0x8F8E, // <cjk>
- 0x5EB7,0x8D4E, // <cjk>
- 0x5EB8,0x9766, // <cjk>
- 0x5EC1,0x9BF8, // <cjk>
- 0x5EC2,0x9BF9, // <cjk>
- 0x5EC3,0x9470, // <cjk>
- 0x5EC8,0x9BFA, // <cjk>
- 0x5EC9,0x97F5, // <cjk>
- 0x5ECA,0x984C, // <cjk>
- 0x5ECF,0x9BFC, // <cjk>
- 0x5ED0,0x9BFB, // <cjk>
- 0x5ED3,0x8A66, // <cjk>
- 0x5ED6,0x9C40, // <cjk>
- 0x5EDA,0x9C43, // <cjk>
- 0x5EDB,0x9C44, // <cjk>
- 0x5EDD,0x9C42, // <cjk>
- 0x5EDF,0x955F, // <cjk>
- 0x5EE0,0x8FB1, // <cjk>
- 0x5EE1,0x9C46, // <cjk>
- 0x5EE2,0x9C45, // <cjk>
- 0x5EE3,0x9C41, // <cjk>
- 0x5EE8,0x9C47, // <cjk>
- 0x5EE9,0x9C48, // <cjk>
- 0x5EEC,0x9C49, // <cjk>
- 0x5EF0,0x9C4C, // <cjk>
- 0x5EF1,0x9C4A, // <cjk>
- 0x5EF3,0x9C4B, // <cjk>
- 0x5EF4,0x9C4D, // <cjk>
- 0x5EF6,0x8984, // <cjk>
- 0x5EF7,0x92EC, // <cjk>
- 0x5EF8,0x9C4E, // <cjk>
- 0x5EFA,0x8C9A, // <cjk>
- 0x5EFB,0x89F4, // <cjk>
- 0x5EFC,0x9455, // <cjk>
- 0x5EFE,0x9C4F, // <cjk>
- 0x5EFF,0x93F9, // <cjk>
- 0x5F01,0x95D9, // <cjk>
- 0x5F03,0x9C50, // <cjk>
- 0x5F04,0x984D, // <cjk>
- 0x5F09,0x9C51, // <cjk>
- 0x5F0A,0x95BE, // <cjk>
- 0x5F0B,0x9C54, // <cjk>
- 0x5F0C,0x989F, // <cjk>
- 0x5F0D,0x98AF, // <cjk>
- 0x5F0F,0x8EAE, // <cjk>
- 0x5F10,0x93F3, // <cjk>
- 0x5F11,0x9C55, // <cjk>
- 0x5F13,0x8B7C, // <cjk>
- 0x5F14,0x92A2, // <cjk>
- 0x5F15,0x88F8, // <cjk>
- 0x5F16,0x9C56, // <cjk>
- 0x5F17,0x95A4, // <cjk>
- 0x5F18,0x8D4F, // <cjk>
- 0x5F1B,0x926F, // <cjk>
- 0x5F1F,0x92ED, // <cjk>
- 0x5F25,0x96ED, // <cjk>
- 0x5F26,0x8CB7, // <cjk>
- 0x5F27,0x8CCA, // <cjk>
- 0x5F29,0x9C57, // <cjk>
- 0x5F2D,0x9C58, // <cjk>
- 0x5F2F,0x9C5E, // <cjk>
- 0x5F31,0x8EE3, // <cjk>
- 0x5F35,0x92A3, // <cjk>
- 0x5F37,0x8BAD, // <cjk>
- 0x5F38,0x9C59, // <cjk>
- 0x5F3C,0x954A, // <cjk>
- 0x5F3E,0x9265, // <cjk>
- 0x5F41,0x9C5A, // <cjk>
- 0x5F4A,0x8BAE, // <cjk>
- 0x5F4C,0x9C5C, // <cjk>
- 0x5F4E,0x9C5D, // <cjk>
- 0x5F51,0x9C5F, // <cjk>
- 0x5F53,0x9396, // <cjk>
- 0x5F56,0x9C60, // <cjk>
- 0x5F57,0x9C61, // <cjk>
- 0x5F59,0x9C62, // <cjk>
- 0x5F5C,0x9C53, // <cjk>
- 0x5F5D,0x9C52, // <cjk>
- 0x5F61,0x9C63, // <cjk>
- 0x5F62,0x8C60, // <cjk>
- 0x5F66,0x9546, // <cjk>
- 0x5F69,0x8DCA, // <cjk>
- 0x5F6A,0x9556, // <cjk>
- 0x5F6B,0x92A4, // <cjk>
- 0x5F6C,0x956A, // <cjk>
- 0x5F6D,0x9C64, // <cjk>
- 0x5F70,0x8FB2, // <cjk>
- 0x5F71,0x8965, // <cjk>
- 0x5F73,0x9C65, // <cjk>
- 0x5F77,0x9C66, // <cjk>
- 0x5F79,0x96F0, // <cjk>
- 0x5F7C,0x94DE, // <cjk>
- 0x5F7F,0x9C69, // <cjk>
- 0x5F80,0x899D, // <cjk>
- 0x5F81,0x90AA, // <cjk>
- 0x5F82,0x9C68, // <cjk>
- 0x5F83,0x9C67, // <cjk>
- 0x5F84,0x8C61, // <cjk>
- 0x5F85,0x91D2, // <cjk>
- 0x5F87,0x9C6D, // <cjk>
- 0x5F88,0x9C6B, // <cjk>
- 0x5F8A,0x9C6A, // <cjk>
- 0x5F8B,0x97A5, // <cjk>
- 0x5F8C,0x8CE3, // <cjk>
- 0x5F90,0x8F99, // <cjk>
- 0x5F91,0x9C6C, // <cjk>
- 0x5F92,0x936B, // <cjk>
- 0x5F93,0x8F5D, // <cjk>
- 0x5F97,0x93BE, // <cjk>
- 0x5F98,0x9C70, // <cjk>
- 0x5F99,0x9C6F, // <cjk>
- 0x5F9E,0x9C6E, // <cjk>
- 0x5FA0,0x9C71, // <cjk>
- 0x5FA1,0x8CE4, // <cjk>
- 0x5FA8,0x9C72, // <cjk>
- 0x5FA9,0x959C, // <cjk>
- 0x5FAA,0x8F7A, // <cjk>
- 0x5FAD,0x9C73, // <cjk>
- 0x5FAE,0x94F7, // <cjk>
- 0x5FB3,0x93BF, // <cjk>
- 0x5FB4,0x92A5, // <cjk>
- 0x5FB9,0x934F, // <cjk>
- 0x5FBC,0x9C74, // <cjk>
- 0x5FBD,0x8B4A, // <cjk>
- 0x5FC3,0x9053, // <cjk>
- 0x5FC5,0x954B, // <cjk>
- 0x5FCC,0x8AF5, // <cjk>
- 0x5FCD,0x9445, // <cjk>
- 0x5FD6,0x9C75, // <cjk>
- 0x5FD7,0x8E75, // <cjk>
- 0x5FD8,0x9659, // <cjk>
- 0x5FD9,0x965A, // <cjk>
- 0x5FDC,0x899E, // <cjk>
- 0x5FDD,0x9C7A, // <cjk>
- 0x5FE0,0x9289, // <cjk>
- 0x5FE4,0x9C77, // <cjk>
- 0x5FEB,0x89F5, // <cjk>
- 0x5FF0,0x9CAB, // <cjk>
- 0x5FF1,0x9C79, // <cjk>
- 0x5FF5,0x944F, // <cjk>
- 0x5FF8,0x9C78, // <cjk>
- 0x5FFB,0x9C76, // <cjk>
- 0x5FFD,0x8D9A, // <cjk>
- 0x5FFF,0x9C7C, // <cjk>
- 0x600E,0x9C83, // <cjk>
- 0x600F,0x9C89, // <cjk>
- 0x6010,0x9C81, // <cjk>
- 0x6012,0x937B, // <cjk>
- 0x6015,0x9C86, // <cjk>
- 0x6016,0x957C, // <cjk>
- 0x6019,0x9C80, // <cjk>
- 0x601B,0x9C85, // <cjk>
- 0x601C,0x97E5, // <cjk>
- 0x601D,0x8E76, // <cjk>
- 0x6020,0x91D3, // <cjk>
- 0x6021,0x9C7D, // <cjk>
- 0x6025,0x8B7D, // <cjk>
- 0x6026,0x9C88, // <cjk>
- 0x6027,0x90AB, // <cjk>
- 0x6028,0x8985, // <cjk>
- 0x6029,0x9C82, // <cjk>
- 0x602A,0x89F6, // <cjk>
- 0x602B,0x9C87, // <cjk>
- 0x602F,0x8BAF, // <cjk>
- 0x6031,0x9C84, // <cjk>
- 0x603A,0x9C8A, // <cjk>
- 0x6041,0x9C8C, // <cjk>
- 0x6042,0x9C96, // <cjk>
- 0x6043,0x9C94, // <cjk>
- 0x6046,0x9C91, // <cjk>
- 0x604A,0x9C90, // <cjk>
- 0x604B,0x97F6, // <cjk>
- 0x604D,0x9C92, // <cjk>
- 0x6050,0x8BB0, // <cjk>
- 0x6052,0x8D50, // <cjk>
- 0x6055,0x8F9A, // <cjk>
- 0x6059,0x9C99, // <cjk>
- 0x605A,0x9C8B, // <cjk>
- 0x605F,0x9C8F, // <cjk>
- 0x6060,0x9C7E, // <cjk>
- 0x6062,0x89F8, // <cjk>
- 0x6063,0x9C93, // <cjk>
- 0x6064,0x9C95, // <cjk>
- 0x6065,0x9270, // <cjk>
- 0x6068,0x8DA6, // <cjk>
- 0x6069,0x89B6, // <cjk>
- 0x606A,0x9C8D, // <cjk>
- 0x606B,0x9C98, // <cjk>
- 0x606C,0x9C97, // <cjk>
- 0x606D,0x8BB1, // <cjk>
- 0x606F,0x91A7, // <cjk>
- 0x6070,0x8A86, // <cjk>
- 0x6075,0x8C62, // <cjk>
- 0x6077,0x9C8E, // <cjk>
- 0x6081,0x9C9A, // <cjk>
- 0x6083,0x9C9D, // <cjk>
- 0x6084,0x9C9F, // <cjk>
- 0x6089,0x8EBB, // <cjk>
- 0x608B,0x9CA5, // <cjk>
- 0x608C,0x92EE, // <cjk>
- 0x608D,0x9C9B, // <cjk>
- 0x6092,0x9CA3, // <cjk>
- 0x6094,0x89F7, // <cjk>
- 0x6096,0x9CA1, // <cjk>
- 0x6097,0x9CA2, // <cjk>
- 0x609A,0x9C9E, // <cjk>
- 0x609B,0x9CA0, // <cjk>
- 0x609F,0x8CE5, // <cjk>
- 0x60A0,0x9749, // <cjk>
- 0x60A3,0x8AB3, // <cjk>
- 0x60A6,0x8978, // <cjk>
- 0x60A7,0x9CA4, // <cjk>
- 0x60A9,0x9459, // <cjk>
- 0x60AA,0x88AB, // <cjk>
- 0x60B2,0x94DF, // <cjk>
- 0x60B3,0x9C7B, // <cjk>
- 0x60B4,0x9CAA, // <cjk>
- 0x60B5,0x9CAE, // <cjk>
- 0x60B6,0x96E3, // <cjk>
- 0x60B8,0x9CA7, // <cjk>
- 0x60BC,0x9389, // <cjk>
- 0x60BD,0x9CAC, // <cjk>
- 0x60C5,0x8FEE, // <cjk>
- 0x60C6,0x9CAD, // <cjk>
- 0x60C7,0x93D5, // <cjk>
- 0x60D1,0x9866, // <cjk>
- 0x60D3,0x9CA9, // <cjk>
- 0x60D8,0x9CAF, // <cjk>
- 0x60DA,0x8D9B, // <cjk>
- 0x60DC,0x90C9, // <cjk>
- 0x60DF,0x88D2, // <cjk>
- 0x60E0,0x9CA8, // <cjk>
- 0x60E1,0x9CA6, // <cjk>
- 0x60E3,0x9179, // <cjk>
- 0x60E7,0x9C9C, // <cjk>
- 0x60E8,0x8E53, // <cjk>
- 0x60F0,0x91C4, // <cjk>
- 0x60F1,0x9CBB, // <cjk>
- 0x60F3,0x917A, // <cjk>
- 0x60F4,0x9CB6, // <cjk>
- 0x60F6,0x9CB3, // <cjk>
- 0x60F7,0x9CB4, // <cjk>
- 0x60F9,0x8EE4, // <cjk>
- 0x60FA,0x9CB7, // <cjk>
- 0x60FB,0x9CBA, // <cjk>
- 0x6100,0x9CB5, // <cjk>
- 0x6101,0x8F44, // <cjk>
- 0x6103,0x9CB8, // <cjk>
- 0x6106,0x9CB2, // <cjk>
- 0x6108,0x96FA, // <cjk>
- 0x6109,0x96F9, // <cjk>
- 0x610D,0x9CBC, // <cjk>
- 0x610E,0x9CBD, // <cjk>
- 0x610F,0x88D3, // <cjk>
- 0x6115,0x9CB1, // <cjk>
- 0x611A,0x8BF0, // <cjk>
- 0x611B,0x88A4, // <cjk>
- 0x611F,0x8AB4, // <cjk>
- 0x6121,0x9CB9, // <cjk>
- 0x6127,0x9CC1, // <cjk>
- 0x6128,0x9CC0, // <cjk>
- 0x612C,0x9CC5, // <cjk>
- 0x6134,0x9CC6, // <cjk>
- 0x613C,0x9CC4, // <cjk>
- 0x613D,0x9CC7, // <cjk>
- 0x613E,0x9CBF, // <cjk>
- 0x613F,0x9CC3, // <cjk>
- 0x6142,0x9CC8, // <cjk>
- 0x6144,0x9CC9, // <cjk>
- 0x6147,0x9CBE, // <cjk>
- 0x6148,0x8E9C, // <cjk>
- 0x614A,0x9CC2, // <cjk>
- 0x614B,0x91D4, // <cjk>
- 0x614C,0x8D51, // <cjk>
- 0x614D,0x9CB0, // <cjk>
- 0x614E,0x9054, // <cjk>
- 0x6153,0x9CD6, // <cjk>
- 0x6155,0x95E7, // <cjk>
- 0x6158,0x9CCC, // <cjk>
- 0x6159,0x9CCD, // <cjk>
- 0x615A,0x9CCE, // <cjk>
- 0x615D,0x9CD5, // <cjk>
- 0x615F,0x9CD4, // <cjk>
- 0x6162,0x969D, // <cjk>
- 0x6163,0x8AB5, // <cjk>
- 0x6165,0x9CD2, // <cjk>
- 0x6167,0x8C64, // <cjk>
- 0x6168,0x8A53, // <cjk>
- 0x616B,0x9CCF, // <cjk>
- 0x616E,0x97B6, // <cjk>
- 0x616F,0x9CD1, // <cjk>
- 0x6170,0x88D4, // <cjk>
- 0x6171,0x9CD3, // <cjk>
- 0x6173,0x9CCA, // <cjk>
- 0x6174,0x9CD0, // <cjk>
- 0x6175,0x9CD7, // <cjk>
- 0x6176,0x8C63, // <cjk>
- 0x6177,0x9CCB, // <cjk>
- 0x617E,0x977C, // <cjk>
- 0x6182,0x974A, // <cjk>
- 0x6187,0x9CDA, // <cjk>
- 0x618A,0x9CDE, // <cjk>
- 0x618E,0x919E, // <cjk>
- 0x6190,0x97F7, // <cjk>
- 0x6191,0x9CDF, // <cjk>
- 0x6194,0x9CDC, // <cjk>
- 0x6196,0x9CD9, // <cjk>
- 0x6199,0x9CD8, // <cjk>
- 0x619A,0x9CDD, // <cjk>
- 0x61A4,0x95AE, // <cjk>
- 0x61A7,0x93B2, // <cjk>
- 0x61A9,0x8C65, // <cjk>
- 0x61AB,0x9CE0, // <cjk>
- 0x61AC,0x9CDB, // <cjk>
- 0x61AE,0x9CE1, // <cjk>
- 0x61B2,0x8C9B, // <cjk>
- 0x61B6,0x89AF, // <cjk>
- 0x61BA,0x9CE9, // <cjk>
- 0x61BE,0x8AB6, // <cjk>
- 0x61C3,0x9CE7, // <cjk>
- 0x61C6,0x9CE8, // <cjk>
- 0x61C7,0x8DA7, // <cjk>
- 0x61C8,0x9CE6, // <cjk>
- 0x61C9,0x9CE4, // <cjk>
- 0x61CA,0x9CE3, // <cjk>
- 0x61CB,0x9CEA, // <cjk>
- 0x61CC,0x9CE2, // <cjk>
- 0x61CD,0x9CEC, // <cjk>
- 0x61D0,0x89F9, // <cjk>
- 0x61E3,0x9CEE, // <cjk>
- 0x61E6,0x9CED, // <cjk>
- 0x61F2,0x92A6, // <cjk>
- 0x61F4,0x9CF1, // <cjk>
- 0x61F6,0x9CEF, // <cjk>
- 0x61F7,0x9CE5, // <cjk>
- 0x61F8,0x8C9C, // <cjk>
- 0x61FA,0x9CF0, // <cjk>
- 0x61FC,0x9CF4, // <cjk>
- 0x61FD,0x9CF3, // <cjk>
- 0x61FE,0x9CF5, // <cjk>
- 0x61FF,0x9CF2, // <cjk>
- 0x6200,0x9CF6, // <cjk>
- 0x6208,0x9CF7, // <cjk>
- 0x6209,0x9CF8, // <cjk>
- 0x620A,0x95E8, // <cjk>
- 0x620C,0x9CFA, // <cjk>
- 0x620D,0x9CF9, // <cjk>
- 0x620E,0x8F5E, // <cjk>
- 0x6210,0x90AC, // <cjk>
- 0x6211,0x89E4, // <cjk>
- 0x6212,0x89FA, // <cjk>
- 0x6214,0x9CFB, // <cjk>
- 0x6216,0x88BD, // <cjk>
- 0x621A,0x90CA, // <cjk>
- 0x621B,0x9CFC, // <cjk>
- 0x621D,0xE6C1, // <cjk>
- 0x621E,0x9D40, // <cjk>
- 0x621F,0x8C81, // <cjk>
- 0x6221,0x9D41, // <cjk>
- 0x6226,0x90ED, // <cjk>
- 0x622A,0x9D42, // <cjk>
- 0x622E,0x9D43, // <cjk>
- 0x622F,0x8B59, // <cjk>
- 0x6230,0x9D44, // <cjk>
- 0x6232,0x9D45, // <cjk>
- 0x6233,0x9D46, // <cjk>
- 0x6234,0x91D5, // <cjk>
- 0x6238,0x8CCB, // <cjk>
- 0x623B,0x96DF, // <cjk>
- 0x6240,0x8F8A, // <cjk>
- 0x6241,0x9D47, // <cjk>
- 0x6247,0x90EE, // <cjk>
- 0x6248,0xE7BB, // <cjk>
- 0x6249,0x94E0, // <cjk>
- 0x624B,0x8EE8, // <cjk>
- 0x624D,0x8DCB, // <cjk>
- 0x624E,0x9D48, // <cjk>
- 0x6253,0x91C5, // <cjk>
- 0x6255,0x95A5, // <cjk>
- 0x6258,0x91EF, // <cjk>
- 0x625B,0x9D4B, // <cjk>
- 0x625E,0x9D49, // <cjk>
- 0x6260,0x9D4C, // <cjk>
- 0x6263,0x9D4A, // <cjk>
- 0x6268,0x9D4D, // <cjk>
- 0x626E,0x95AF, // <cjk>
- 0x6271,0x88B5, // <cjk>
- 0x6276,0x957D, // <cjk>
- 0x6279,0x94E1, // <cjk>
- 0x627C,0x9D4E, // <cjk>
- 0x627E,0x9D51, // <cjk>
- 0x627F,0x8FB3, // <cjk>
- 0x6280,0x8B5A, // <cjk>
- 0x6282,0x9D4F, // <cjk>
- 0x6283,0x9D56, // <cjk>
- 0x6284,0x8FB4, // <cjk>
- 0x6289,0x9D50, // <cjk>
- 0x628A,0x9463, // <cjk>
- 0x6291,0x977D, // <cjk>
- 0x6292,0x9D52, // <cjk>
- 0x6293,0x9D53, // <cjk>
- 0x6294,0x9D57, // <cjk>
- 0x6295,0x938A, // <cjk>
- 0x6296,0x9D54, // <cjk>
- 0x6297,0x8D52, // <cjk>
- 0x6298,0x90DC, // <cjk>
- 0x629B,0x9D65, // <cjk>
- 0x629C,0x94B2, // <cjk>
- 0x629E,0x91F0, // <cjk>
- 0x62AB,0x94E2, // <cjk>
- 0x62AC,0x9DAB, // <cjk>
- 0x62B1,0x95F8, // <cjk>
- 0x62B5,0x92EF, // <cjk>
- 0x62B9,0x9695, // <cjk>
- 0x62BB,0x9D5A, // <cjk>
- 0x62BC,0x899F, // <cjk>
- 0x62BD,0x928A, // <cjk>
- 0x62C2,0x9D63, // <cjk>
- 0x62C5,0x9253, // <cjk>
- 0x62C6,0x9D5D, // <cjk>
- 0x62C7,0x9D64, // <cjk>
- 0x62C8,0x9D5F, // <cjk>
- 0x62C9,0x9D66, // <cjk>
- 0x62CA,0x9D62, // <cjk>
- 0x62CC,0x9D61, // <cjk>
- 0x62CD,0x948F, // <cjk>
- 0x62D0,0x89FB, // <cjk>
- 0x62D1,0x9D59, // <cjk>
- 0x62D2,0x8B91, // <cjk>
- 0x62D3,0x91F1, // <cjk>
- 0x62D4,0x9D55, // <cjk>
- 0x62D7,0x9D58, // <cjk>
- 0x62D8,0x8D53, // <cjk>
- 0x62D9,0x90D9, // <cjk>
- 0x62DB,0x8FB5, // <cjk>
- 0x62DC,0x9D60, // <cjk>
- 0x62DD,0x9471, // <cjk>
- 0x62E0,0x8B92, // <cjk>
- 0x62E1,0x8A67, // <cjk>
- 0x62EC,0x8A87, // <cjk>
- 0x62ED,0x9040, // <cjk>
- 0x62EE,0x9D68, // <cjk>
- 0x62EF,0x9D6D, // <cjk>
- 0x62F1,0x9D69, // <cjk>
- 0x62F3,0x8C9D, // <cjk>
- 0x62F5,0x9D6E, // <cjk>
- 0x62F6,0x8E41, // <cjk>
- 0x62F7,0x8D89, // <cjk>
- 0x62FE,0x8F45, // <cjk>
- 0x62FF,0x9D5C, // <cjk>
- 0x6301,0x8E9D, // <cjk>
- 0x6302,0x9D6B, // <cjk>
- 0x6307,0x8E77, // <cjk>
- 0x6308,0x9D6C, // <cjk>
- 0x6309,0x88C2, // <cjk>
- 0x630C,0x9D67, // <cjk>
- 0x6311,0x92A7, // <cjk>
- 0x6319,0x8B93, // <cjk>
- 0x631F,0x8BB2, // <cjk>
- 0x6327,0x9D6A, // <cjk>
- 0x6328,0x88A5, // <cjk>
- 0x632B,0x8DC1, // <cjk>
- 0x632F,0x9055, // <cjk>
- 0x633A,0x92F0, // <cjk>
- 0x633D,0x94D2, // <cjk>
- 0x633E,0x9D70, // <cjk>
- 0x633F,0x917D, // <cjk>
- 0x6349,0x91A8, // <cjk>
- 0x634C,0x8E4A, // <cjk>
- 0x634D,0x9D71, // <cjk>
- 0x634F,0x9D73, // <cjk>
- 0x6350,0x9D6F, // <cjk>
- 0x6355,0x95DF, // <cjk>
- 0x6357,0x92BB, // <cjk>
- 0x635C,0x917B, // <cjk>
- 0x6367,0x95F9, // <cjk>
- 0x6368,0x8ECC, // <cjk>
- 0x6369,0x9D80, // <cjk>
- 0x636B,0x9D7E, // <cjk>
- 0x636E,0x9098, // <cjk>
- 0x6372,0x8C9E, // <cjk>
- 0x6376,0x9D78, // <cjk>
- 0x6377,0x8FB7, // <cjk>
- 0x637A,0x93E6, // <cjk>
- 0x637B,0x9450, // <cjk>
- 0x6380,0x9D76, // <cjk>
- 0x6383,0x917C, // <cjk>
- 0x6388,0x8EF6, // <cjk>
- 0x6389,0x9D7B, // <cjk>
- 0x638C,0x8FB6, // <cjk>
- 0x638E,0x9D75, // <cjk>
- 0x638F,0x9D7A, // <cjk>
- 0x6392,0x9472, // <cjk>
- 0x6396,0x9D74, // <cjk>
- 0x6398,0x8C40, // <cjk>
- 0x639B,0x8A7C, // <cjk>
- 0x639F,0x9D7C, // <cjk>
- 0x63A0,0x97A9, // <cjk>
- 0x63A1,0x8DCC, // <cjk>
- 0x63A2,0x9254, // <cjk>
- 0x63A3,0x9D79, // <cjk>
- 0x63A5,0x90DA, // <cjk>
- 0x63A7,0x8D54, // <cjk>
- 0x63A8,0x9084, // <cjk>
- 0x63A9,0x8986, // <cjk>
- 0x63AB,0x9D77, // <cjk>
- 0x63AC,0x8B64, // <cjk>
- 0x63B2,0x8C66, // <cjk>
- 0x63B4,0x92CD, // <cjk>
- 0x63B5,0x9D7D, // <cjk>
- 0x63BB,0x917E, // <cjk>
- 0x63BE,0x9D81, // <cjk>
- 0x63C0,0x9D83, // <cjk>
- 0x63C3,0x91B5, // <cjk>
- 0x63C4,0x9D89, // <cjk>
- 0x63C6,0x9D84, // <cjk>
- 0x63C9,0x9D86, // <cjk>
- 0x63CF,0x9560, // <cjk>
- 0x63D0,0x92F1, // <cjk>
- 0x63D2,0x9D87, // <cjk>
- 0x63D6,0x974B, // <cjk>
- 0x63DA,0x9767, // <cjk>
- 0x63DB,0x8AB7, // <cjk>
- 0x63E1,0x88AC, // <cjk>
- 0x63E3,0x9D85, // <cjk>
- 0x63E9,0x9D82, // <cjk>
- 0x63EE,0x8AF6, // <cjk>
- 0x63F4,0x8987, // <cjk>
- 0x63F6,0x9D88, // <cjk>
- 0x63FA,0x9768, // <cjk>
- 0x6406,0x9D8C, // <cjk>
- 0x640D,0x91B9, // <cjk>
- 0x640F,0x9D93, // <cjk>
- 0x6413,0x9D8D, // <cjk>
- 0x6416,0x9D8A, // <cjk>
- 0x6417,0x9D91, // <cjk>
- 0x641C,0x9D72, // <cjk>
- 0x6426,0x9D8E, // <cjk>
- 0x6428,0x9D92, // <cjk>
- 0x642C,0x94C0, // <cjk>
- 0x642D,0x938B, // <cjk>
- 0x6434,0x9D8B, // <cjk>
- 0x6436,0x9D8F, // <cjk>
- 0x643A,0x8C67, // <cjk>
- 0x643E,0x8DEF, // <cjk>
- 0x6442,0x90DB, // <cjk>
- 0x644E,0x9D97, // <cjk>
- 0x6458,0x9345, // <cjk>
- 0x6467,0x9D94, // <cjk>
- 0x6469,0x9680, // <cjk>
- 0x646F,0x9D95, // <cjk>
- 0x6476,0x9D96, // <cjk>
- 0x6478,0x96CC, // <cjk>
- 0x647A,0x90A0, // <cjk>
- 0x6483,0x8C82, // <cjk>
- 0x6488,0x9D9D, // <cjk>
- 0x6492,0x8E54, // <cjk>
- 0x6493,0x9D9A, // <cjk>
- 0x6495,0x9D99, // <cjk>
- 0x649A,0x9451, // <cjk>
- 0x649E,0x93B3, // <cjk>
- 0x64A4,0x9350, // <cjk>
- 0x64A5,0x9D9B, // <cjk>
- 0x64A9,0x9D9C, // <cjk>
- 0x64AB,0x958F, // <cjk>
- 0x64AD,0x9464, // <cjk>
- 0x64AE,0x8E42, // <cjk>
- 0x64B0,0x90EF, // <cjk>
- 0x64B2,0x966F, // <cjk>
- 0x64B9,0x8A68, // <cjk>
- 0x64BB,0x9DA3, // <cjk>
- 0x64BC,0x9D9E, // <cjk>
- 0x64C1,0x9769, // <cjk>
- 0x64C2,0x9DA5, // <cjk>
- 0x64C5,0x9DA1, // <cjk>
- 0x64C7,0x9DA2, // <cjk>
- 0x64CD,0x9180, // <cjk>
- 0x64D2,0x9DA0, // <cjk>
- 0x64D4,0x9D5E, // <cjk>
- 0x64D8,0x9DA4, // <cjk>
- 0x64DA,0x9D9F, // <cjk>
- 0x64E0,0x9DA9, // <cjk>
- 0x64E1,0x9DAA, // <cjk>
- 0x64E2,0x9346, // <cjk>
- 0x64E3,0x9DAC, // <cjk>
- 0x64E6,0x8E43, // <cjk>
- 0x64E7,0x9DA7, // <cjk>
- 0x64EF,0x9DAD, // <cjk>
- 0x64F1,0x9DA6, // <cjk>
- 0x64F2,0x9DB1, // <cjk>
- 0x64F4,0x9DB0, // <cjk>
- 0x64F6,0x9DAF, // <cjk>
- 0x64FA,0x9DB2, // <cjk>
- 0x64FD,0x9DB4, // <cjk>
- 0x64FE,0x8FEF, // <cjk>
- 0x6500,0x9DB3, // <cjk>
- 0x6505,0x9DB7, // <cjk>
- 0x6518,0x9DB5, // <cjk>
- 0x651C,0x9DB6, // <cjk>
- 0x651D,0x9D90, // <cjk>
- 0x6523,0x9DB9, // <cjk>
- 0x6524,0x9DB8, // <cjk>
- 0x652A,0x9D98, // <cjk>
- 0x652B,0x9DBA, // <cjk>
- 0x652C,0x9DAE, // <cjk>
- 0x652F,0x8E78, // <cjk>
- 0x6534,0x9DBB, // <cjk>
- 0x6535,0x9DBC, // <cjk>
- 0x6536,0x9DBE, // <cjk>
- 0x6537,0x9DBD, // <cjk>
- 0x6538,0x9DBF, // <cjk>
- 0x6539,0x89FC, // <cjk>
- 0x653B,0x8D55, // <cjk>
- 0x653E,0x95FA, // <cjk>
- 0x653F,0x90AD, // <cjk>
- 0x6545,0x8CCC, // <cjk>
- 0x6548,0x9DC1, // <cjk>
- 0x654D,0x9DC4, // <cjk>
- 0x654F,0x9571, // <cjk>
- 0x6551,0x8B7E, // <cjk>
- 0x6555,0x9DC3, // <cjk>
- 0x6556,0x9DC2, // <cjk>
- 0x6557,0x9473, // <cjk>
- 0x6558,0x9DC5, // <cjk>
- 0x6559,0x8BB3, // <cjk>
- 0x655D,0x9DC7, // <cjk>
- 0x655E,0x9DC6, // <cjk>
- 0x6562,0x8AB8, // <cjk>
- 0x6563,0x8E55, // <cjk>
- 0x6566,0x93D6, // <cjk>
- 0x656C,0x8C68, // <cjk>
- 0x6570,0x9094, // <cjk>
- 0x6572,0x9DC8, // <cjk>
- 0x6574,0x90AE, // <cjk>
- 0x6575,0x9347, // <cjk>
- 0x6577,0x957E, // <cjk>
- 0x6578,0x9DC9, // <cjk>
- 0x6582,0x9DCA, // <cjk>
- 0x6583,0x9DCB, // <cjk>
- 0x6587,0x95B6, // <cjk>
- 0x6588,0x9B7C, // <cjk>
- 0x6589,0x90C4, // <cjk>
- 0x658C,0x956B, // <cjk>
- 0x658E,0x8DD6, // <cjk>
- 0x6590,0x94E3, // <cjk>
- 0x6591,0x94C1, // <cjk>
- 0x6597,0x936C, // <cjk>
- 0x6599,0x97BF, // <cjk>
- 0x659B,0x9DCD, // <cjk>
- 0x659C,0x8ECE, // <cjk>
- 0x659F,0x9DCE, // <cjk>
- 0x65A1,0x88B4, // <cjk>
- 0x65A4,0x8BD2, // <cjk>
- 0x65A5,0x90CB, // <cjk>
- 0x65A7,0x9580, // <cjk>
- 0x65AB,0x9DCF, // <cjk>
- 0x65AC,0x8E61, // <cjk>
- 0x65AD,0x9266, // <cjk>
- 0x65AF,0x8E7A, // <cjk>
- 0x65B0,0x9056, // <cjk>
- 0x65B7,0x9DD0, // <cjk>
- 0x65B9,0x95FB, // <cjk>
- 0x65BC,0x8997, // <cjk>
- 0x65BD,0x8E7B, // <cjk>
- 0x65C1,0x9DD3, // <cjk>
- 0x65C3,0x9DD1, // <cjk>
- 0x65C4,0x9DD4, // <cjk>
- 0x65C5,0x97B7, // <cjk>
- 0x65C6,0x9DD2, // <cjk>
- 0x65CB,0x90F9, // <cjk>
- 0x65CC,0x9DD5, // <cjk>
- 0x65CF,0x91B0, // <cjk>
- 0x65D2,0x9DD6, // <cjk>
- 0x65D7,0x8AF8, // <cjk>
- 0x65D9,0x9DD8, // <cjk>
- 0x65DB,0x9DD7, // <cjk>
- 0x65E0,0x9DD9, // <cjk>
- 0x65E1,0x9DDA, // <cjk>
- 0x65E2,0x8AF9, // <cjk>
- 0x65E5,0x93FA, // <cjk>
- 0x65E6,0x9255, // <cjk>
- 0x65E7,0x8B8C, // <cjk>
- 0x65E8,0x8E7C, // <cjk>
- 0x65E9,0x9181, // <cjk>
- 0x65EC,0x8F7B, // <cjk>
- 0x65ED,0x88AE, // <cjk>
- 0x65F1,0x9DDB, // <cjk>
- 0x65FA,0x89A0, // <cjk>
- 0x65FB,0x9DDF, // <cjk>
- 0x6602,0x8D56, // <cjk>
- 0x6603,0x9DDE, // <cjk>
- 0x6606,0x8DA9, // <cjk>
- 0x6607,0x8FB8, // <cjk>
- 0x660A,0x9DDD, // <cjk>
- 0x660C,0x8FB9, // <cjk>
- 0x660E,0x96BE, // <cjk>
- 0x660F,0x8DA8, // <cjk>
- 0x6613,0x88D5, // <cjk>
- 0x6614,0x90CC, // <cjk>
- 0x661C,0x9DE4, // <cjk>
- 0x661F,0x90AF, // <cjk>
- 0x6620,0x8966, // <cjk>
- 0x6625,0x8F74, // <cjk>
- 0x6627,0x9686, // <cjk>
- 0x6628,0x8DF0, // <cjk>
- 0x662D,0x8FBA, // <cjk>
- 0x662F,0x90A5, // <cjk>
- 0x6634,0x9DE3, // <cjk>
- 0x6635,0x9DE1, // <cjk>
- 0x6636,0x9DE2, // <cjk>
- 0x663C,0x928B, // <cjk>
- 0x663F,0x9E45, // <cjk>
- 0x6641,0x9DE8, // <cjk>
- 0x6642,0x8E9E, // <cjk>
- 0x6643,0x8D57, // <cjk>
- 0x6644,0x9DE6, // <cjk>
- 0x6649,0x9DE7, // <cjk>
- 0x664B,0x9057, // <cjk>
- 0x664F,0x9DE5, // <cjk>
- 0x6652,0x8E4E, // <cjk>
- 0x665D,0x9DEA, // <cjk>
- 0x665E,0x9DE9, // <cjk>
- 0x665F,0x9DEE, // <cjk>
- 0x6662,0x9DEF, // <cjk>
- 0x6664,0x9DEB, // <cjk>
- 0x6666,0x8A41, // <cjk>
- 0x6667,0x9DEC, // <cjk>
- 0x6668,0x9DED, // <cjk>
- 0x6669,0x94D3, // <cjk>
- 0x666E,0x9581, // <cjk>
- 0x666F,0x8C69, // <cjk>
- 0x6670,0x9DF0, // <cjk>
- 0x6674,0x90B0, // <cjk>
- 0x6676,0x8FBB, // <cjk>
- 0x667A,0x9271, // <cjk>
- 0x6681,0x8BC5, // <cjk>
- 0x6683,0x9DF1, // <cjk>
- 0x6684,0x9DF5, // <cjk>
- 0x6687,0x89C9, // <cjk>
- 0x6688,0x9DF2, // <cjk>
- 0x6689,0x9DF4, // <cjk>
- 0x668E,0x9DF3, // <cjk>
- 0x6691,0x8F8B, // <cjk>
- 0x6696,0x9267, // <cjk>
- 0x6697,0x88C3, // <cjk>
- 0x6698,0x9DF6, // <cjk>
- 0x669D,0x9DF7, // <cjk>
- 0x66A2,0x92A8, // <cjk>
- 0x66A6,0x97EF, // <cjk>
- 0x66AB,0x8E62, // <cjk>
- 0x66AE,0x95E9, // <cjk>
- 0x66B4,0x965C, // <cjk>
- 0x66B8,0x9E41, // <cjk>
- 0x66B9,0x9DF9, // <cjk>
- 0x66BC,0x9DFC, // <cjk>
- 0x66BE,0x9DFB, // <cjk>
- 0x66C1,0x9DF8, // <cjk>
- 0x66C4,0x9E40, // <cjk>
- 0x66C7,0x93DC, // <cjk>
- 0x66C9,0x9DFA, // <cjk>
- 0x66D6,0x9E42, // <cjk>
- 0x66D9,0x8F8C, // <cjk>
- 0x66DA,0x9E43, // <cjk>
- 0x66DC,0x976A, // <cjk>
- 0x66DD,0x9498, // <cjk>
- 0x66E0,0x9E44, // <cjk>
- 0x66E6,0x9E46, // <cjk>
- 0x66E9,0x9E47, // <cjk>
- 0x66F0,0x9E48, // <cjk>
- 0x66F2,0x8BC8, // <cjk>
- 0x66F3,0x8967, // <cjk>
- 0x66F4,0x8D58, // <cjk>
- 0x66F5,0x9E49, // <cjk>
- 0x66F7,0x9E4A, // <cjk>
- 0x66F8,0x8F91, // <cjk>
- 0x66F9,0x9182, // <cjk>
- 0x66FC,0x99D6, // <cjk>
- 0x66FD,0x915D, // <cjk>
- 0x66FE,0x915C, // <cjk>
- 0x66FF,0x91D6, // <cjk>
- 0x6700,0x8DC5, // <cjk>
- 0x6703,0x98F0, // <cjk>
- 0x6708,0x8C8E, // <cjk>
- 0x6709,0x974C, // <cjk>
- 0x670B,0x95FC, // <cjk>
- 0x670D,0x959E, // <cjk>
- 0x670F,0x9E4B, // <cjk>
- 0x6714,0x8DF1, // <cjk>
- 0x6715,0x92BD, // <cjk>
- 0x6716,0x9E4C, // <cjk>
- 0x6717,0x984E, // <cjk>
- 0x671B,0x965D, // <cjk>
- 0x671D,0x92A9, // <cjk>
- 0x671E,0x9E4D, // <cjk>
- 0x671F,0x8AFA, // <cjk>
- 0x6726,0x9E4E, // <cjk>
- 0x6727,0x9E4F, // <cjk>
- 0x6728,0x96D8, // <cjk>
- 0x672A,0x96A2, // <cjk>
- 0x672B,0x9696, // <cjk>
- 0x672C,0x967B, // <cjk>
- 0x672D,0x8E44, // <cjk>
- 0x672E,0x9E51, // <cjk>
- 0x6731,0x8EE9, // <cjk>
- 0x6734,0x9670, // <cjk>
- 0x6736,0x9E53, // <cjk>
- 0x6737,0x9E56, // <cjk>
- 0x6738,0x9E55, // <cjk>
- 0x673A,0x8AF7, // <cjk>
- 0x673D,0x8B80, // <cjk>
- 0x673F,0x9E52, // <cjk>
- 0x6741,0x9E54, // <cjk>
- 0x6746,0x9E57, // <cjk>
- 0x6749,0x9099, // <cjk>
- 0x674E,0x979B, // <cjk>
- 0x674F,0x88C7, // <cjk>
- 0x6750,0x8DDE, // <cjk>
- 0x6751,0x91BA, // <cjk>
- 0x6753,0x8EDB, // <cjk>
- 0x6756,0x8FF1, // <cjk>
- 0x6759,0x9E5A, // <cjk>
- 0x675C,0x936D, // <cjk>
- 0x675E,0x9E58, // <cjk>
- 0x675F,0x91A9, // <cjk>
- 0x6760,0x9E59, // <cjk>
- 0x6761,0x8FF0, // <cjk>
- 0x6762,0x96DB, // <cjk>
- 0x6764,0x9E5C, // <cjk>
- 0x6765,0x9788, // <cjk>
- 0x676A,0x9E61, // <cjk>
- 0x676D,0x8D59, // <cjk>
- 0x676F,0x9474, // <cjk>
- 0x6770,0x9E5E, // <cjk>
- 0x6771,0x938C, // <cjk>
- 0x6772,0x9DDC, // <cjk>
- 0x6773,0x9DE0, // <cjk>
- 0x6775,0x8B6E, // <cjk>
- 0x6777,0x9466, // <cjk>
- 0x677C,0x9E60, // <cjk>
- 0x677E,0x8FBC, // <cjk>
- 0x677F,0x94C2, // <cjk>
- 0x6785,0x9E66, // <cjk>
- 0x6787,0x94F8, // <cjk>
- 0x6789,0x9E5D, // <cjk>
- 0x678B,0x9E63, // <cjk>
- 0x678C,0x9E62, // <cjk>
- 0x6790,0x90CD, // <cjk>
- 0x6795,0x968D, // <cjk>
- 0x6797,0x97D1, // <cjk>
- 0x679A,0x9687, // <cjk>
- 0x679C,0x89CA, // <cjk>
- 0x679D,0x8E7D, // <cjk>
- 0x67A0,0x9867, // <cjk>
- 0x67A1,0x9E65, // <cjk>
- 0x67A2,0x9095, // <cjk>
- 0x67A6,0x9E64, // <cjk>
- 0x67A9,0x9E5F, // <cjk>
- 0x67AF,0x8CCD, // <cjk>
- 0x67B3,0x9E6B, // <cjk>
- 0x67B4,0x9E69, // <cjk>
- 0x67B6,0x89CB, // <cjk>
- 0x67B7,0x9E67, // <cjk>
- 0x67B8,0x9E6D, // <cjk>
- 0x67B9,0x9E73, // <cjk>
- 0x67C1,0x91C6, // <cjk>
- 0x67C4,0x95BF, // <cjk>
- 0x67C6,0x9E75, // <cjk>
- 0x67CA,0x9541, // <cjk>
- 0x67CE,0x9E74, // <cjk>
- 0x67CF,0x9490, // <cjk>
- 0x67D0,0x965E, // <cjk>
- 0x67D1,0x8AB9, // <cjk>
- 0x67D3,0x90F5, // <cjk>
- 0x67D4,0x8F5F, // <cjk>
- 0x67D8,0x92D1, // <cjk>
- 0x67DA,0x974D, // <cjk>
- 0x67DD,0x9E70, // <cjk>
- 0x67DE,0x9E6F, // <cjk>
- 0x67E2,0x9E71, // <cjk>
- 0x67E4,0x9E6E, // <cjk>
- 0x67E7,0x9E76, // <cjk>
- 0x67E9,0x9E6C, // <cjk>
- 0x67EC,0x9E6A, // <cjk>
- 0x67EE,0x9E72, // <cjk>
- 0x67EF,0x9E68, // <cjk>
- 0x67F1,0x928C, // <cjk>
- 0x67F3,0x96F6, // <cjk>
- 0x67F4,0x8EC4, // <cjk>
- 0x67F5,0x8DF2, // <cjk>
- 0x67FB,0x8DB8, // <cjk>
- 0x67FE,0x968F, // <cjk>
- 0x67FF,0x8A60, // <cjk>
- 0x6802,0x92CC, // <cjk>
- 0x6803,0x93C8, // <cjk>
- 0x6804,0x8968, // <cjk>
- 0x6813,0x90F0, // <cjk>
- 0x6816,0x90B2, // <cjk>
- 0x6817,0x8C49, // <cjk>
- 0x681E,0x9E78, // <cjk>
- 0x6821,0x8D5A, // <cjk>
- 0x6822,0x8A9C, // <cjk>
- 0x6829,0x9E7A, // <cjk>
- 0x682A,0x8A94, // <cjk>
- 0x682B,0x9E81, // <cjk>
- 0x6832,0x9E7D, // <cjk>
- 0x6834,0x90F1, // <cjk>
- 0x6838,0x8A6A, // <cjk>
- 0x6839,0x8DAA, // <cjk>
- 0x683C,0x8A69, // <cjk>
- 0x683D,0x8DCD, // <cjk>
- 0x6840,0x9E7B, // <cjk>
- 0x6841,0x8C85, // <cjk>
- 0x6842,0x8C6A, // <cjk>
- 0x6843,0x938D, // <cjk>
- 0x6846,0x9E79, // <cjk>
- 0x6848,0x88C4, // <cjk>
- 0x684D,0x9E7C, // <cjk>
- 0x684E,0x9E7E, // <cjk>
- 0x6850,0x8BCB, // <cjk>
- 0x6851,0x8C4B, // <cjk>
- 0x6853,0x8ABA, // <cjk>
- 0x6854,0x8B6A, // <cjk>
- 0x6859,0x9E82, // <cjk>
- 0x685C,0x8DF7, // <cjk>
- 0x685D,0x9691, // <cjk>
- 0x685F,0x8E56, // <cjk>
- 0x6863,0x9E83, // <cjk>
- 0x6867,0x954F, // <cjk>
- 0x6874,0x9E8F, // <cjk>
- 0x6876,0x89B1, // <cjk>
- 0x6877,0x9E84, // <cjk>
- 0x687E,0x9E95, // <cjk>
- 0x687F,0x9E85, // <cjk>
- 0x6881,0x97C0, // <cjk>
- 0x6883,0x9E8C, // <cjk>
- 0x6885,0x947E, // <cjk>
- 0x688D,0x9E94, // <cjk>
- 0x688F,0x9E87, // <cjk>
- 0x6893,0x88B2, // <cjk>
- 0x6894,0x9E89, // <cjk>
- 0x689B,0x9E8B, // <cjk>
- 0x689D,0x9E8A, // <cjk>
- 0x689F,0x9E86, // <cjk>
- 0x68A0,0x9E91, // <cjk>
- 0x68A2,0x8FBD, // <cjk>
- 0x68A6,0x9AEB, // <cjk>
- 0x68A7,0x8CE6, // <cjk>
- 0x68A8,0x979C, // <cjk>
- 0x68AD,0x9E88, // <cjk>
- 0x68AF,0x92F2, // <cjk>
- 0x68B0,0x8A42, // <cjk>
- 0x68B1,0x8DAB, // <cjk>
- 0x68B3,0x9E80, // <cjk>
- 0x68B5,0x9E90, // <cjk>
- 0x68B6,0x8A81, // <cjk>
- 0x68B9,0x9E8E, // <cjk>
- 0x68BA,0x9E92, // <cjk>
- 0x68BC,0x938E, // <cjk>
- 0x68C4,0x8AFC, // <cjk>
- 0x68C6,0x9EB0, // <cjk>
- 0x68C9,0x96C7, // <cjk>
- 0x68CA,0x9E97, // <cjk>
- 0x68CB,0x8AFB, // <cjk>
- 0x68CD,0x9E9E, // <cjk>
- 0x68D2,0x965F, // <cjk>
- 0x68D4,0x9E9F, // <cjk>
- 0x68D5,0x9EA1, // <cjk>
- 0x68D7,0x9EA5, // <cjk>
- 0x68D8,0x9E99, // <cjk>
- 0x68DA,0x9249, // <cjk>
- 0x68DF,0x938F, // <cjk>
- 0x68E0,0x9EA9, // <cjk>
- 0x68E1,0x9E9C, // <cjk>
- 0x68E3,0x9EA6, // <cjk>
- 0x68E7,0x9EA0, // <cjk>
- 0x68EE,0x9058, // <cjk>
- 0x68EF,0x9EAA, // <cjk>
- 0x68F2,0x90B1, // <cjk>
- 0x68F9,0x9EA8, // <cjk>
- 0x68FA,0x8ABB, // <cjk>
- 0x6900,0x986F, // <cjk>
- 0x6901,0x9E96, // <cjk>
- 0x6904,0x9EA4, // <cjk>
- 0x6905,0x88D6, // <cjk>
- 0x6908,0x9E98, // <cjk>
- 0x690B,0x96B8, // <cjk>
- 0x690C,0x9E9D, // <cjk>
- 0x690D,0x9041, // <cjk>
- 0x690E,0x92C5, // <cjk>
- 0x690F,0x9E93, // <cjk>
- 0x6912,0x9EA3, // <cjk>
- 0x6919,0x909A, // <cjk>
- 0x691A,0x9EAD, // <cjk>
- 0x691B,0x8A91, // <cjk>
- 0x691C,0x8C9F, // <cjk>
- 0x6921,0x9EAF, // <cjk>
- 0x6922,0x9E9A, // <cjk>
- 0x6923,0x9EAE, // <cjk>
- 0x6925,0x9EA7, // <cjk>
- 0x6926,0x9E9B, // <cjk>
- 0x6928,0x9EAB, // <cjk>
- 0x692A,0x9EAC, // <cjk>
- 0x6930,0x9EBD, // <cjk>
- 0x6934,0x93CC, // <cjk>
- 0x6936,0x9EA2, // <cjk>
- 0x6939,0x9EB9, // <cjk>
- 0x693D,0x9EBB, // <cjk>
- 0x693F,0x92D6, // <cjk>
- 0x694A,0x976B, // <cjk>
- 0x6953,0x9596, // <cjk>
- 0x6954,0x9EB6, // <cjk>
- 0x6955,0x91C8, // <cjk>
- 0x6959,0x9EBC, // <cjk>
- 0x695A,0x915E, // <cjk>
- 0x695C,0x9EB3, // <cjk>
- 0x695D,0x9EC0, // <cjk>
- 0x695E,0x9EBF, // <cjk>
- 0x6960,0x93ED, // <cjk>
- 0x6961,0x9EBE, // <cjk>
- 0x6962,0x93E8, // <cjk>
- 0x696A,0x9EC2, // <cjk>
- 0x696B,0x9EB5, // <cjk>
- 0x696D,0x8BC6, // <cjk>
- 0x696E,0x9EB8, // <cjk>
- 0x696F,0x8F7C, // <cjk>
- 0x6973,0x9480, // <cjk>
- 0x6974,0x9EBA, // <cjk>
- 0x6975,0x8BC9, // <cjk>
- 0x6977,0x9EB2, // <cjk>
- 0x6978,0x9EB4, // <cjk>
- 0x6979,0x9EB1, // <cjk>
- 0x697C,0x984F, // <cjk>
- 0x697D,0x8A79, // <cjk>
- 0x697E,0x9EB7, // <cjk>
- 0x6981,0x9EC1, // <cjk>
- 0x6982,0x8A54, // <cjk>
- 0x698A,0x8DE5, // <cjk>
- 0x698E,0x897C, // <cjk>
- 0x6991,0x9ED2, // <cjk>
- 0x6994,0x9850, // <cjk>
- 0x6995,0x9ED5, // <cjk>
- 0x699B,0x9059, // <cjk>
- 0x699C,0x9ED4, // <cjk>
- 0x69A0,0x9ED3, // <cjk>
- 0x69A7,0x9ED0, // <cjk>
- 0x69AE,0x9EC4, // <cjk>
- 0x69B1,0x9EE1, // <cjk>
- 0x69B2,0x9EC3, // <cjk>
- 0x69B4,0x9ED6, // <cjk>
- 0x69BB,0x9ECE, // <cjk>
- 0x69BE,0x9EC9, // <cjk>
- 0x69BF,0x9EC6, // <cjk>
- 0x69C1,0x9EC7, // <cjk>
- 0x69C3,0x9ECF, // <cjk>
- 0x69C7,0xEAA0, // <cjk>
- 0x69CA,0x9ECC, // <cjk>
- 0x69CB,0x8D5C, // <cjk>
- 0x69CC,0x92C6, // <cjk>
- 0x69CD,0x9184, // <cjk>
- 0x69CE,0x9ECA, // <cjk>
- 0x69D0,0x9EC5, // <cjk>
- 0x69D3,0x9EC8, // <cjk>
- 0x69D8,0x976C, // <cjk>
- 0x69D9,0x968A, // <cjk>
- 0x69DD,0x9ECD, // <cjk>
- 0x69DE,0x9ED7, // <cjk>
- 0x69E7,0x9EDF, // <cjk>
- 0x69E8,0x9ED8, // <cjk>
- 0x69EB,0x9EE5, // <cjk>
- 0x69ED,0x9EE3, // <cjk>
- 0x69F2,0x9EDE, // <cjk>
- 0x69F9,0x9EDD, // <cjk>
- 0x69FB,0x92CE, // <cjk>
- 0x69FD,0x9185, // <cjk>
- 0x69FF,0x9EDB, // <cjk>
- 0x6A02,0x9ED9, // <cjk>
- 0x6A05,0x9EE0, // <cjk>
- 0x6A0A,0x9EE6, // <cjk>
- 0x6A0B,0x94F3, // <cjk>
- 0x6A0C,0x9EEC, // <cjk>
- 0x6A12,0x9EE7, // <cjk>
- 0x6A13,0x9EEA, // <cjk>
- 0x6A14,0x9EE4, // <cjk>
- 0x6A17,0x9294, // <cjk>
- 0x6A19,0x9557, // <cjk>
- 0x6A1B,0x9EDA, // <cjk>
- 0x6A1E,0x9EE2, // <cjk>
- 0x6A1F,0x8FBE, // <cjk>
- 0x6A21,0x96CD, // <cjk>
- 0x6A22,0x9EF6, // <cjk>
- 0x6A23,0x9EE9, // <cjk>
- 0x6A29,0x8CA0, // <cjk>
- 0x6A2A,0x89A1, // <cjk>
- 0x6A2B,0x8A7E, // <cjk>
- 0x6A2E,0x9ED1, // <cjk>
- 0x6A35,0x8FBF, // <cjk>
- 0x6A36,0x9EEE, // <cjk>
- 0x6A38,0x9EF5, // <cjk>
- 0x6A39,0x8EF7, // <cjk>
- 0x6A3A,0x8A92, // <cjk>
- 0x6A3D,0x924D, // <cjk>
- 0x6A44,0x9EEB, // <cjk>
- 0x6A47,0x9EF0, // <cjk>
- 0x6A48,0x9EF4, // <cjk>
- 0x6A4B,0x8BB4, // <cjk>
- 0x6A58,0x8B6B, // <cjk>
- 0x6A59,0x9EF2, // <cjk>
- 0x6A5F,0x8B40, // <cjk>
- 0x6A61,0x93C9, // <cjk>
- 0x6A62,0x9EF1, // <cjk>
- 0x6A66,0x9EF3, // <cjk>
- 0x6A72,0x9EED, // <cjk>
- 0x6A78,0x9EEF, // <cjk>
- 0x6A7F,0x8A80, // <cjk>
- 0x6A80,0x9268, // <cjk>
- 0x6A84,0x9EFA, // <cjk>
- 0x6A8D,0x9EF8, // <cjk>
- 0x6A8E,0x8CE7, // <cjk>
- 0x6A90,0x9EF7, // <cjk>
- 0x6A97,0x9F40, // <cjk>
- 0x6A9C,0x9E77, // <cjk>
- 0x6AA0,0x9EF9, // <cjk>
- 0x6AA2,0x9EFB, // <cjk>
- 0x6AA3,0x9EFC, // <cjk>
- 0x6AAA,0x9F4B, // <cjk>
- 0x6AAC,0x9F47, // <cjk>
- 0x6AAE,0x9E8D, // <cjk>
- 0x6AB3,0x9F46, // <cjk>
- 0x6AB8,0x9F45, // <cjk>
- 0x6ABB,0x9F42, // <cjk>
- 0x6AC1,0x9EE8, // <cjk>
- 0x6AC2,0x9F44, // <cjk>
- 0x6AC3,0x9F43, // <cjk>
- 0x6AD1,0x9F49, // <cjk>
- 0x6AD3,0x9845, // <cjk>
- 0x6ADA,0x9F4C, // <cjk>
- 0x6ADB,0x8BF9, // <cjk>
- 0x6ADE,0x9F48, // <cjk>
- 0x6ADF,0x9F4A, // <cjk>
- 0x6AE8,0x94A5, // <cjk>
- 0x6AEA,0x9F4D, // <cjk>
- 0x6AFA,0x9F51, // <cjk>
- 0x6AFB,0x9F4E, // <cjk>
- 0x6B04,0x9793, // <cjk>
- 0x6B05,0x9F4F, // <cjk>
- 0x6B0A,0x9EDC, // <cjk>
- 0x6B12,0x9F52, // <cjk>
- 0x6B16,0x9F53, // <cjk>
- 0x6B1D,0x8954, // <cjk>
- 0x6B1F,0x9F55, // <cjk>
- 0x6B20,0x8C87, // <cjk>
- 0x6B21,0x8E9F, // <cjk>
- 0x6B23,0x8BD3, // <cjk>
- 0x6B27,0x89A2, // <cjk>
- 0x6B32,0x977E, // <cjk>
- 0x6B37,0x9F57, // <cjk>
- 0x6B38,0x9F56, // <cjk>
- 0x6B39,0x9F59, // <cjk>
- 0x6B3A,0x8B5C, // <cjk>
- 0x6B3D,0x8BD4, // <cjk>
- 0x6B3E,0x8ABC, // <cjk>
- 0x6B43,0x9F5C, // <cjk>
- 0x6B49,0x9F5D, // <cjk>
- 0x6B4C,0x89CC, // <cjk>
- 0x6B4E,0x9256, // <cjk>
- 0x6B50,0x9F5E, // <cjk>
- 0x6B53,0x8ABD, // <cjk>
- 0x6B54,0x9F60, // <cjk>
- 0x6B59,0x9F5F, // <cjk>
- 0x6B5B,0x9F61, // <cjk>
- 0x6B5F,0x9F62, // <cjk>
- 0x6B61,0x9F63, // <cjk>
- 0x6B62,0x8E7E, // <cjk>
- 0x6B63,0x90B3, // <cjk>
- 0x6B64,0x8D9F, // <cjk>
- 0x6B66,0x9590, // <cjk>
- 0x6B69,0x95E0, // <cjk>
- 0x6B6A,0x9863, // <cjk>
- 0x6B6F,0x8E95, // <cjk>
- 0x6B73,0x8DCE, // <cjk>
- 0x6B74,0x97F0, // <cjk>
- 0x6B78,0x9F64, // <cjk>
- 0x6B79,0x9F65, // <cjk>
- 0x6B7B,0x8E80, // <cjk>
- 0x6B7F,0x9F66, // <cjk>
- 0x6B80,0x9F67, // <cjk>
- 0x6B83,0x9F69, // <cjk>
- 0x6B84,0x9F68, // <cjk>
- 0x6B86,0x9677, // <cjk>
- 0x6B89,0x8F7D, // <cjk>
- 0x6B8A,0x8EEA, // <cjk>
- 0x6B8B,0x8E63, // <cjk>
- 0x6B8D,0x9F6A, // <cjk>
- 0x6B95,0x9F6C, // <cjk>
- 0x6B96,0x9042, // <cjk>
- 0x6B98,0x9F6B, // <cjk>
- 0x6B9E,0x9F6D, // <cjk>
- 0x6BA4,0x9F6E, // <cjk>
- 0x6BAA,0x9F6F, // <cjk>
- 0x6BAB,0x9F70, // <cjk>
- 0x6BAF,0x9F71, // <cjk>
- 0x6BB1,0x9F73, // <cjk>
- 0x6BB2,0x9F72, // <cjk>
- 0x6BB3,0x9F74, // <cjk>
- 0x6BB4,0x89A3, // <cjk>
- 0x6BB5,0x9269, // <cjk>
- 0x6BB7,0x9F75, // <cjk>
- 0x6BBA,0x8E45, // <cjk>
- 0x6BBB,0x8A6B, // <cjk>
- 0x6BBC,0x9F76, // <cjk>
- 0x6BBF,0x9361, // <cjk>
- 0x6BC0,0x9ACA, // <cjk>
- 0x6BC5,0x8B42, // <cjk>
- 0x6BC6,0x9F77, // <cjk>
- 0x6BCB,0x9F78, // <cjk>
- 0x6BCD,0x95EA, // <cjk>
- 0x6BCE,0x9688, // <cjk>
- 0x6BD2,0x93C5, // <cjk>
- 0x6BD3,0x9F79, // <cjk>
- 0x6BD4,0x94E4, // <cjk>
- 0x6BD8,0x94F9, // <cjk>
- 0x6BDB,0x96D1, // <cjk>
- 0x6BDF,0x9F7A, // <cjk>
- 0x6BEB,0x9F7C, // <cjk>
- 0x6BEC,0x9F7B, // <cjk>
- 0x6BEF,0x9F7E, // <cjk>
- 0x6BF3,0x9F7D, // <cjk>
- 0x6C08,0x9F81, // <cjk>
- 0x6C0F,0x8E81, // <cjk>
- 0x6C11,0x96AF, // <cjk>
- 0x6C13,0x9F82, // <cjk>
- 0x6C14,0x9F83, // <cjk>
- 0x6C17,0x8B43, // <cjk>
- 0x6C1B,0x9F84, // <cjk>
- 0x6C23,0x9F86, // <cjk>
- 0x6C24,0x9F85, // <cjk>
- 0x6C34,0x9085, // <cjk>
- 0x6C37,0x9558, // <cjk>
- 0x6C38,0x8969, // <cjk>
- 0x6C3E,0x94C3, // <cjk>
- 0x6C40,0x92F3, // <cjk>
- 0x6C41,0x8F60, // <cjk>
- 0x6C42,0x8B81, // <cjk>
- 0x6C4E,0x94C4, // <cjk>
- 0x6C50,0x8EAC, // <cjk>
- 0x6C55,0x9F88, // <cjk>
- 0x6C57,0x8ABE, // <cjk>
- 0x6C5A,0x8998, // <cjk>
- 0x6C5D,0x93F0, // <cjk>
- 0x6C5E,0x9F87, // <cjk>
- 0x6C5F,0x8D5D, // <cjk>
- 0x6C60,0x9272, // <cjk>
- 0x6C62,0x9F89, // <cjk>
- 0x6C68,0x9F91, // <cjk>
- 0x6C6A,0x9F8A, // <cjk>
- 0x6C70,0x91BF, // <cjk>
- 0x6C72,0x8B82, // <cjk>
- 0x6C73,0x9F92, // <cjk>
- 0x6C7A,0x8C88, // <cjk>
- 0x6C7D,0x8B44, // <cjk>
- 0x6C7E,0x9F90, // <cjk>
- 0x6C81,0x9F8E, // <cjk>
- 0x6C82,0x9F8B, // <cjk>
- 0x6C83,0x9780, // <cjk>
- 0x6C88,0x92BE, // <cjk>
- 0x6C8C,0x93D7, // <cjk>
- 0x6C8D,0x9F8C, // <cjk>
- 0x6C90,0x9F94, // <cjk>
- 0x6C92,0x9F93, // <cjk>
- 0x6C93,0x8C42, // <cjk>
- 0x6C96,0x89AB, // <cjk>
- 0x6C99,0x8DB9, // <cjk>
- 0x6C9A,0x9F8D, // <cjk>
- 0x6C9B,0x9F8F, // <cjk>
- 0x6CA1,0x9676, // <cjk>
- 0x6CA2,0x91F2, // <cjk>
- 0x6CAB,0x9697, // <cjk>
- 0x6CAE,0x9F9C, // <cjk>
- 0x6CB1,0x9F9D, // <cjk>
- 0x6CB3,0x89CD, // <cjk>
- 0x6CB8,0x95A6, // <cjk>
- 0x6CB9,0x96FB, // <cjk>
- 0x6CBA,0x9F9F, // <cjk>
- 0x6CBB,0x8EA1, // <cjk>
- 0x6CBC,0x8FC0, // <cjk>
- 0x6CBD,0x9F98, // <cjk>
- 0x6CBE,0x9F9E, // <cjk>
- 0x6CBF,0x8988, // <cjk>
- 0x6CC1,0x8BB5, // <cjk>
- 0x6CC4,0x9F95, // <cjk>
- 0x6CC5,0x9F9A, // <cjk>
- 0x6CC9,0x90F2, // <cjk>
- 0x6CCA,0x9491, // <cjk>
- 0x6CCC,0x94E5, // <cjk>
- 0x6CD3,0x9F97, // <cjk>
- 0x6CD5,0x9640, // <cjk>
- 0x6CD7,0x9F99, // <cjk>
- 0x6CD9,0x9FA2, // <cjk>
- 0x6CDB,0x9FA0, // <cjk>
- 0x6CDD,0x9F9B, // <cjk>
- 0x6CE1,0x9641, // <cjk>
- 0x6CE2,0x9467, // <cjk>
- 0x6CE3,0x8B83, // <cjk>
- 0x6CE5,0x9344, // <cjk>
- 0x6CE8,0x928D, // <cjk>
- 0x6CEA,0x9FA3, // <cjk>
- 0x6CEF,0x9FA1, // <cjk>
- 0x6CF0,0x91D7, // <cjk>
- 0x6CF1,0x9F96, // <cjk>
- 0x6CF3,0x896A, // <cjk>
- 0x6D0B,0x976D, // <cjk>
- 0x6D0C,0x9FAE, // <cjk>
- 0x6D12,0x9FAD, // <cjk>
- 0x6D17,0x90F4, // <cjk>
- 0x6D19,0x9FAA, // <cjk>
- 0x6D1B,0x978C, // <cjk>
- 0x6D1E,0x93B4, // <cjk>
- 0x6D1F,0x9FA4, // <cjk>
- 0x6D25,0x92C3, // <cjk>
- 0x6D29,0x896B, // <cjk>
- 0x6D2A,0x8D5E, // <cjk>
- 0x6D2B,0x9FA7, // <cjk>
- 0x6D32,0x8F46, // <cjk>
- 0x6D33,0x9FAC, // <cjk>
- 0x6D35,0x9FAB, // <cjk>
- 0x6D36,0x9FA6, // <cjk>
- 0x6D38,0x9FA9, // <cjk>
- 0x6D3B,0x8A88, // <cjk>
- 0x6D3D,0x9FA8, // <cjk>
- 0x6D3E,0x9468, // <cjk>
- 0x6D41,0x97AC, // <cjk>
- 0x6D44,0x8FF2, // <cjk>
- 0x6D45,0x90F3, // <cjk>
- 0x6D59,0x9FB4, // <cjk>
- 0x6D5A,0x9FB2, // <cjk>
- 0x6D5C,0x956C, // <cjk>
- 0x6D63,0x9FAF, // <cjk>
- 0x6D64,0x9FB1, // <cjk>
- 0x6D66,0x8959, // <cjk>
- 0x6D69,0x8D5F, // <cjk>
- 0x6D6A,0x9851, // <cjk>
- 0x6D6C,0x8A5C, // <cjk>
- 0x6D6E,0x9582, // <cjk>
- 0x6D74,0x9781, // <cjk>
- 0x6D77,0x8A43, // <cjk>
- 0x6D78,0x905A, // <cjk>
- 0x6D79,0x9FB3, // <cjk>
- 0x6D85,0x9FB8, // <cjk>
- 0x6D88,0x8FC1, // <cjk>
- 0x6D8C,0x974F, // <cjk>
- 0x6D8E,0x9FB5, // <cjk>
- 0x6D93,0x9FB0, // <cjk>
- 0x6D95,0x9FB6, // <cjk>
- 0x6D99,0x97DC, // <cjk>
- 0x6D9B,0x9393, // <cjk>
- 0x6D9C,0x93C0, // <cjk>
- 0x6DAF,0x8A55, // <cjk>
- 0x6DB2,0x8974, // <cjk>
- 0x6DB5,0x9FBC, // <cjk>
- 0x6DB8,0x9FBF, // <cjk>
- 0x6DBC,0x97C1, // <cjk>
- 0x6DC0,0x9784, // <cjk>
- 0x6DC5,0x9FC6, // <cjk>
- 0x6DC6,0x9FC0, // <cjk>
- 0x6DC7,0x9FBD, // <cjk>
- 0x6DCB,0x97D2, // <cjk>
- 0x6DCC,0x9FC3, // <cjk>
- 0x6DD1,0x8F69, // <cjk>
- 0x6DD2,0x9FC5, // <cjk>
- 0x6DD5,0x9FCA, // <cjk>
- 0x6DD8,0x9391, // <cjk>
- 0x6DD9,0x9FC8, // <cjk>
- 0x6DDE,0x9FC2, // <cjk>
- 0x6DE1,0x9257, // <cjk>
- 0x6DE4,0x9FC9, // <cjk>
- 0x6DE6,0x9FBE, // <cjk>
- 0x6DE8,0x9FC4, // <cjk>
- 0x6DEA,0x9FCB, // <cjk>
- 0x6DEB,0x88FA, // <cjk>
- 0x6DEC,0x9FC1, // <cjk>
- 0x6DEE,0x9FCC, // <cjk>
- 0x6DF3,0x8F7E, // <cjk>
- 0x6DF5,0x95A3, // <cjk>
- 0x6DF7,0x8DAC, // <cjk>
- 0x6DF9,0x9FB9, // <cjk>
- 0x6DFA,0x9FC7, // <cjk>
- 0x6DFB,0x9359, // <cjk>
- 0x6E05,0x90B4, // <cjk>
- 0x6E07,0x8A89, // <cjk>
- 0x6E08,0x8DCF, // <cjk>
- 0x6E09,0x8FC2, // <cjk>
- 0x6E0A,0x9FBB, // <cjk>
- 0x6E0B,0x8F61, // <cjk>
- 0x6E13,0x8C6B, // <cjk>
- 0x6E15,0x9FBA, // <cjk>
- 0x6E19,0x9FD0, // <cjk>
- 0x6E1A,0x8F8D, // <cjk>
- 0x6E1B,0x8CB8, // <cjk>
- 0x6E1D,0x9FDF, // <cjk>
- 0x6E1F,0x9FD9, // <cjk>
- 0x6E20,0x8B94, // <cjk>
- 0x6E21,0x936E, // <cjk>
- 0x6E23,0x9FD4, // <cjk>
- 0x6E24,0x9FDD, // <cjk>
- 0x6E25,0x88AD, // <cjk>
- 0x6E26,0x8951, // <cjk>
- 0x6E29,0x89B7, // <cjk>
- 0x6E2B,0x9FD6, // <cjk>
- 0x6E2C,0x91AA, // <cjk>
- 0x6E2D,0x9FCD, // <cjk>
- 0x6E2E,0x9FCF, // <cjk>
- 0x6E2F,0x8D60, // <cjk>
- 0x6E38,0x9FE0, // <cjk>
- 0x6E3A,0x9FDB, // <cjk>
- 0x6E3E,0x9FD3, // <cjk>
- 0x6E43,0x9FDA, // <cjk>
- 0x6E4A,0x96A9, // <cjk>
- 0x6E4D,0x9FD8, // <cjk>
- 0x6E4E,0x9FDC, // <cjk>
- 0x6E56,0x8CCE, // <cjk>
- 0x6E58,0x8FC3, // <cjk>
- 0x6E5B,0x9258, // <cjk>
- 0x6E5F,0x9FD2, // <cjk>
- 0x6E67,0x974E, // <cjk>
- 0x6E6B,0x9FD5, // <cjk>
- 0x6E6E,0x9FCE, // <cjk>
- 0x6E6F,0x9392, // <cjk>
- 0x6E72,0x9FD1, // <cjk>
- 0x6E76,0x9FD7, // <cjk>
- 0x6E7E,0x9870, // <cjk>
- 0x6E7F,0x8EBC, // <cjk>
- 0x6E80,0x969E, // <cjk>
- 0x6E82,0x9FE1, // <cjk>
- 0x6E8C,0x94AC, // <cjk>
- 0x6E8F,0x9FED, // <cjk>
- 0x6E90,0x8CB9, // <cjk>
- 0x6E96,0x8F80, // <cjk>
- 0x6E98,0x9FE3, // <cjk>
- 0x6E9C,0x97AD, // <cjk>
- 0x6E9D,0x8D61, // <cjk>
- 0x6E9F,0x9FF0, // <cjk>
- 0x6EA2,0x88EC, // <cjk>
- 0x6EA5,0x9FEE, // <cjk>
- 0x6EAA,0x9FE2, // <cjk>
- 0x6EAF,0x9FE8, // <cjk>
- 0x6EB2,0x9FEA, // <cjk>
- 0x6EB6,0x976E, // <cjk>
- 0x6EB7,0x9FE5, // <cjk>
- 0x6EBA,0x934D, // <cjk>
- 0x6EBD,0x9FE7, // <cjk>
- 0x6EC2,0x9FEF, // <cjk>
- 0x6EC4,0x9FE9, // <cjk>
- 0x6EC5,0x96C5, // <cjk>
- 0x6EC9,0x9FE4, // <cjk>
- 0x6ECB,0x8EA0, // <cjk>
- 0x6ECC,0x9FFC, // <cjk>
- 0x6ED1,0x8A8A, // <cjk>
- 0x6ED3,0x9FE6, // <cjk>
- 0x6ED4,0x9FEB, // <cjk>
- 0x6ED5,0x9FEC, // <cjk>
- 0x6EDD,0x91EA, // <cjk>
- 0x6EDE,0x91D8, // <cjk>
- 0x6EEC,0x9FF4, // <cjk>
- 0x6EEF,0x9FFA, // <cjk>
- 0x6EF2,0x9FF8, // <cjk>
- 0x6EF4,0x9348, // <cjk>
- 0x6EF7,0xE042, // <cjk>
- 0x6EF8,0x9FF5, // <cjk>
- 0x6EFE,0x9FF6, // <cjk>
- 0x6EFF,0x9FDE, // <cjk>
- 0x6F01,0x8B99, // <cjk>
- 0x6F02,0x9559, // <cjk>
- 0x6F06,0x8EBD, // <cjk>
- 0x6F09,0x8D97, // <cjk>
- 0x6F0F,0x9852, // <cjk>
- 0x6F11,0x9FF2, // <cjk>
- 0x6F13,0xE041, // <cjk>
- 0x6F14,0x8989, // <cjk>
- 0x6F15,0x9186, // <cjk>
- 0x6F20,0x9499, // <cjk>
- 0x6F22,0x8ABF, // <cjk>
- 0x6F23,0x97F8, // <cjk>
- 0x6F2B,0x969F, // <cjk>
- 0x6F2C,0x92D0, // <cjk>
- 0x6F31,0x9FF9, // <cjk>
- 0x6F32,0x9FFB, // <cjk>
- 0x6F38,0x9151, // <cjk>
- 0x6F3E,0xE040, // <cjk>
- 0x6F3F,0x9FF7, // <cjk>
- 0x6F41,0x9FF1, // <cjk>
- 0x6F45,0x8AC1, // <cjk>
- 0x6F54,0x8C89, // <cjk>
- 0x6F58,0xE04E, // <cjk>
- 0x6F5B,0xE049, // <cjk>
- 0x6F5C,0x90F6, // <cjk>
- 0x6F5F,0x8A83, // <cjk>
- 0x6F64,0x8F81, // <cjk>
- 0x6F66,0xE052, // <cjk>
- 0x6F6D,0xE04B, // <cjk>
- 0x6F6E,0x92AA, // <cjk>
- 0x6F6F,0xE048, // <cjk>
- 0x6F70,0x92D7, // <cjk>
- 0x6F74,0xE06B, // <cjk>
- 0x6F78,0xE045, // <cjk>
- 0x6F7A,0xE044, // <cjk>
- 0x6F7C,0xE04D, // <cjk>
- 0x6F80,0xE047, // <cjk>
- 0x6F81,0xE046, // <cjk>
- 0x6F82,0xE04C, // <cjk>
- 0x6F84,0x909F, // <cjk>
- 0x6F86,0xE043, // <cjk>
- 0x6F8E,0xE04F, // <cjk>
- 0x6F91,0xE050, // <cjk>
- 0x6F97,0x8AC0, // <cjk>
- 0x6FA1,0xE055, // <cjk>
- 0x6FA3,0xE054, // <cjk>
- 0x6FA4,0xE056, // <cjk>
- 0x6FAA,0xE059, // <cjk>
- 0x6FB1,0x9362, // <cjk>
- 0x6FB3,0xE053, // <cjk>
- 0x6FB9,0xE057, // <cjk>
- 0x6FC0,0x8C83, // <cjk>
- 0x6FC1,0x91F7, // <cjk>
- 0x6FC2,0xE051, // <cjk>
- 0x6FC3,0x945A, // <cjk>
- 0x6FC6,0xE058, // <cjk>
- 0x6FD4,0xE05D, // <cjk>
- 0x6FD8,0xE05E, // <cjk>
- 0x6FDB,0xE061, // <cjk>
- 0x6FDF,0xE05A, // <cjk>
- 0x6FE0,0x8D8A, // <cjk>
- 0x6FE1,0x9447, // <cjk>
- 0x6FE4,0x9FB7, // <cjk>
- 0x6FEB,0x9794, // <cjk>
- 0x6FEC,0xE05C, // <cjk>
- 0x6FEE,0xE060, // <cjk>
- 0x6FEF,0x91F3, // <cjk>
- 0x6FF1,0xE05F, // <cjk>
- 0x6FF3,0xE04A, // <cjk>
- 0x6FF6,0xE889, // <cjk>
- 0x6FFA,0xE064, // <cjk>
- 0x6FFE,0xE068, // <cjk>
- 0x7001,0xE066, // <cjk>
- 0x7009,0xE062, // <cjk>
- 0x700B,0xE063, // <cjk>
- 0x700F,0xE067, // <cjk>
- 0x7011,0xE065, // <cjk>
- 0x7015,0x956D, // <cjk>
- 0x7018,0xE06D, // <cjk>
- 0x701A,0xE06A, // <cjk>
- 0x701B,0xE069, // <cjk>
- 0x701D,0xE06C, // <cjk>
- 0x701E,0x93D2, // <cjk>
- 0x701F,0xE06E, // <cjk>
- 0x7026,0x9295, // <cjk>
- 0x7027,0x91EB, // <cjk>
- 0x702C,0x90A3, // <cjk>
- 0x7030,0xE06F, // <cjk>
- 0x7032,0xE071, // <cjk>
- 0x703E,0xE070, // <cjk>
- 0x704C,0x9FF3, // <cjk>
- 0x7051,0xE072, // <cjk>
- 0x7058,0x93E5, // <cjk>
- 0x7063,0xE073, // <cjk>
- 0x706B,0x89CE, // <cjk>
- 0x706F,0x9394, // <cjk>
- 0x7070,0x8A44, // <cjk>
- 0x7078,0x8B84, // <cjk>
- 0x707C,0x8EDC, // <cjk>
- 0x707D,0x8DD0, // <cjk>
- 0x7089,0x9846, // <cjk>
- 0x708A,0x9086, // <cjk>
- 0x708E,0x898A, // <cjk>
- 0x7092,0xE075, // <cjk>
- 0x7099,0xE074, // <cjk>
- 0x70AC,0xE078, // <cjk>
- 0x70AD,0x9259, // <cjk>
- 0x70AE,0xE07B, // <cjk>
- 0x70AF,0xE076, // <cjk>
- 0x70B3,0xE07A, // <cjk>
- 0x70B8,0xE079, // <cjk>
- 0x70B9,0x935F, // <cjk>
- 0x70BA,0x88D7, // <cjk>
- 0x70C8,0x97F3, // <cjk>
- 0x70CB,0xE07D, // <cjk>
- 0x70CF,0x8947, // <cjk>
- 0x70D9,0xE080, // <cjk>
- 0x70DD,0xE07E, // <cjk>
- 0x70DF,0xE07C, // <cjk>
- 0x70F1,0xE077, // <cjk>
- 0x70F9,0x9642, // <cjk>
- 0x70FD,0xE082, // <cjk>
- 0x7109,0xE081, // <cjk>
- 0x7114,0x898B, // <cjk>
- 0x7119,0xE084, // <cjk>
- 0x711A,0x95B0, // <cjk>
- 0x711C,0xE083, // <cjk>
- 0x7121,0x96B3, // <cjk>
- 0x7126,0x8FC5, // <cjk>
- 0x7136,0x9152, // <cjk>
- 0x713C,0x8FC4, // <cjk>
- 0x7149,0x97F9, // <cjk>
- 0x714C,0xE08A, // <cjk>
- 0x714E,0x90F7, // <cjk>
- 0x7155,0xE086, // <cjk>
- 0x7156,0xE08B, // <cjk>
- 0x7159,0x898C, // <cjk>
- 0x7162,0xE089, // <cjk>
- 0x7164,0x9481, // <cjk>
- 0x7165,0xE085, // <cjk>
- 0x7166,0xE088, // <cjk>
- 0x7167,0x8FC6, // <cjk>
- 0x7169,0x94CF, // <cjk>
- 0x716C,0xE08C, // <cjk>
- 0x716E,0x8ECF, // <cjk>
- 0x717D,0x90F8, // <cjk>
- 0x7184,0xE08F, // <cjk>
- 0x7188,0xE087, // <cjk>
- 0x718A,0x8C46, // <cjk>
- 0x718F,0xE08D, // <cjk>
- 0x7194,0x976F, // <cjk>
- 0x7195,0xE090, // <cjk>
- 0x7199,0xEAA4, // <cjk>
- 0x719F,0x8F6E, // <cjk>
- 0x71A8,0xE091, // <cjk>
- 0x71AC,0xE092, // <cjk>
- 0x71B1,0x944D, // <cjk>
- 0x71B9,0xE094, // <cjk>
- 0x71BE,0xE095, // <cjk>
- 0x71C3,0x9452, // <cjk>
- 0x71C8,0x9395, // <cjk>
- 0x71C9,0xE097, // <cjk>
- 0x71CE,0xE099, // <cjk>
- 0x71D0,0x97D3, // <cjk>
- 0x71D2,0xE096, // <cjk>
- 0x71D4,0xE098, // <cjk>
- 0x71D5,0x898D, // <cjk>
- 0x71D7,0xE093, // <cjk>
- 0x71DF,0x9A7A, // <cjk>
- 0x71E0,0xE09A, // <cjk>
- 0x71E5,0x9187, // <cjk>
- 0x71E6,0x8E57, // <cjk>
- 0x71E7,0xE09C, // <cjk>
- 0x71EC,0xE09B, // <cjk>
- 0x71ED,0x9043, // <cjk>
- 0x71EE,0x99D7, // <cjk>
- 0x71F5,0xE09D, // <cjk>
- 0x71F9,0xE09F, // <cjk>
- 0x71FB,0xE08E, // <cjk>
- 0x71FC,0xE09E, // <cjk>
- 0x71FF,0xE0A0, // <cjk>
- 0x7206,0x949A, // <cjk>
- 0x720D,0xE0A1, // <cjk>
- 0x7210,0xE0A2, // <cjk>
- 0x721B,0xE0A3, // <cjk>
- 0x7228,0xE0A4, // <cjk>
- 0x722A,0x92DC, // <cjk>
- 0x722C,0xE0A6, // <cjk>
- 0x722D,0xE0A5, // <cjk>
- 0x7230,0xE0A7, // <cjk>
- 0x7232,0xE0A8, // <cjk>
- 0x7235,0x8EDD, // <cjk>
- 0x7236,0x9583, // <cjk>
- 0x723A,0x96EA, // <cjk>
- 0x723B,0xE0A9, // <cjk>
- 0x723C,0xE0AA, // <cjk>
- 0x723D,0x9175, // <cjk>
- 0x723E,0x8EA2, // <cjk>
- 0x723F,0xE0AB, // <cjk>
- 0x7240,0xE0AC, // <cjk>
- 0x7246,0xE0AD, // <cjk>
- 0x7247,0x95D0, // <cjk>
- 0x7248,0x94C5, // <cjk>
- 0x724B,0xE0AE, // <cjk>
- 0x724C,0x9476, // <cjk>
- 0x7252,0x92AB, // <cjk>
- 0x7258,0xE0AF, // <cjk>
- 0x7259,0x89E5, // <cjk>
- 0x725B,0x8B8D, // <cjk>
- 0x725D,0x96C4, // <cjk>
- 0x725F,0x96B4, // <cjk>
- 0x7261,0x89B2, // <cjk>
- 0x7262,0x9853, // <cjk>
- 0x7267,0x9671, // <cjk>
- 0x7269,0x95A8, // <cjk>
- 0x7272,0x90B5, // <cjk>
- 0x7274,0xE0B0, // <cjk>
- 0x7279,0x93C1, // <cjk>
- 0x727D,0x8CA1, // <cjk>
- 0x727E,0xE0B1, // <cjk>
- 0x7280,0x8DD2, // <cjk>
- 0x7281,0xE0B3, // <cjk>
- 0x7282,0xE0B2, // <cjk>
- 0x7287,0xE0B4, // <cjk>
- 0x7292,0xE0B5, // <cjk>
- 0x7296,0xE0B6, // <cjk>
- 0x72A0,0x8B5D, // <cjk>
- 0x72A2,0xE0B7, // <cjk>
- 0x72A7,0xE0B8, // <cjk>
- 0x72AC,0x8CA2, // <cjk>
- 0x72AF,0x94C6, // <cjk>
- 0x72B2,0xE0BA, // <cjk>
- 0x72B6,0x8FF3, // <cjk>
- 0x72B9,0xE0B9, // <cjk>
- 0x72C2,0x8BB6, // <cjk>
- 0x72C3,0xE0BB, // <cjk>
- 0x72C4,0xE0BD, // <cjk>
- 0x72C6,0xE0BC, // <cjk>
- 0x72CE,0xE0BE, // <cjk>
- 0x72D0,0x8CCF, // <cjk>
- 0x72D2,0xE0BF, // <cjk>
- 0x72D7,0x8BE7, // <cjk>
- 0x72D9,0x915F, // <cjk>
- 0x72DB,0x8D9D, // <cjk>
- 0x72E0,0xE0C1, // <cjk>
- 0x72E1,0xE0C2, // <cjk>
- 0x72E2,0xE0C0, // <cjk>
- 0x72E9,0x8EEB, // <cjk>
- 0x72EC,0x93C6, // <cjk>
- 0x72ED,0x8BB7, // <cjk>
- 0x72F7,0xE0C4, // <cjk>
- 0x72F8,0x924B, // <cjk>
- 0x72F9,0xE0C3, // <cjk>
- 0x72FC,0x9854, // <cjk>
- 0x72FD,0x9482, // <cjk>
- 0x730A,0xE0C7, // <cjk>
- 0x7316,0xE0C9, // <cjk>
- 0x7317,0xE0C6, // <cjk>
- 0x731B,0x96D2, // <cjk>
- 0x731C,0xE0C8, // <cjk>
- 0x731D,0xE0CA, // <cjk>
- 0x731F,0x97C2, // <cjk>
- 0x7325,0xE0CE, // <cjk>
- 0x7329,0xE0CD, // <cjk>
- 0x732A,0x9296, // <cjk>
- 0x732B,0x944C, // <cjk>
- 0x732E,0x8CA3, // <cjk>
- 0x732F,0xE0CC, // <cjk>
- 0x7334,0xE0CB, // <cjk>
- 0x7336,0x9750, // <cjk>
- 0x7337,0x9751, // <cjk>
- 0x733E,0xE0CF, // <cjk>
- 0x733F,0x898E, // <cjk>
- 0x7344,0x8D96, // <cjk>
- 0x7345,0x8E82, // <cjk>
- 0x734E,0xE0D0, // <cjk>
- 0x734F,0xE0D1, // <cjk>
- 0x7357,0xE0D3, // <cjk>
- 0x7363,0x8F62, // <cjk>
- 0x7368,0xE0D5, // <cjk>
- 0x736A,0xE0D4, // <cjk>
- 0x7370,0xE0D6, // <cjk>
- 0x7372,0x8A6C, // <cjk>
- 0x7375,0xE0D8, // <cjk>
- 0x7378,0xE0D7, // <cjk>
- 0x737A,0xE0DA, // <cjk>
- 0x737B,0xE0D9, // <cjk>
- 0x7384,0x8CBA, // <cjk>
- 0x7387,0x97A6, // <cjk>
- 0x7389,0x8BCA, // <cjk>
- 0x738B,0x89A4, // <cjk>
- 0x7396,0x8BE8, // <cjk>
- 0x73A9,0x8ADF, // <cjk>
- 0x73B2,0x97E6, // <cjk>
- 0x73B3,0xE0DC, // <cjk>
- 0x73BB,0xE0DE, // <cjk>
- 0x73C0,0xE0DF, // <cjk>
- 0x73C2,0x89CF, // <cjk>
- 0x73C8,0xE0DB, // <cjk>
- 0x73CA,0x8E58, // <cjk>
- 0x73CD,0x92BF, // <cjk>
- 0x73CE,0xE0DD, // <cjk>
- 0x73DE,0xE0E2, // <cjk>
- 0x73E0,0x8EEC, // <cjk>
- 0x73E5,0xE0E0, // <cjk>
- 0x73EA,0x8C5D, // <cjk>
- 0x73ED,0x94C7, // <cjk>
- 0x73EE,0xE0E1, // <cjk>
- 0x73F1,0xE0FC, // <cjk>
- 0x73F8,0xE0E7, // <cjk>
- 0x73FE,0x8CBB, // <cjk>
- 0x7403,0x8B85, // <cjk>
- 0x7405,0xE0E4, // <cjk>
- 0x7406,0x979D, // <cjk>
- 0x7409,0x97AE, // <cjk>
- 0x7422,0x91F4, // <cjk>
- 0x7425,0xE0E6, // <cjk>
- 0x7432,0xE0E8, // <cjk>
- 0x7433,0x97D4, // <cjk>
- 0x7434,0x8BD5, // <cjk>
- 0x7435,0x94FA, // <cjk>
- 0x7436,0x9469, // <cjk>
- 0x743A,0xE0E9, // <cjk>
- 0x743F,0xE0EB, // <cjk>
- 0x7441,0xE0EE, // <cjk>
- 0x7455,0xE0EA, // <cjk>
- 0x7459,0xE0ED, // <cjk>
- 0x745A,0x8CE8, // <cjk>
- 0x745B,0x896C, // <cjk>
- 0x745C,0xE0EF, // <cjk>
- 0x745E,0x9090, // <cjk>
- 0x745F,0xE0EC, // <cjk>
- 0x7460,0x97DA, // <cjk>
- 0x7463,0xE0F2, // <cjk>
- 0x7464,0xEAA2, // <cjk>
- 0x7469,0xE0F0, // <cjk>
- 0x746A,0xE0F3, // <cjk>
- 0x746F,0xE0E5, // <cjk>
- 0x7470,0xE0F1, // <cjk>
- 0x7473,0x8DBA, // <cjk>
- 0x7476,0xE0F4, // <cjk>
- 0x747E,0xE0F5, // <cjk>
- 0x7483,0x979E, // <cjk>
- 0x748B,0xE0F6, // <cjk>
- 0x749E,0xE0F7, // <cjk>
- 0x74A2,0xE0E3, // <cjk>
- 0x74A7,0xE0F8, // <cjk>
- 0x74B0,0x8AC2, // <cjk>
- 0x74BD,0x8EA3, // <cjk>
- 0x74CA,0xE0F9, // <cjk>
- 0x74CF,0xE0FA, // <cjk>
- 0x74D4,0xE0FB, // <cjk>
- 0x74DC,0x895A, // <cjk>
- 0x74E0,0xE140, // <cjk>
- 0x74E2,0x955A, // <cjk>
- 0x74E3,0xE141, // <cjk>
- 0x74E6,0x8AA2, // <cjk>
- 0x74E7,0xE142, // <cjk>
- 0x74E9,0xE143, // <cjk>
- 0x74EE,0xE144, // <cjk>
- 0x74F0,0xE146, // <cjk>
- 0x74F1,0xE147, // <cjk>
- 0x74F2,0xE145, // <cjk>
- 0x74F6,0x9572, // <cjk>
- 0x74F7,0xE149, // <cjk>
- 0x74F8,0xE148, // <cjk>
- 0x7503,0xE14B, // <cjk>
- 0x7504,0xE14A, // <cjk>
- 0x7505,0xE14C, // <cjk>
- 0x750C,0xE14D, // <cjk>
- 0x750D,0xE14F, // <cjk>
- 0x750E,0xE14E, // <cjk>
- 0x7511,0x8D99, // <cjk>
- 0x7513,0xE151, // <cjk>
- 0x7515,0xE150, // <cjk>
- 0x7518,0x8AC3, // <cjk>
- 0x751A,0x9072, // <cjk>
- 0x751E,0xE152, // <cjk>
- 0x751F,0x90B6, // <cjk>
- 0x7523,0x8E59, // <cjk>
- 0x7525,0x8999, // <cjk>
- 0x7526,0xE153, // <cjk>
- 0x7528,0x9770, // <cjk>
- 0x752B,0x95E1, // <cjk>
- 0x752C,0xE154, // <cjk>
- 0x7530,0x9363, // <cjk>
- 0x7531,0x9752, // <cjk>
- 0x7532,0x8D62, // <cjk>
- 0x7533,0x905C, // <cjk>
- 0x7537,0x926A, // <cjk>
- 0x7538,0x99B2, // <cjk>
- 0x753A,0x92AC, // <cjk>
- 0x753B,0x89E6, // <cjk>
- 0x753C,0xE155, // <cjk>
- 0x7544,0xE156, // <cjk>
- 0x7549,0xE159, // <cjk>
- 0x754A,0xE158, // <cjk>
- 0x754B,0x9DC0, // <cjk>
- 0x754C,0x8A45, // <cjk>
- 0x754D,0xE157, // <cjk>
- 0x754F,0x88D8, // <cjk>
- 0x7551,0x94A8, // <cjk>
- 0x7554,0x94C8, // <cjk>
- 0x7559,0x97AF, // <cjk>
- 0x755A,0xE15C, // <cjk>
- 0x755B,0xE15A, // <cjk>
- 0x755C,0x927B, // <cjk>
- 0x755D,0x90A4, // <cjk>
- 0x7560,0x94A9, // <cjk>
- 0x7562,0x954C, // <cjk>
- 0x7564,0xE15E, // <cjk>
- 0x7565,0x97AA, // <cjk>
- 0x7566,0x8C6C, // <cjk>
- 0x7567,0xE15F, // <cjk>
- 0x7569,0xE15D, // <cjk>
- 0x756A,0x94D4, // <cjk>
- 0x756B,0xE160, // <cjk>
- 0x756D,0xE161, // <cjk>
- 0x7570,0x88D9, // <cjk>
- 0x7573,0x8FF4, // <cjk>
- 0x7574,0xE166, // <cjk>
- 0x7576,0xE163, // <cjk>
- 0x7577,0x93EB, // <cjk>
- 0x7578,0xE162, // <cjk>
- 0x757F,0x8B45, // <cjk>
- 0x7582,0xE169, // <cjk>
- 0x7586,0xE164, // <cjk>
- 0x7587,0xE165, // <cjk>
- 0x7589,0xE168, // <cjk>
- 0x758A,0xE167, // <cjk>
- 0x758B,0x9544, // <cjk>
- 0x758E,0x9161, // <cjk>
- 0x758F,0x9160, // <cjk>
- 0x7591,0x8B5E, // <cjk>
- 0x7594,0xE16A, // <cjk>
- 0x759A,0xE16B, // <cjk>
- 0x759D,0xE16C, // <cjk>
- 0x75A3,0xE16E, // <cjk>
- 0x75A5,0xE16D, // <cjk>
- 0x75AB,0x8975, // <cjk>
- 0x75B1,0xE176, // <cjk>
- 0x75B2,0x94E6, // <cjk>
- 0x75B3,0xE170, // <cjk>
- 0x75B5,0xE172, // <cjk>
- 0x75B8,0xE174, // <cjk>
- 0x75B9,0x905D, // <cjk>
- 0x75BC,0xE175, // <cjk>
- 0x75BD,0xE173, // <cjk>
- 0x75BE,0x8EBE, // <cjk>
- 0x75C2,0xE16F, // <cjk>
- 0x75C3,0xE171, // <cjk>
- 0x75C5,0x9561, // <cjk>
- 0x75C7,0x8FC7, // <cjk>
- 0x75CA,0xE178, // <cjk>
- 0x75CD,0xE177, // <cjk>
- 0x75D2,0xE179, // <cjk>
- 0x75D4,0x8EA4, // <cjk>
- 0x75D5,0x8DAD, // <cjk>
- 0x75D8,0x9397, // <cjk>
- 0x75D9,0xE17A, // <cjk>
- 0x75DB,0x92C9, // <cjk>
- 0x75DE,0xE17C, // <cjk>
- 0x75E2,0x979F, // <cjk>
- 0x75E3,0xE17B, // <cjk>
- 0x75E9,0x9189, // <cjk>
- 0x75F0,0xE182, // <cjk>
- 0x75F2,0xE184, // <cjk>
- 0x75F3,0xE185, // <cjk>
- 0x75F4,0x9273, // <cjk>
- 0x75FA,0xE183, // <cjk>
- 0x75FC,0xE180, // <cjk>
- 0x75FE,0xE17D, // <cjk>
- 0x75FF,0xE17E, // <cjk>
- 0x7601,0xE181, // <cjk>
- 0x7609,0xE188, // <cjk>
- 0x760B,0xE186, // <cjk>
- 0x760D,0xE187, // <cjk>
- 0x761F,0xE189, // <cjk>
- 0x7620,0xE18B, // <cjk>
- 0x7621,0xE18C, // <cjk>
- 0x7622,0xE18D, // <cjk>
- 0x7624,0xE18E, // <cjk>
- 0x7627,0xE18A, // <cjk>
- 0x7630,0xE190, // <cjk>
- 0x7634,0xE18F, // <cjk>
- 0x763B,0xE191, // <cjk>
- 0x7642,0x97C3, // <cjk>
- 0x7646,0xE194, // <cjk>
- 0x7647,0xE192, // <cjk>
- 0x7648,0xE193, // <cjk>
- 0x764C,0x8AE0, // <cjk>
- 0x7652,0x96FC, // <cjk>
- 0x7656,0x95C8, // <cjk>
- 0x7658,0xE196, // <cjk>
- 0x765C,0xE195, // <cjk>
- 0x7661,0xE197, // <cjk>
- 0x7662,0xE198, // <cjk>
- 0x7667,0xE19C, // <cjk>
- 0x7668,0xE199, // <cjk>
- 0x7669,0xE19A, // <cjk>
- 0x766A,0xE19B, // <cjk>
- 0x766C,0xE19D, // <cjk>
- 0x7670,0xE19E, // <cjk>
- 0x7672,0xE19F, // <cjk>
- 0x7676,0xE1A0, // <cjk>
- 0x7678,0xE1A1, // <cjk>
- 0x767A,0x94AD, // <cjk>
- 0x767B,0x936F, // <cjk>
- 0x767C,0xE1A2, // <cjk>
- 0x767D,0x9492, // <cjk>
- 0x767E,0x9553, // <cjk>
- 0x7680,0xE1A3, // <cjk>
- 0x7683,0xE1A4, // <cjk>
- 0x7684,0x9349, // <cjk>
- 0x7686,0x8A46, // <cjk>
- 0x7687,0x8D63, // <cjk>
- 0x7688,0xE1A5, // <cjk>
- 0x768B,0xE1A6, // <cjk>
- 0x768E,0xE1A7, // <cjk>
- 0x7690,0x8E48, // <cjk>
- 0x7693,0xE1A9, // <cjk>
- 0x7696,0xE1A8, // <cjk>
- 0x7699,0xE1AA, // <cjk>
- 0x769A,0xE1AB, // <cjk>
- 0x76AE,0x94E7, // <cjk>
- 0x76B0,0xE1AC, // <cjk>
- 0x76B4,0xE1AD, // <cjk>
- 0x76B7,0xEA89, // <cjk>
- 0x76B8,0xE1AE, // <cjk>
- 0x76B9,0xE1AF, // <cjk>
- 0x76BA,0xE1B0, // <cjk>
- 0x76BF,0x8E4D, // <cjk>
- 0x76C2,0xE1B1, // <cjk>
- 0x76C3,0x9475, // <cjk>
- 0x76C6,0x967E, // <cjk>
- 0x76C8,0x896D, // <cjk>
- 0x76CA,0x8976, // <cjk>
- 0x76CD,0xE1B2, // <cjk>
- 0x76D2,0xE1B4, // <cjk>
- 0x76D6,0xE1B3, // <cjk>
- 0x76D7,0x9390, // <cjk>
- 0x76DB,0x90B7, // <cjk>
- 0x76DC,0x9F58, // <cjk>
- 0x76DE,0xE1B5, // <cjk>
- 0x76DF,0x96BF, // <cjk>
- 0x76E1,0xE1B6, // <cjk>
- 0x76E3,0x8AC4, // <cjk>
- 0x76E4,0x94D5, // <cjk>
- 0x76E5,0xE1B7, // <cjk>
- 0x76E7,0xE1B8, // <cjk>
- 0x76EA,0xE1B9, // <cjk>
- 0x76EE,0x96DA, // <cjk>
- 0x76F2,0x96D3, // <cjk>
- 0x76F4,0x92BC, // <cjk>
- 0x76F8,0x918A, // <cjk>
- 0x76FB,0xE1BB, // <cjk>
- 0x76FE,0x8F82, // <cjk>
- 0x7701,0x8FC8, // <cjk>
- 0x7704,0xE1BE, // <cjk>
- 0x7707,0xE1BD, // <cjk>
- 0x7708,0xE1BC, // <cjk>
- 0x7709,0x94FB, // <cjk>
- 0x770B,0x8AC5, // <cjk>
- 0x770C,0x8CA7, // <cjk>
- 0x771B,0xE1C4, // <cjk>
- 0x771E,0xE1C1, // <cjk>
- 0x771F,0x905E, // <cjk>
- 0x7720,0x96B0, // <cjk>
- 0x7724,0xE1C0, // <cjk>
- 0x7725,0xE1C2, // <cjk>
- 0x7726,0xE1C3, // <cjk>
- 0x7729,0xE1BF, // <cjk>
- 0x7737,0xE1C5, // <cjk>
- 0x7738,0xE1C6, // <cjk>
- 0x773A,0x92AD, // <cjk>
- 0x773C,0x8AE1, // <cjk>
- 0x7740,0x9285, // <cjk>
- 0x7747,0xE1C7, // <cjk>
- 0x775A,0xE1C8, // <cjk>
- 0x775B,0xE1CB, // <cjk>
- 0x7761,0x9087, // <cjk>
- 0x7763,0x93C2, // <cjk>
- 0x7765,0xE1CC, // <cjk>
- 0x7766,0x9672, // <cjk>
- 0x7768,0xE1C9, // <cjk>
- 0x776B,0xE1CA, // <cjk>
- 0x7779,0xE1CF, // <cjk>
- 0x777E,0xE1CE, // <cjk>
- 0x777F,0xE1CD, // <cjk>
- 0x778B,0xE1D1, // <cjk>
- 0x778E,0xE1D0, // <cjk>
- 0x7791,0xE1D2, // <cjk>
- 0x779E,0xE1D4, // <cjk>
- 0x77A0,0xE1D3, // <cjk>
- 0x77A5,0x95CB, // <cjk>
- 0x77AC,0x8F75, // <cjk>
- 0x77AD,0x97C4, // <cjk>
- 0x77B0,0xE1D5, // <cjk>
- 0x77B3,0x93B5, // <cjk>
- 0x77B6,0xE1D6, // <cjk>
- 0x77B9,0xE1D7, // <cjk>
- 0x77BB,0xE1DB, // <cjk>
- 0x77BC,0xE1D9, // <cjk>
- 0x77BD,0xE1DA, // <cjk>
- 0x77BF,0xE1D8, // <cjk>
- 0x77C7,0xE1DC, // <cjk>
- 0x77CD,0xE1DD, // <cjk>
- 0x77D7,0xE1DE, // <cjk>
- 0x77DA,0xE1DF, // <cjk>
- 0x77DB,0x96B5, // <cjk>
- 0x77DC,0xE1E0, // <cjk>
- 0x77E2,0x96EE, // <cjk>
- 0x77E3,0xE1E1, // <cjk>
- 0x77E5,0x926D, // <cjk>
- 0x77E7,0x948A, // <cjk>
- 0x77E9,0x8BE9, // <cjk>
- 0x77ED,0x925A, // <cjk>
- 0x77EE,0xE1E2, // <cjk>
- 0x77EF,0x8BB8, // <cjk>
- 0x77F3,0x90CE, // <cjk>
- 0x77FC,0xE1E3, // <cjk>
- 0x7802,0x8DBB, // <cjk>
- 0x780C,0xE1E4, // <cjk>
- 0x7812,0xE1E5, // <cjk>
- 0x7814,0x8CA4, // <cjk>
- 0x7815,0x8DD3, // <cjk>
- 0x7820,0xE1E7, // <cjk>
- 0x7825,0x9375, // <cjk>
- 0x7826,0x8DD4, // <cjk>
- 0x7827,0x8B6D, // <cjk>
- 0x7832,0x9643, // <cjk>
- 0x7834,0x946A, // <cjk>
- 0x783A,0x9376, // <cjk>
- 0x783F,0x8D7B, // <cjk>
- 0x7845,0xE1E9, // <cjk>
- 0x785D,0x8FC9, // <cjk>
- 0x786B,0x97B0, // <cjk>
- 0x786C,0x8D64, // <cjk>
- 0x786F,0x8CA5, // <cjk>
- 0x7872,0x94A1, // <cjk>
- 0x7874,0xE1EB, // <cjk>
- 0x787C,0xE1ED, // <cjk>
- 0x7881,0x8CE9, // <cjk>
- 0x7886,0xE1EC, // <cjk>
- 0x7887,0x92F4, // <cjk>
- 0x788C,0xE1EF, // <cjk>
- 0x788D,0x8A56, // <cjk>
- 0x788E,0xE1EA, // <cjk>
- 0x7891,0x94E8, // <cjk>
- 0x7893,0x894F, // <cjk>
- 0x7895,0x8DEA, // <cjk>
- 0x7897,0x9871, // <cjk>
- 0x789A,0xE1EE, // <cjk>
- 0x78A3,0xE1F0, // <cjk>
- 0x78A7,0x95C9, // <cjk>
- 0x78A9,0x90D7, // <cjk>
- 0x78AA,0xE1F2, // <cjk>
- 0x78AF,0xE1F3, // <cjk>
- 0x78B5,0xE1F1, // <cjk>
- 0x78BA,0x8A6D, // <cjk>
- 0x78BC,0xE1F9, // <cjk>
- 0x78BE,0xE1F8, // <cjk>
- 0x78C1,0x8EA5, // <cjk>
- 0x78C5,0xE1FA, // <cjk>
- 0x78C6,0xE1F5, // <cjk>
- 0x78CA,0xE1FB, // <cjk>
- 0x78CB,0xE1F6, // <cjk>
- 0x78D0,0x94D6, // <cjk>
- 0x78D1,0xE1F4, // <cjk>
- 0x78D4,0xE1F7, // <cjk>
- 0x78DA,0xE241, // <cjk>
- 0x78E7,0xE240, // <cjk>
- 0x78E8,0x9681, // <cjk>
- 0x78EC,0xE1FC, // <cjk>
- 0x78EF,0x88E9, // <cjk>
- 0x78F4,0xE243, // <cjk>
- 0x78FD,0xE242, // <cjk>
- 0x7901,0x8FCA, // <cjk>
- 0x7907,0xE244, // <cjk>
- 0x790E,0x9162, // <cjk>
- 0x7911,0xE246, // <cjk>
- 0x7912,0xE245, // <cjk>
- 0x7919,0xE247, // <cjk>
- 0x7926,0xE1E6, // <cjk>
- 0x792A,0xE1E8, // <cjk>
- 0x792B,0xE249, // <cjk>
- 0x792C,0xE248, // <cjk>
- 0x793A,0x8EA6, // <cjk>
- 0x793C,0x97E7, // <cjk>
- 0x793E,0x8ED0, // <cjk>
- 0x7940,0xE24A, // <cjk>
- 0x7941,0x8C56, // <cjk>
- 0x7947,0x8B5F, // <cjk>
- 0x7948,0x8B46, // <cjk>
- 0x7949,0x8E83, // <cjk>
- 0x7950,0x9753, // <cjk>
- 0x7953,0xE250, // <cjk>
- 0x7955,0xE24F, // <cjk>
- 0x7956,0x9163, // <cjk>
- 0x7957,0xE24C, // <cjk>
- 0x795A,0xE24E, // <cjk>
- 0x795D,0x8F6A, // <cjk>
- 0x795E,0x905F, // <cjk>
- 0x795F,0xE24D, // <cjk>
- 0x7960,0xE24B, // <cjk>
- 0x7962,0x9449, // <cjk>
- 0x7965,0x8FCB, // <cjk>
- 0x796D,0x8DD5, // <cjk>
- 0x7977,0x9398, // <cjk>
- 0x797A,0xE251, // <cjk>
- 0x797F,0xE252, // <cjk>
- 0x7980,0xE268, // <cjk>
- 0x7981,0x8BD6, // <cjk>
- 0x7984,0x985C, // <cjk>
- 0x7985,0x9154, // <cjk>
- 0x798A,0xE253, // <cjk>
- 0x798D,0x89D0, // <cjk>
- 0x798E,0x92F5, // <cjk>
- 0x798F,0x959F, // <cjk>
- 0x799D,0xE254, // <cjk>
- 0x79A6,0x8B9A, // <cjk>
- 0x79A7,0xE255, // <cjk>
- 0x79AA,0xE257, // <cjk>
- 0x79AE,0xE258, // <cjk>
- 0x79B0,0x9448, // <cjk>
- 0x79B3,0xE259, // <cjk>
- 0x79B9,0xE25A, // <cjk>
- 0x79BD,0x8BD7, // <cjk>
- 0x79BE,0x89D1, // <cjk>
- 0x79BF,0x93C3, // <cjk>
- 0x79C0,0x8F47, // <cjk>
- 0x79C1,0x8E84, // <cjk>
- 0x79C9,0xE25C, // <cjk>
- 0x79CB,0x8F48, // <cjk>
- 0x79D1,0x89C8, // <cjk>
- 0x79D2,0x9562, // <cjk>
- 0x79D5,0xE25D, // <cjk>
- 0x79D8,0x94E9, // <cjk>
- 0x79DF,0x9164, // <cjk>
- 0x79E1,0xE260, // <cjk>
- 0x79E3,0xE261, // <cjk>
- 0x79E4,0x9489, // <cjk>
- 0x79E6,0x9060, // <cjk>
- 0x79E7,0xE25E, // <cjk>
- 0x79E9,0x9281, // <cjk>
- 0x79EC,0xE25F, // <cjk>
- 0x79F0,0x8FCC, // <cjk>
- 0x79FB,0x88DA, // <cjk>
- 0x7A00,0x8B48, // <cjk>
- 0x7A08,0xE262, // <cjk>
- 0x7A0B,0x92F6, // <cjk>
- 0x7A0D,0xE263, // <cjk>
- 0x7A0E,0x90C5, // <cjk>
- 0x7A14,0x96AB, // <cjk>
- 0x7A17,0x9542, // <cjk>
- 0x7A18,0xE264, // <cjk>
- 0x7A19,0xE265, // <cjk>
- 0x7A1A,0x9274, // <cjk>
- 0x7A1C,0x97C5, // <cjk>
- 0x7A1F,0xE267, // <cjk>
- 0x7A20,0xE266, // <cjk>
- 0x7A2E,0x8EED, // <cjk>
- 0x7A31,0xE269, // <cjk>
- 0x7A32,0x88EE, // <cjk>
- 0x7A37,0xE26C, // <cjk>
- 0x7A3B,0xE26A, // <cjk>
- 0x7A3C,0x89D2, // <cjk>
- 0x7A3D,0x8C6D, // <cjk>
- 0x7A3E,0xE26B, // <cjk>
- 0x7A3F,0x8D65, // <cjk>
- 0x7A40,0x8D92, // <cjk>
- 0x7A42,0x95E4, // <cjk>
- 0x7A43,0xE26D, // <cjk>
- 0x7A46,0x9673, // <cjk>
- 0x7A49,0xE26F, // <cjk>
- 0x7A4D,0x90CF, // <cjk>
- 0x7A4E,0x896E, // <cjk>
- 0x7A4F,0x89B8, // <cjk>
- 0x7A50,0x88AA, // <cjk>
- 0x7A57,0xE26E, // <cjk>
- 0x7A61,0xE270, // <cjk>
- 0x7A62,0xE271, // <cjk>
- 0x7A63,0x8FF5, // <cjk>
- 0x7A69,0xE272, // <cjk>
- 0x7A6B,0x8A6E, // <cjk>
- 0x7A70,0xE274, // <cjk>
- 0x7A74,0x8C8A, // <cjk>
- 0x7A76,0x8B86, // <cjk>
- 0x7A79,0xE275, // <cjk>
- 0x7A7A,0x8BF3, // <cjk>
- 0x7A7D,0xE276, // <cjk>
- 0x7A7F,0x90FA, // <cjk>
- 0x7A81,0x93CB, // <cjk>
- 0x7A83,0x90DE, // <cjk>
- 0x7A84,0x8DF3, // <cjk>
- 0x7A88,0xE277, // <cjk>
- 0x7A92,0x9282, // <cjk>
- 0x7A93,0x918B, // <cjk>
- 0x7A95,0xE279, // <cjk>
- 0x7A96,0xE27B, // <cjk>
- 0x7A97,0xE278, // <cjk>
- 0x7A98,0xE27A, // <cjk>
- 0x7A9F,0x8C41, // <cjk>
- 0x7AA9,0xE27C, // <cjk>
- 0x7AAA,0x8C45, // <cjk>
- 0x7AAE,0x8B87, // <cjk>
- 0x7AAF,0x9771, // <cjk>
- 0x7AB0,0xE27E, // <cjk>
- 0x7AB6,0xE280, // <cjk>
- 0x7ABA,0x894D, // <cjk>
- 0x7ABF,0xE283, // <cjk>
- 0x7AC3,0x8A96, // <cjk>
- 0x7AC4,0xE282, // <cjk>
- 0x7AC5,0xE281, // <cjk>
- 0x7AC7,0xE285, // <cjk>
- 0x7AC8,0xE27D, // <cjk>
- 0x7ACA,0xE286, // <cjk>
- 0x7ACB,0x97A7, // <cjk>
- 0x7ACD,0xE287, // <cjk>
- 0x7ACF,0xE288, // <cjk>
- 0x7AD2,0x9AF2, // <cjk>
- 0x7AD3,0xE28A, // <cjk>
- 0x7AD5,0xE289, // <cjk>
- 0x7AD9,0xE28B, // <cjk>
- 0x7ADA,0xE28C, // <cjk>
- 0x7ADC,0x97B3, // <cjk>
- 0x7ADD,0xE28D, // <cjk>
- 0x7ADF,0xE8ED, // <cjk>
- 0x7AE0,0x8FCD, // <cjk>
- 0x7AE1,0xE28E, // <cjk>
- 0x7AE2,0xE28F, // <cjk>
- 0x7AE3,0x8F76, // <cjk>
- 0x7AE5,0x93B6, // <cjk>
- 0x7AE6,0xE290, // <cjk>
- 0x7AEA,0x9247, // <cjk>
- 0x7AED,0xE291, // <cjk>
- 0x7AF0,0xE292, // <cjk>
- 0x7AF6,0x8BA3, // <cjk>
- 0x7AF8,0x995E, // <cjk>
- 0x7AF9,0x927C, // <cjk>
- 0x7AFA,0x8EB1, // <cjk>
- 0x7AFF,0x8AC6, // <cjk>
- 0x7B02,0xE293, // <cjk>
- 0x7B04,0xE2A0, // <cjk>
- 0x7B06,0xE296, // <cjk>
- 0x7B08,0x8B88, // <cjk>
- 0x7B0A,0xE295, // <cjk>
- 0x7B0B,0xE2A2, // <cjk>
- 0x7B0F,0xE294, // <cjk>
- 0x7B11,0x8FCE, // <cjk>
- 0x7B18,0xE298, // <cjk>
- 0x7B19,0xE299, // <cjk>
- 0x7B1B,0x934A, // <cjk>
- 0x7B1E,0xE29A, // <cjk>
- 0x7B20,0x8A7D, // <cjk>
- 0x7B25,0x9079, // <cjk>
- 0x7B26,0x9584, // <cjk>
- 0x7B28,0xE29C, // <cjk>
- 0x7B2C,0x91E6, // <cjk>
- 0x7B33,0xE297, // <cjk>
- 0x7B35,0xE29B, // <cjk>
- 0x7B36,0xE29D, // <cjk>
- 0x7B39,0x8DF9, // <cjk>
- 0x7B45,0xE2A4, // <cjk>
- 0x7B46,0x954D, // <cjk>
- 0x7B48,0x94A4, // <cjk>
- 0x7B49,0x9399, // <cjk>
- 0x7B4B,0x8BD8, // <cjk>
- 0x7B4C,0xE2A3, // <cjk>
- 0x7B4D,0xE2A1, // <cjk>
- 0x7B4F,0x94B3, // <cjk>
- 0x7B50,0xE29E, // <cjk>
- 0x7B51,0x927D, // <cjk>
- 0x7B52,0x939B, // <cjk>
- 0x7B54,0x939A, // <cjk>
- 0x7B56,0x8DF4, // <cjk>
- 0x7B5D,0xE2B6, // <cjk>
- 0x7B65,0xE2A6, // <cjk>
- 0x7B67,0xE2A8, // <cjk>
- 0x7B6C,0xE2AB, // <cjk>
- 0x7B6E,0xE2AC, // <cjk>
- 0x7B70,0xE2A9, // <cjk>
- 0x7B71,0xE2AA, // <cjk>
- 0x7B74,0xE2A7, // <cjk>
- 0x7B75,0xE2A5, // <cjk>
- 0x7B7A,0xE29F, // <cjk>
- 0x7B86,0x95CD, // <cjk>
- 0x7B87,0x89D3, // <cjk>
- 0x7B8B,0xE2B3, // <cjk>
- 0x7B8D,0xE2B0, // <cjk>
- 0x7B8F,0xE2B5, // <cjk>
- 0x7B92,0xE2B4, // <cjk>
- 0x7B94,0x9493, // <cjk>
- 0x7B95,0x96A5, // <cjk>
- 0x7B97,0x8E5A, // <cjk>
- 0x7B98,0xE2AE, // <cjk>
- 0x7B99,0xE2B7, // <cjk>
- 0x7B9A,0xE2B2, // <cjk>
- 0x7B9C,0xE2B1, // <cjk>
- 0x7B9D,0xE2AD, // <cjk>
- 0x7B9F,0xE2AF, // <cjk>
- 0x7BA1,0x8AC7, // <cjk>
- 0x7BAA,0x925C, // <cjk>
- 0x7BAD,0x90FB, // <cjk>
- 0x7BB1,0x94A0, // <cjk>
- 0x7BB4,0xE2BC, // <cjk>
- 0x7BB8,0x94A2, // <cjk>
- 0x7BC0,0x90DF, // <cjk>
- 0x7BC1,0xE2B9, // <cjk>
- 0x7BC4,0x94CD, // <cjk>
- 0x7BC6,0xE2BD, // <cjk>
- 0x7BC7,0x95D1, // <cjk>
- 0x7BC9,0x927A, // <cjk>
- 0x7BCB,0xE2B8, // <cjk>
- 0x7BCC,0xE2BA, // <cjk>
- 0x7BCF,0xE2BB, // <cjk>
- 0x7BDD,0xE2BE, // <cjk>
- 0x7BE0,0x8EC2, // <cjk>
- 0x7BE4,0x93C4, // <cjk>
- 0x7BE5,0xE2C3, // <cjk>
- 0x7BE6,0xE2C2, // <cjk>
- 0x7BE9,0xE2BF, // <cjk>
- 0x7BED,0x9855, // <cjk>
- 0x7BF3,0xE2C8, // <cjk>
- 0x7BF6,0xE2CC, // <cjk>
- 0x7BF7,0xE2C9, // <cjk>
- 0x7C00,0xE2C5, // <cjk>
- 0x7C07,0xE2C6, // <cjk>
- 0x7C0D,0xE2CB, // <cjk>
- 0x7C11,0xE2C0, // <cjk>
- 0x7C12,0x99D3, // <cjk>
- 0x7C13,0xE2C7, // <cjk>
- 0x7C14,0xE2C1, // <cjk>
- 0x7C17,0xE2CA, // <cjk>
- 0x7C1F,0xE2D0, // <cjk>
- 0x7C21,0x8AC8, // <cjk>
- 0x7C23,0xE2CD, // <cjk>
- 0x7C27,0xE2CE, // <cjk>
- 0x7C2A,0xE2CF, // <cjk>
- 0x7C2B,0xE2D2, // <cjk>
- 0x7C37,0xE2D1, // <cjk>
- 0x7C38,0x94F4, // <cjk>
- 0x7C3D,0xE2D3, // <cjk>
- 0x7C3E,0x97FA, // <cjk>
- 0x7C3F,0x95EB, // <cjk>
- 0x7C40,0xE2D8, // <cjk>
- 0x7C43,0xE2D5, // <cjk>
- 0x7C4C,0xE2D4, // <cjk>
- 0x7C4D,0x90D0, // <cjk>
- 0x7C4F,0xE2D7, // <cjk>
- 0x7C50,0xE2D9, // <cjk>
- 0x7C54,0xE2D6, // <cjk>
- 0x7C56,0xE2DD, // <cjk>
- 0x7C58,0xE2DA, // <cjk>
- 0x7C5F,0xE2DB, // <cjk>
- 0x7C60,0xE2C4, // <cjk>
- 0x7C64,0xE2DC, // <cjk>
- 0x7C65,0xE2DE, // <cjk>
- 0x7C6C,0xE2DF, // <cjk>
- 0x7C73,0x95C4, // <cjk>
- 0x7C75,0xE2E0, // <cjk>
- 0x7C7E,0x96E0, // <cjk>
- 0x7C81,0x8BCC, // <cjk>
- 0x7C82,0x8C48, // <cjk>
- 0x7C83,0xE2E1, // <cjk>
- 0x7C89,0x95B2, // <cjk>
- 0x7C8B,0x9088, // <cjk>
- 0x7C8D,0x96AE, // <cjk>
- 0x7C90,0xE2E2, // <cjk>
- 0x7C92,0x97B1, // <cjk>
- 0x7C95,0x9494, // <cjk>
- 0x7C97,0x9165, // <cjk>
- 0x7C98,0x9453, // <cjk>
- 0x7C9B,0x8F6C, // <cjk>
- 0x7C9F,0x88BE, // <cjk>
- 0x7CA1,0xE2E7, // <cjk>
- 0x7CA2,0xE2E5, // <cjk>
- 0x7CA4,0xE2E3, // <cjk>
- 0x7CA5,0x8A9F, // <cjk>
- 0x7CA7,0x8FCF, // <cjk>
- 0x7CA8,0xE2E8, // <cjk>
- 0x7CAB,0xE2E6, // <cjk>
- 0x7CAD,0xE2E4, // <cjk>
- 0x7CAE,0xE2EC, // <cjk>
- 0x7CB1,0xE2EB, // <cjk>
- 0x7CB2,0xE2EA, // <cjk>
- 0x7CB3,0xE2E9, // <cjk>
- 0x7CB9,0xE2ED, // <cjk>
- 0x7CBD,0xE2EE, // <cjk>
- 0x7CBE,0x90B8, // <cjk>
- 0x7CC0,0xE2EF, // <cjk>
- 0x7CC2,0xE2F1, // <cjk>
- 0x7CC5,0xE2F0, // <cjk>
- 0x7CCA,0x8CD0, // <cjk>
- 0x7CCE,0x9157, // <cjk>
- 0x7CD2,0xE2F3, // <cjk>
- 0x7CD6,0x939C, // <cjk>
- 0x7CD8,0xE2F2, // <cjk>
- 0x7CDC,0xE2F4, // <cjk>
- 0x7CDE,0x95B3, // <cjk>
- 0x7CDF,0x918C, // <cjk>
- 0x7CE0,0x8D66, // <cjk>
- 0x7CE2,0xE2F5, // <cjk>
- 0x7CE7,0x97C6, // <cjk>
- 0x7CEF,0xE2F7, // <cjk>
- 0x7CF2,0xE2F8, // <cjk>
- 0x7CF4,0xE2F9, // <cjk>
- 0x7CF6,0xE2FA, // <cjk>
- 0x7CF8,0x8E85, // <cjk>
- 0x7CFA,0xE2FB, // <cjk>
- 0x7CFB,0x8C6E, // <cjk>
- 0x7CFE,0x8B8A, // <cjk>
- 0x7D00,0x8B49, // <cjk>
- 0x7D02,0xE340, // <cjk>
- 0x7D04,0x96F1, // <cjk>
- 0x7D05,0x8D67, // <cjk>
- 0x7D06,0xE2FC, // <cjk>
- 0x7D0A,0xE343, // <cjk>
- 0x7D0B,0x96E4, // <cjk>
- 0x7D10,0x9552, // <cjk>
- 0x7D14,0x8F83, // <cjk>
- 0x7D15,0xE342, // <cjk>
- 0x7D17,0x8ED1, // <cjk>
- 0x7D18,0x8D68, // <cjk>
- 0x7D19,0x8E86, // <cjk>
- 0x7D1A,0x8B89, // <cjk>
- 0x7D1B,0x95B4, // <cjk>
- 0x7D1C,0xE341, // <cjk>
- 0x7D20,0x9166, // <cjk>
- 0x7D21,0x9661, // <cjk>
- 0x7D22,0x8DF5, // <cjk>
- 0x7D2B,0x8E87, // <cjk>
- 0x7D2C,0x92DB, // <cjk>
- 0x7D2E,0xE346, // <cjk>
- 0x7D2F,0x97DD, // <cjk>
- 0x7D30,0x8DD7, // <cjk>
- 0x7D32,0xE347, // <cjk>
- 0x7D33,0x9061, // <cjk>
- 0x7D35,0xE349, // <cjk>
- 0x7D39,0x8FD0, // <cjk>
- 0x7D3A,0x8DAE, // <cjk>
- 0x7D3F,0xE348, // <cjk>
- 0x7D42,0x8F49, // <cjk>
- 0x7D43,0x8CBC, // <cjk>
- 0x7D44,0x9167, // <cjk>
- 0x7D45,0xE344, // <cjk>
- 0x7D46,0xE34A, // <cjk>
- 0x7D4B,0xE345, // <cjk>
- 0x7D4C,0x8C6F, // <cjk>
- 0x7D4E,0xE34D, // <cjk>
- 0x7D4F,0xE351, // <cjk>
- 0x7D50,0x8C8B, // <cjk>
- 0x7D56,0xE34C, // <cjk>
- 0x7D5B,0xE355, // <cjk>
- 0x7D5E,0x8D69, // <cjk>
- 0x7D61,0x978D, // <cjk>
- 0x7D62,0x88BA, // <cjk>
- 0x7D63,0xE352, // <cjk>
- 0x7D66,0x8B8B, // <cjk>
- 0x7D68,0xE34F, // <cjk>
- 0x7D6E,0xE350, // <cjk>
- 0x7D71,0x939D, // <cjk>
- 0x7D72,0xE34E, // <cjk>
- 0x7D73,0xE34B, // <cjk>
- 0x7D75,0x8A47, // <cjk>
- 0x7D76,0x90E2, // <cjk>
- 0x7D79,0x8CA6, // <cjk>
- 0x7D7D,0xE357, // <cjk>
- 0x7D89,0xE354, // <cjk>
- 0x7D8F,0xE356, // <cjk>
- 0x7D93,0xE353, // <cjk>
- 0x7D99,0x8C70, // <cjk>
- 0x7D9A,0x91B1, // <cjk>
- 0x7D9B,0xE358, // <cjk>
- 0x7D9C,0x918E, // <cjk>
- 0x7D9F,0xE365, // <cjk>
- 0x7DA2,0xE361, // <cjk>
- 0x7DAB,0xE35F, // <cjk>
- 0x7DAC,0x8EF8, // <cjk>
- 0x7DAD,0x88DB, // <cjk>
- 0x7DAE,0xE35A, // <cjk>
- 0x7DAF,0xE362, // <cjk>
- 0x7DB0,0xE366, // <cjk>
- 0x7DB1,0x8D6A, // <cjk>
- 0x7DB2,0x96D4, // <cjk>
- 0x7DB4,0x92D4, // <cjk>
- 0x7DB5,0xE35C, // <cjk>
- 0x7DB8,0xE364, // <cjk>
- 0x7DBA,0xE359, // <cjk>
- 0x7DBB,0x925D, // <cjk>
- 0x7DBD,0xE35E, // <cjk>
- 0x7DBE,0x88BB, // <cjk>
- 0x7DBF,0x96C8, // <cjk>
- 0x7DC7,0xE35D, // <cjk>
- 0x7DCA,0x8BD9, // <cjk>
- 0x7DCB,0x94EA, // <cjk>
- 0x7DCF,0x918D, // <cjk>
- 0x7DD1,0x97CE, // <cjk>
- 0x7DD2,0x8F8F, // <cjk>
- 0x7DD5,0xE38E, // <cjk>
- 0x7DD8,0xE367, // <cjk>
- 0x7DDA,0x90FC, // <cjk>
- 0x7DDC,0xE363, // <cjk>
- 0x7DDD,0xE368, // <cjk>
- 0x7DDE,0xE36A, // <cjk>
- 0x7DE0,0x92F7, // <cjk>
- 0x7DE1,0xE36D, // <cjk>
- 0x7DE4,0xE369, // <cjk>
- 0x7DE8,0x95D2, // <cjk>
- 0x7DE9,0x8AC9, // <cjk>
- 0x7DEC,0x96C9, // <cjk>
- 0x7DEF,0x88DC, // <cjk>
- 0x7DF2,0xE36C, // <cjk>
- 0x7DF4,0x97FB, // <cjk>
- 0x7DFB,0xE36B, // <cjk>
- 0x7E01,0x898F, // <cjk>
- 0x7E04,0x93EA, // <cjk>
- 0x7E05,0xE36E, // <cjk>
- 0x7E09,0xE375, // <cjk>
- 0x7E0A,0xE36F, // <cjk>
- 0x7E0B,0xE376, // <cjk>
- 0x7E12,0xE372, // <cjk>
- 0x7E1B,0x949B, // <cjk>
- 0x7E1E,0x8EC8, // <cjk>
- 0x7E1F,0xE374, // <cjk>
- 0x7E21,0xE371, // <cjk>
- 0x7E22,0xE377, // <cjk>
- 0x7E23,0xE370, // <cjk>
- 0x7E26,0x8F63, // <cjk>
- 0x7E2B,0x9644, // <cjk>
- 0x7E2E,0x8F6B, // <cjk>
- 0x7E31,0xE373, // <cjk>
- 0x7E32,0xE380, // <cjk>
- 0x7E35,0xE37B, // <cjk>
- 0x7E37,0xE37E, // <cjk>
- 0x7E39,0xE37C, // <cjk>
- 0x7E3A,0xE381, // <cjk>
- 0x7E3B,0xE37A, // <cjk>
- 0x7E3D,0xE360, // <cjk>
- 0x7E3E,0x90D1, // <cjk>
- 0x7E41,0x94C9, // <cjk>
- 0x7E43,0xE37D, // <cjk>
- 0x7E46,0xE378, // <cjk>
- 0x7E4A,0x9140, // <cjk>
- 0x7E4B,0x8C71, // <cjk>
- 0x7E4D,0x8F4A, // <cjk>
- 0x7E54,0x9044, // <cjk>
- 0x7E55,0x9155, // <cjk>
- 0x7E56,0xE384, // <cjk>
- 0x7E59,0xE386, // <cjk>
- 0x7E5A,0xE387, // <cjk>
- 0x7E5D,0xE383, // <cjk>
- 0x7E5E,0xE385, // <cjk>
- 0x7E66,0xE379, // <cjk>
- 0x7E67,0xE382, // <cjk>
- 0x7E69,0xE38A, // <cjk>
- 0x7E6A,0xE389, // <cjk>
- 0x7E6D,0x969A, // <cjk>
- 0x7E70,0x8C4A, // <cjk>
- 0x7E79,0xE388, // <cjk>
- 0x7E7B,0xE38C, // <cjk>
- 0x7E7C,0xE38B, // <cjk>
- 0x7E7D,0xE38F, // <cjk>
- 0x7E7F,0xE391, // <cjk>
- 0x7E83,0xE38D, // <cjk>
- 0x7E88,0xE392, // <cjk>
- 0x7E89,0xE393, // <cjk>
- 0x7E8C,0xE394, // <cjk>
- 0x7E8E,0xE39A, // <cjk>
- 0x7E8F,0x935A, // <cjk>
- 0x7E90,0xE396, // <cjk>
- 0x7E92,0xE395, // <cjk>
- 0x7E93,0xE397, // <cjk>
- 0x7E94,0xE398, // <cjk>
- 0x7E96,0xE399, // <cjk>
- 0x7E9B,0xE39B, // <cjk>
- 0x7E9C,0xE39C, // <cjk>
- 0x7F36,0x8ACA, // <cjk>
- 0x7F38,0xE39D, // <cjk>
- 0x7F3A,0xE39E, // <cjk>
- 0x7F45,0xE39F, // <cjk>
- 0x7F4C,0xE3A0, // <cjk>
- 0x7F4D,0xE3A1, // <cjk>
- 0x7F4E,0xE3A2, // <cjk>
- 0x7F50,0xE3A3, // <cjk>
- 0x7F51,0xE3A4, // <cjk>
- 0x7F54,0xE3A6, // <cjk>
- 0x7F55,0xE3A5, // <cjk>
- 0x7F58,0xE3A7, // <cjk>
- 0x7F5F,0xE3A8, // <cjk>
- 0x7F60,0xE3A9, // <cjk>
- 0x7F67,0xE3AC, // <cjk>
- 0x7F68,0xE3AA, // <cjk>
- 0x7F69,0xE3AB, // <cjk>
- 0x7F6A,0x8DDF, // <cjk>
- 0x7F6B,0x8C72, // <cjk>
- 0x7F6E,0x9275, // <cjk>
- 0x7F70,0x94B1, // <cjk>
- 0x7F72,0x8F90, // <cjk>
- 0x7F75,0x946C, // <cjk>
- 0x7F77,0x94EB, // <cjk>
- 0x7F78,0xE3AD, // <cjk>
- 0x7F79,0x9CEB, // <cjk>
- 0x7F82,0xE3AE, // <cjk>
- 0x7F83,0xE3B0, // <cjk>
- 0x7F85,0x9785, // <cjk>
- 0x7F86,0xE3AF, // <cjk>
- 0x7F87,0xE3B2, // <cjk>
- 0x7F88,0xE3B1, // <cjk>
- 0x7F8A,0x9772, // <cjk>
- 0x7F8C,0xE3B3, // <cjk>
- 0x7F8E,0x94FC, // <cjk>
- 0x7F94,0xE3B4, // <cjk>
- 0x7F9A,0xE3B7, // <cjk>
- 0x7F9D,0xE3B6, // <cjk>
- 0x7F9E,0xE3B5, // <cjk>
- 0x7FA3,0xE3B8, // <cjk>
- 0x7FA4,0x8C51, // <cjk>
- 0x7FA8,0x9141, // <cjk>
- 0x7FA9,0x8B60, // <cjk>
- 0x7FAE,0xE3BC, // <cjk>
- 0x7FAF,0xE3B9, // <cjk>
- 0x7FB2,0xE3BA, // <cjk>
- 0x7FB6,0xE3BD, // <cjk>
- 0x7FB8,0xE3BE, // <cjk>
- 0x7FB9,0xE3BB, // <cjk>
- 0x7FBD,0x8948, // <cjk>
- 0x7FC1,0x89A5, // <cjk>
- 0x7FC5,0xE3C0, // <cjk>
- 0x7FC6,0xE3C1, // <cjk>
- 0x7FCA,0xE3C2, // <cjk>
- 0x7FCC,0x9782, // <cjk>
- 0x7FD2,0x8F4B, // <cjk>
- 0x7FD4,0xE3C4, // <cjk>
- 0x7FD5,0xE3C3, // <cjk>
- 0x7FE0,0x9089, // <cjk>
- 0x7FE1,0xE3C5, // <cjk>
- 0x7FE6,0xE3C6, // <cjk>
- 0x7FE9,0xE3C7, // <cjk>
- 0x7FEB,0x8AE3, // <cjk>
- 0x7FF0,0x8ACB, // <cjk>
- 0x7FF3,0xE3C8, // <cjk>
- 0x7FF9,0xE3C9, // <cjk>
- 0x7FFB,0x967C, // <cjk>
- 0x7FFC,0x9783, // <cjk>
- 0x8000,0x9773, // <cjk>
- 0x8001,0x9856, // <cjk>
- 0x8003,0x8D6C, // <cjk>
- 0x8004,0xE3CC, // <cjk>
- 0x8005,0x8ED2, // <cjk>
- 0x8006,0xE3CB, // <cjk>
- 0x800B,0xE3CD, // <cjk>
- 0x800C,0x8EA7, // <cjk>
- 0x8010,0x91CF, // <cjk>
- 0x8012,0xE3CE, // <cjk>
- 0x8015,0x8D6B, // <cjk>
- 0x8017,0x96D5, // <cjk>
- 0x8018,0xE3CF, // <cjk>
- 0x8019,0xE3D0, // <cjk>
- 0x801C,0xE3D1, // <cjk>
- 0x8021,0xE3D2, // <cjk>
- 0x8028,0xE3D3, // <cjk>
- 0x8033,0x8EA8, // <cjk>
- 0x8036,0x96EB, // <cjk>
- 0x803B,0xE3D5, // <cjk>
- 0x803D,0x925E, // <cjk>
- 0x803F,0xE3D4, // <cjk>
- 0x8046,0xE3D7, // <cjk>
- 0x804A,0xE3D6, // <cjk>
- 0x8052,0xE3D8, // <cjk>
- 0x8056,0x90B9, // <cjk>
- 0x8058,0xE3D9, // <cjk>
- 0x805A,0xE3DA, // <cjk>
- 0x805E,0x95B7, // <cjk>
- 0x805F,0xE3DB, // <cjk>
- 0x8061,0x918F, // <cjk>
- 0x8062,0xE3DC, // <cjk>
- 0x8068,0xE3DD, // <cjk>
- 0x806F,0x97FC, // <cjk>
- 0x8070,0xE3E0, // <cjk>
- 0x8072,0xE3DF, // <cjk>
- 0x8073,0xE3DE, // <cjk>
- 0x8074,0x92AE, // <cjk>
- 0x8076,0xE3E1, // <cjk>
- 0x8077,0x9045, // <cjk>
- 0x8079,0xE3E2, // <cjk>
- 0x807D,0xE3E3, // <cjk>
- 0x807E,0x9857, // <cjk>
- 0x807F,0xE3E4, // <cjk>
- 0x8084,0xE3E5, // <cjk>
- 0x8085,0xE3E7, // <cjk>
- 0x8086,0xE3E6, // <cjk>
- 0x8087,0x94A3, // <cjk>
- 0x8089,0x93F7, // <cjk>
- 0x808B,0x985D, // <cjk>
- 0x808C,0x94A7, // <cjk>
- 0x8093,0xE3E9, // <cjk>
- 0x8096,0x8FD1, // <cjk>
- 0x8098,0x9549, // <cjk>
- 0x809A,0xE3EA, // <cjk>
- 0x809B,0xE3E8, // <cjk>
- 0x809D,0x8ACC, // <cjk>
- 0x80A1,0x8CD2, // <cjk>
- 0x80A2,0x8E88, // <cjk>
- 0x80A5,0x94EC, // <cjk>
- 0x80A9,0x8CA8, // <cjk>
- 0x80AA,0x9662, // <cjk>
- 0x80AC,0xE3ED, // <cjk>
- 0x80AD,0xE3EB, // <cjk>
- 0x80AF,0x8D6D, // <cjk>
- 0x80B1,0x8D6E, // <cjk>
- 0x80B2,0x88E7, // <cjk>
- 0x80B4,0x8DE6, // <cjk>
- 0x80BA,0x9478, // <cjk>
- 0x80C3,0x88DD, // <cjk>
- 0x80C4,0xE3F2, // <cjk>
- 0x80C6,0x925F, // <cjk>
- 0x80CC,0x9477, // <cjk>
- 0x80CE,0x91D9, // <cjk>
- 0x80D6,0xE3F4, // <cjk>
- 0x80D9,0xE3F0, // <cjk>
- 0x80DA,0xE3F3, // <cjk>
- 0x80DB,0xE3EE, // <cjk>
- 0x80DD,0xE3F1, // <cjk>
- 0x80DE,0x9645, // <cjk>
- 0x80E1,0x8CD3, // <cjk>
- 0x80E4,0x88FB, // <cjk>
- 0x80E5,0xE3EF, // <cjk>
- 0x80EF,0xE3F6, // <cjk>
- 0x80F1,0xE3F7, // <cjk>
- 0x80F4,0x93B7, // <cjk>
- 0x80F8,0x8BB9, // <cjk>
- 0x80FC,0xE445, // <cjk>
- 0x80FD,0x945C, // <cjk>
- 0x8102,0x8E89, // <cjk>
- 0x8105,0x8BBA, // <cjk>
- 0x8106,0x90C6, // <cjk>
- 0x8107,0x9865, // <cjk>
- 0x8108,0x96AC, // <cjk>
- 0x8109,0xE3F5, // <cjk>
- 0x810A,0x90D2, // <cjk>
- 0x811A,0x8B72, // <cjk>
- 0x811B,0xE3F8, // <cjk>
- 0x8123,0xE3FA, // <cjk>
- 0x8129,0xE3F9, // <cjk>
- 0x812F,0xE3FB, // <cjk>
- 0x8131,0x9245, // <cjk>
- 0x8133,0x945D, // <cjk>
- 0x8139,0x92AF, // <cjk>
- 0x813E,0xE442, // <cjk>
- 0x8146,0xE441, // <cjk>
- 0x814B,0xE3FC, // <cjk>
- 0x814E,0x9074, // <cjk>
- 0x8150,0x9585, // <cjk>
- 0x8151,0xE444, // <cjk>
- 0x8153,0xE443, // <cjk>
- 0x8154,0x8D6F, // <cjk>
- 0x8155,0x9872, // <cjk>
- 0x815F,0xE454, // <cjk>
- 0x8165,0xE448, // <cjk>
- 0x8166,0xE449, // <cjk>
- 0x816B,0x8EEE, // <cjk>
- 0x816E,0xE447, // <cjk>
- 0x8170,0x8D98, // <cjk>
- 0x8171,0xE446, // <cjk>
- 0x8174,0xE44A, // <cjk>
- 0x8178,0x92B0, // <cjk>
- 0x8179,0x95A0, // <cjk>
- 0x817A,0x9142, // <cjk>
- 0x817F,0x91DA, // <cjk>
- 0x8180,0xE44E, // <cjk>
- 0x8182,0xE44F, // <cjk>
- 0x8183,0xE44B, // <cjk>
- 0x8188,0xE44C, // <cjk>
- 0x818A,0xE44D, // <cjk>
- 0x818F,0x8D70, // <cjk>
- 0x8193,0xE455, // <cjk>
- 0x8195,0xE451, // <cjk>
- 0x819A,0x9586, // <cjk>
- 0x819C,0x968C, // <cjk>
- 0x819D,0x9547, // <cjk>
- 0x81A0,0xE450, // <cjk>
- 0x81A3,0xE453, // <cjk>
- 0x81A4,0xE452, // <cjk>
- 0x81A8,0x9663, // <cjk>
- 0x81A9,0xE456, // <cjk>
- 0x81B0,0xE457, // <cjk>
- 0x81B3,0x9156, // <cjk>
- 0x81B5,0xE458, // <cjk>
- 0x81B8,0xE45A, // <cjk>
- 0x81BA,0xE45E, // <cjk>
- 0x81BE,0xE459, // <cjk>
- 0x81BF,0x945E, // <cjk>
- 0x81C0,0xE45C, // <cjk>
- 0x81C2,0xE45D, // <cjk>
- 0x81C6,0x89B0, // <cjk>
- 0x81C8,0xE464, // <cjk>
- 0x81C9,0xE45F, // <cjk>
- 0x81CD,0xE460, // <cjk>
- 0x81D1,0xE461, // <cjk>
- 0x81D3,0x919F, // <cjk>
- 0x81D8,0xE463, // <cjk>
- 0x81D9,0xE462, // <cjk>
- 0x81DA,0xE465, // <cjk>
- 0x81DF,0xE466, // <cjk>
- 0x81E0,0xE467, // <cjk>
- 0x81E3,0x9062, // <cjk>
- 0x81E5,0x89E7, // <cjk>
- 0x81E7,0xE468, // <cjk>
- 0x81E8,0x97D5, // <cjk>
- 0x81EA,0x8EA9, // <cjk>
- 0x81ED,0x8F4C, // <cjk>
- 0x81F3,0x8E8A, // <cjk>
- 0x81F4,0x9276, // <cjk>
- 0x81FA,0xE469, // <cjk>
- 0x81FB,0xE46A, // <cjk>
- 0x81FC,0x8950, // <cjk>
- 0x81FE,0xE46B, // <cjk>
- 0x8201,0xE46C, // <cjk>
- 0x8202,0xE46D, // <cjk>
- 0x8205,0xE46E, // <cjk>
- 0x8207,0xE46F, // <cjk>
- 0x8208,0x8BBB, // <cjk>
- 0x8209,0x9DA8, // <cjk>
- 0x820A,0xE470, // <cjk>
- 0x820C,0x90E3, // <cjk>
- 0x820D,0xE471, // <cjk>
- 0x820E,0x8EC9, // <cjk>
- 0x8210,0xE472, // <cjk>
- 0x8212,0x98AE, // <cjk>
- 0x8216,0xE473, // <cjk>
- 0x8217,0x95DC, // <cjk>
- 0x8218,0x8ADA, // <cjk>
- 0x821B,0x9143, // <cjk>
- 0x821C,0x8F77, // <cjk>
- 0x821E,0x9591, // <cjk>
- 0x821F,0x8F4D, // <cjk>
- 0x8229,0xE474, // <cjk>
- 0x822A,0x8D71, // <cjk>
- 0x822B,0xE475, // <cjk>
- 0x822C,0x94CA, // <cjk>
- 0x822E,0xE484, // <cjk>
- 0x8233,0xE477, // <cjk>
- 0x8235,0x91C7, // <cjk>
- 0x8236,0x9495, // <cjk>
- 0x8237,0x8CBD, // <cjk>
- 0x8238,0xE476, // <cjk>
- 0x8239,0x9144, // <cjk>
- 0x8240,0xE478, // <cjk>
- 0x8247,0x92F8, // <cjk>
- 0x8258,0xE47A, // <cjk>
- 0x8259,0xE479, // <cjk>
- 0x825A,0xE47C, // <cjk>
- 0x825D,0xE47B, // <cjk>
- 0x825F,0xE47D, // <cjk>
- 0x8262,0xE480, // <cjk>
- 0x8264,0xE47E, // <cjk>
- 0x8266,0x8ACD, // <cjk>
- 0x8268,0xE481, // <cjk>
- 0x826A,0xE482, // <cjk>
- 0x826B,0xE483, // <cjk>
- 0x826E,0x8DAF, // <cjk>
- 0x826F,0x97C7, // <cjk>
- 0x8271,0xE485, // <cjk>
- 0x8272,0x9046, // <cjk>
- 0x8276,0x8990, // <cjk>
- 0x8277,0xE486, // <cjk>
- 0x8278,0xE487, // <cjk>
- 0x827E,0xE488, // <cjk>
- 0x828B,0x88F0, // <cjk>
- 0x828D,0xE489, // <cjk>
- 0x8292,0xE48A, // <cjk>
- 0x8299,0x9587, // <cjk>
- 0x829D,0x8EC5, // <cjk>
- 0x829F,0xE48C, // <cjk>
- 0x82A5,0x8A48, // <cjk>
- 0x82A6,0x88B0, // <cjk>
- 0x82AB,0xE48B, // <cjk>
- 0x82AC,0xE48E, // <cjk>
- 0x82AD,0x946D, // <cjk>
- 0x82AF,0x9063, // <cjk>
- 0x82B1,0x89D4, // <cjk>
- 0x82B3,0x9646, // <cjk>
- 0x82B8,0x8C7C, // <cjk>
- 0x82B9,0x8BDA, // <cjk>
- 0x82BB,0xE48D, // <cjk>
- 0x82BD,0x89E8, // <cjk>
- 0x82C5,0x8AA1, // <cjk>
- 0x82D1,0x8991, // <cjk>
- 0x82D2,0xE492, // <cjk>
- 0x82D3,0x97E8, // <cjk>
- 0x82D4,0x91DB, // <cjk>
- 0x82D7,0x9563, // <cjk>
- 0x82D9,0xE49E, // <cjk>
- 0x82DB,0x89D5, // <cjk>
- 0x82DC,0xE49C, // <cjk>
- 0x82DE,0xE49A, // <cjk>
- 0x82DF,0xE491, // <cjk>
- 0x82E1,0xE48F, // <cjk>
- 0x82E3,0xE490, // <cjk>
- 0x82E5,0x8EE1, // <cjk>
- 0x82E6,0x8BEA, // <cjk>
- 0x82E7,0x9297, // <cjk>
- 0x82EB,0x93CF, // <cjk>
- 0x82F1,0x8970, // <cjk>
- 0x82F3,0xE494, // <cjk>
- 0x82F4,0xE493, // <cjk>
- 0x82F9,0xE499, // <cjk>
- 0x82FA,0xE495, // <cjk>
- 0x82FB,0xE498, // <cjk>
- 0x8302,0x96CE, // <cjk>
- 0x8303,0xE497, // <cjk>
- 0x8304,0x89D6, // <cjk>
- 0x8305,0x8A9D, // <cjk>
- 0x8306,0xE49B, // <cjk>
- 0x8309,0xE49D, // <cjk>
- 0x830E,0x8C73, // <cjk>
- 0x8316,0xE4A1, // <cjk>
- 0x8317,0xE4AA, // <cjk>
- 0x8318,0xE4AB, // <cjk>
- 0x831C,0x88A9, // <cjk>
- 0x8323,0xE4B2, // <cjk>
- 0x8328,0x88EF, // <cjk>
- 0x832B,0xE4A9, // <cjk>
- 0x832F,0xE4A8, // <cjk>
- 0x8331,0xE4A3, // <cjk>
- 0x8332,0xE4A2, // <cjk>
- 0x8334,0xE4A0, // <cjk>
- 0x8335,0xE49F, // <cjk>
- 0x8336,0x9283, // <cjk>
- 0x8338,0x91F9, // <cjk>
- 0x8339,0xE4A5, // <cjk>
- 0x8340,0xE4A4, // <cjk>
- 0x8345,0xE4A7, // <cjk>
- 0x8349,0x9190, // <cjk>
- 0x834A,0x8C74, // <cjk>
- 0x834F,0x8960, // <cjk>
- 0x8350,0xE4A6, // <cjk>
- 0x8352,0x8D72, // <cjk>
- 0x8358,0x9191, // <cjk>
- 0x8373,0xE4B8, // <cjk>
- 0x8375,0xE4B9, // <cjk>
- 0x8377,0x89D7, // <cjk>
- 0x837B,0x89AC, // <cjk>
- 0x837C,0xE4B6, // <cjk>
- 0x8385,0xE4AC, // <cjk>
- 0x8387,0xE4B4, // <cjk>
- 0x8389,0xE4BB, // <cjk>
- 0x838A,0xE4B5, // <cjk>
- 0x838E,0xE4B3, // <cjk>
- 0x8393,0xE496, // <cjk>
- 0x8396,0xE4B1, // <cjk>
- 0x839A,0xE4AD, // <cjk>
- 0x839E,0x8ACE, // <cjk>
- 0x839F,0xE4AF, // <cjk>
- 0x83A0,0xE4BA, // <cjk>
- 0x83A2,0xE4B0, // <cjk>
- 0x83A8,0xE4BC, // <cjk>
- 0x83AA,0xE4AE, // <cjk>
- 0x83AB,0x949C, // <cjk>
- 0x83B1,0x9789, // <cjk>
- 0x83B5,0xE4B7, // <cjk>
- 0x83BD,0xE4CD, // <cjk>
- 0x83C1,0xE4C5, // <cjk>
- 0x83C5,0x909B, // <cjk>
- 0x83CA,0x8B65, // <cjk>
- 0x83CC,0x8BDB, // <cjk>
- 0x83CE,0xE4C0, // <cjk>
- 0x83D3,0x89D9, // <cjk>
- 0x83D6,0x8FD2, // <cjk>
- 0x83D8,0xE4C3, // <cjk>
- 0x83DC,0x8DD8, // <cjk>
- 0x83DF,0x9370, // <cjk>
- 0x83E0,0xE4C8, // <cjk>
- 0x83E9,0x95EC, // <cjk>
- 0x83EB,0xE4BF, // <cjk>
- 0x83EF,0x89D8, // <cjk>
- 0x83F0,0x8CD4, // <cjk>
- 0x83F1,0x9548, // <cjk>
- 0x83F2,0xE4C9, // <cjk>
- 0x83F4,0xE4BD, // <cjk>
- 0x83F7,0xE4C6, // <cjk>
- 0x83FB,0xE4D0, // <cjk>
- 0x83FD,0xE4C1, // <cjk>
- 0x8403,0xE4C2, // <cjk>
- 0x8404,0x93B8, // <cjk>
- 0x8407,0xE4C7, // <cjk>
- 0x840B,0xE4C4, // <cjk>
- 0x840C,0x9647, // <cjk>
- 0x840D,0xE4CA, // <cjk>
- 0x840E,0x88DE, // <cjk>
- 0x8413,0xE4BE, // <cjk>
- 0x8420,0xE4CC, // <cjk>
- 0x8422,0xE4CB, // <cjk>
- 0x8429,0x948B, // <cjk>
- 0x842A,0xE4D2, // <cjk>
- 0x842C,0xE4DD, // <cjk>
- 0x8431,0x8A9E, // <cjk>
- 0x8435,0xE4E0, // <cjk>
- 0x8438,0xE4CE, // <cjk>
- 0x843C,0xE4D3, // <cjk>
- 0x843D,0x978E, // <cjk>
- 0x8446,0xE4DC, // <cjk>
- 0x8449,0x9774, // <cjk>
- 0x844E,0x97A8, // <cjk>
- 0x8457,0x9298, // <cjk>
- 0x845B,0x8A8B, // <cjk>
- 0x8461,0x9592, // <cjk>
- 0x8462,0xE4E2, // <cjk>
- 0x8463,0x939F, // <cjk>
- 0x8466,0x88AF, // <cjk>
- 0x8469,0xE4DB, // <cjk>
- 0x846B,0xE4D7, // <cjk>
- 0x846C,0x9192, // <cjk>
- 0x846D,0xE4D1, // <cjk>
- 0x846E,0xE4D9, // <cjk>
- 0x846F,0xE4DE, // <cjk>
- 0x8471,0x944B, // <cjk>
- 0x8475,0x88A8, // <cjk>
- 0x8477,0xE4D6, // <cjk>
- 0x8479,0xE4DF, // <cjk>
- 0x847A,0x9598, // <cjk>
- 0x8482,0xE4DA, // <cjk>
- 0x8484,0xE4D5, // <cjk>
- 0x848B,0x8FD3, // <cjk>
- 0x8490,0x8F4E, // <cjk>
- 0x8494,0x8EAA, // <cjk>
- 0x8499,0x96D6, // <cjk>
- 0x849C,0x9566, // <cjk>
- 0x849F,0xE4E5, // <cjk>
- 0x84A1,0xE4EE, // <cjk>
- 0x84AD,0xE4D8, // <cjk>
- 0x84B2,0x8A97, // <cjk>
- 0x84B8,0x8FF6, // <cjk>
- 0x84B9,0xE4E3, // <cjk>
- 0x84BB,0xE4E8, // <cjk>
- 0x84BC,0x9193, // <cjk>
- 0x84BF,0xE4E4, // <cjk>
- 0x84C1,0xE4EB, // <cjk>
- 0x84C4,0x927E, // <cjk>
- 0x84C6,0xE4EC, // <cjk>
- 0x84C9,0x9775, // <cjk>
- 0x84CA,0xE4E1, // <cjk>
- 0x84CB,0x8A57, // <cjk>
- 0x84CD,0xE4E7, // <cjk>
- 0x84D0,0xE4EA, // <cjk>
- 0x84D1,0x96AA, // <cjk>
- 0x84D6,0xE4ED, // <cjk>
- 0x84D9,0xE4E6, // <cjk>
- 0x84DA,0xE4E9, // <cjk>
- 0x84EC,0x9648, // <cjk>
- 0x84EE,0x9840, // <cjk>
- 0x84F4,0xE4F1, // <cjk>
- 0x84FC,0xE4F8, // <cjk>
- 0x84FF,0xE4F0, // <cjk>
- 0x8500,0x8EC1, // <cjk>
- 0x8506,0xE4CF, // <cjk>
- 0x8511,0x95CC, // <cjk>
- 0x8513,0x96A0, // <cjk>
- 0x8514,0xE4F7, // <cjk>
- 0x8515,0xE4F6, // <cjk>
- 0x8517,0xE4F2, // <cjk>
- 0x8518,0xE4F3, // <cjk>
- 0x851A,0x8955, // <cjk>
- 0x851F,0xE4F5, // <cjk>
- 0x8521,0xE4EF, // <cjk>
- 0x8526,0x92D3, // <cjk>
- 0x852C,0xE4F4, // <cjk>
- 0x852D,0x88FC, // <cjk>
- 0x8535,0x91A0, // <cjk>
- 0x853D,0x95C1, // <cjk>
- 0x8540,0xE4F9, // <cjk>
- 0x8541,0xE540, // <cjk>
- 0x8543,0x94D7, // <cjk>
- 0x8548,0xE4FC, // <cjk>
- 0x8549,0x8FD4, // <cjk>
- 0x854A,0x8EC7, // <cjk>
- 0x854B,0xE542, // <cjk>
- 0x854E,0x8BBC, // <cjk>
- 0x8555,0xE543, // <cjk>
- 0x8557,0x9599, // <cjk>
- 0x8558,0xE4FB, // <cjk>
- 0x855A,0xE4D4, // <cjk>
- 0x8563,0xE4FA, // <cjk>
- 0x8568,0x986E, // <cjk>
- 0x8569,0x93A0, // <cjk>
- 0x856A,0x9593, // <cjk>
- 0x856D,0xE54A, // <cjk>
- 0x8577,0xE550, // <cjk>
- 0x857E,0xE551, // <cjk>
- 0x8580,0xE544, // <cjk>
- 0x8584,0x9496, // <cjk>
- 0x8587,0xE54E, // <cjk>
- 0x8588,0xE546, // <cjk>
- 0x858A,0xE548, // <cjk>
- 0x8590,0xE552, // <cjk>
- 0x8591,0xE547, // <cjk>
- 0x8594,0xE54B, // <cjk>
- 0x8597,0x8992, // <cjk>
- 0x8599,0x93E3, // <cjk>
- 0x859B,0xE54C, // <cjk>
- 0x859C,0xE54F, // <cjk>
- 0x85A4,0xE545, // <cjk>
- 0x85A6,0x9145, // <cjk>
- 0x85A8,0xE549, // <cjk>
- 0x85A9,0x8E46, // <cjk>
- 0x85AA,0x9064, // <cjk>
- 0x85AB,0x8C4F, // <cjk>
- 0x85AC,0x96F2, // <cjk>
- 0x85AE,0x96F7, // <cjk>
- 0x85AF,0x8F92, // <cjk>
- 0x85B9,0xE556, // <cjk>
- 0x85BA,0xE554, // <cjk>
- 0x85C1,0x986D, // <cjk>
- 0x85C9,0xE553, // <cjk>
- 0x85CD,0x9795, // <cjk>
- 0x85CF,0xE555, // <cjk>
- 0x85D0,0xE557, // <cjk>
- 0x85D5,0xE558, // <cjk>
- 0x85DD,0xE559, // <cjk>
- 0x85E4,0x93A1, // <cjk>
- 0x85E5,0xE55A, // <cjk>
- 0x85E9,0x94CB, // <cjk>
- 0x85EA,0xE54D, // <cjk>
- 0x85F7,0x8F93, // <cjk>
- 0x85F9,0xE55C, // <cjk>
- 0x85FA,0xE561, // <cjk>
- 0x85FB,0x9194, // <cjk>
- 0x85FE,0xE560, // <cjk>
- 0x8602,0xE541, // <cjk>
- 0x8606,0xE562, // <cjk>
- 0x8607,0x9168, // <cjk>
- 0x860A,0xE55D, // <cjk>
- 0x860B,0xE55F, // <cjk>
- 0x8613,0xE55E, // <cjk>
- 0x8616,0x9F50, // <cjk>
- 0x8617,0x9F41, // <cjk>
- 0x861A,0xE564, // <cjk>
- 0x8622,0xE563, // <cjk>
- 0x862D,0x9796, // <cjk>
- 0x862F,0xE1BA, // <cjk>
- 0x8630,0xE565, // <cjk>
- 0x863F,0xE566, // <cjk>
- 0x864D,0xE567, // <cjk>
- 0x864E,0x8CD5, // <cjk>
- 0x8650,0x8B73, // <cjk>
- 0x8654,0xE569, // <cjk>
- 0x8655,0x997C, // <cjk>
- 0x865A,0x8B95, // <cjk>
- 0x865C,0x97B8, // <cjk>
- 0x865E,0x8BF1, // <cjk>
- 0x865F,0xE56A, // <cjk>
- 0x8667,0xE56B, // <cjk>
- 0x866B,0x928E, // <cjk>
- 0x8671,0xE56C, // <cjk>
- 0x8679,0x93F8, // <cjk>
- 0x867B,0x88B8, // <cjk>
- 0x868A,0x89E1, // <cjk>
- 0x868B,0xE571, // <cjk>
- 0x868C,0xE572, // <cjk>
- 0x8693,0xE56D, // <cjk>
- 0x8695,0x8E5C, // <cjk>
- 0x86A3,0xE56E, // <cjk>
- 0x86A4,0x9461, // <cjk>
- 0x86A9,0xE56F, // <cjk>
- 0x86AA,0xE570, // <cjk>
- 0x86AB,0xE57A, // <cjk>
- 0x86AF,0xE574, // <cjk>
- 0x86B0,0xE577, // <cjk>
- 0x86B6,0xE573, // <cjk>
- 0x86C4,0xE575, // <cjk>
- 0x86C6,0xE576, // <cjk>
- 0x86C7,0x8ED6, // <cjk>
- 0x86C9,0xE578, // <cjk>
- 0x86CB,0x9260, // <cjk>
- 0x86CD,0x8C75, // <cjk>
- 0x86CE,0x8A61, // <cjk>
- 0x86D4,0xE57B, // <cjk>
- 0x86D9,0x8A5E, // <cjk>
- 0x86DB,0xE581, // <cjk>
- 0x86DE,0xE57C, // <cjk>
- 0x86DF,0xE580, // <cjk>
- 0x86E4,0x94B8, // <cjk>
- 0x86E9,0xE57D, // <cjk>
- 0x86EC,0xE57E, // <cjk>
- 0x86ED,0x9567, // <cjk>
- 0x86EE,0x94D8, // <cjk>
- 0x86EF,0xE582, // <cjk>
- 0x86F8,0x91FB, // <cjk>
- 0x86F9,0xE58C, // <cjk>
- 0x86FB,0xE588, // <cjk>
- 0x86FE,0x89E9, // <cjk>
- 0x8700,0xE586, // <cjk>
- 0x8702,0x9649, // <cjk>
- 0x8703,0xE587, // <cjk>
- 0x8706,0xE584, // <cjk>
- 0x8708,0xE585, // <cjk>
- 0x8709,0xE58A, // <cjk>
- 0x870A,0xE58D, // <cjk>
- 0x870D,0xE58B, // <cjk>
- 0x8711,0xE589, // <cjk>
- 0x8712,0xE583, // <cjk>
- 0x8718,0x9277, // <cjk>
- 0x871A,0xE594, // <cjk>
- 0x871C,0x96A8, // <cjk>
- 0x8725,0xE592, // <cjk>
- 0x8729,0xE593, // <cjk>
- 0x8734,0xE58E, // <cjk>
- 0x8737,0xE590, // <cjk>
- 0x873B,0xE591, // <cjk>
- 0x873F,0xE58F, // <cjk>
- 0x8749,0x90E4, // <cjk>
- 0x874B,0x9858, // <cjk>
- 0x874C,0xE598, // <cjk>
- 0x874E,0xE599, // <cjk>
- 0x8753,0xE59F, // <cjk>
- 0x8755,0x9049, // <cjk>
- 0x8757,0xE59B, // <cjk>
- 0x8759,0xE59E, // <cjk>
- 0x875F,0xE596, // <cjk>
- 0x8760,0xE595, // <cjk>
- 0x8763,0xE5A0, // <cjk>
- 0x8766,0x89DA, // <cjk>
- 0x8768,0xE59C, // <cjk>
- 0x876A,0xE5A1, // <cjk>
- 0x876E,0xE59D, // <cjk>
- 0x8774,0xE59A, // <cjk>
- 0x8776,0x92B1, // <cjk>
- 0x8778,0xE597, // <cjk>
- 0x877F,0x9488, // <cjk>
- 0x8782,0xE5A5, // <cjk>
- 0x878D,0x975A, // <cjk>
- 0x879F,0xE5A4, // <cjk>
- 0x87A2,0xE5A3, // <cjk>
- 0x87AB,0xE5AC, // <cjk>
- 0x87AF,0xE5A6, // <cjk>
- 0x87B3,0xE5AE, // <cjk>
- 0x87BA,0x9786, // <cjk>
- 0x87BB,0xE5B1, // <cjk>
- 0x87BD,0xE5A8, // <cjk>
- 0x87C0,0xE5A9, // <cjk>
- 0x87C4,0xE5AD, // <cjk>
- 0x87C6,0xE5B0, // <cjk>
- 0x87C7,0xE5AF, // <cjk>
- 0x87CB,0xE5A7, // <cjk>
- 0x87D0,0xE5AA, // <cjk>
- 0x87D2,0xE5BB, // <cjk>
- 0x87E0,0xE5B4, // <cjk>
- 0x87EF,0xE5B2, // <cjk>
- 0x87F2,0xE5B3, // <cjk>
- 0x87F6,0xE5B8, // <cjk>
- 0x87F7,0xE5B9, // <cjk>
- 0x87F9,0x8A49, // <cjk>
- 0x87FB,0x8B61, // <cjk>
- 0x87FE,0xE5B7, // <cjk>
- 0x8805,0xE5A2, // <cjk>
- 0x880D,0xE5B6, // <cjk>
- 0x880E,0xE5BA, // <cjk>
- 0x880F,0xE5B5, // <cjk>
- 0x8811,0xE5BC, // <cjk>
- 0x8815,0xE5BE, // <cjk>
- 0x8816,0xE5BD, // <cjk>
- 0x8821,0xE5C0, // <cjk>
- 0x8822,0xE5BF, // <cjk>
- 0x8823,0xE579, // <cjk>
- 0x8827,0xE5C4, // <cjk>
- 0x8831,0xE5C1, // <cjk>
- 0x8836,0xE5C2, // <cjk>
- 0x8839,0xE5C3, // <cjk>
- 0x883B,0xE5C5, // <cjk>
- 0x8840,0x8C8C, // <cjk>
- 0x8842,0xE5C7, // <cjk>
- 0x8844,0xE5C6, // <cjk>
- 0x8846,0x8F4F, // <cjk>
- 0x884C,0x8D73, // <cjk>
- 0x884D,0x9FA5, // <cjk>
- 0x8852,0xE5C8, // <cjk>
- 0x8853,0x8F70, // <cjk>
- 0x8857,0x8A58, // <cjk>
- 0x8859,0xE5C9, // <cjk>
- 0x885B,0x8971, // <cjk>
- 0x885D,0x8FD5, // <cjk>
- 0x885E,0xE5CA, // <cjk>
- 0x8861,0x8D74, // <cjk>
- 0x8862,0xE5CB, // <cjk>
- 0x8863,0x88DF, // <cjk>
- 0x8868,0x955C, // <cjk>
- 0x886B,0xE5CC, // <cjk>
- 0x8870,0x908A, // <cjk>
- 0x8872,0xE5D3, // <cjk>
- 0x8875,0xE5D0, // <cjk>
- 0x8877,0x928F, // <cjk>
- 0x887D,0xE5D1, // <cjk>
- 0x887E,0xE5CE, // <cjk>
- 0x887F,0x8BDC, // <cjk>
- 0x8881,0xE5CD, // <cjk>
- 0x8882,0xE5D4, // <cjk>
- 0x8888,0x8C55, // <cjk>
- 0x888B,0x91DC, // <cjk>
- 0x888D,0xE5DA, // <cjk>
- 0x8892,0xE5D6, // <cjk>
- 0x8896,0x91B3, // <cjk>
- 0x8897,0xE5D5, // <cjk>
- 0x8899,0xE5D8, // <cjk>
- 0x889E,0xE5CF, // <cjk>
- 0x88A2,0xE5D9, // <cjk>
- 0x88A4,0xE5DB, // <cjk>
- 0x88AB,0x94ED, // <cjk>
- 0x88AE,0xE5D7, // <cjk>
- 0x88B0,0xE5DC, // <cjk>
- 0x88B1,0xE5DE, // <cjk>
- 0x88B4,0x8CD1, // <cjk>
- 0x88B5,0xE5D2, // <cjk>
- 0x88B7,0x88BF, // <cjk>
- 0x88BF,0xE5DD, // <cjk>
- 0x88C1,0x8DD9, // <cjk>
- 0x88C2,0x97F4, // <cjk>
- 0x88C3,0xE5DF, // <cjk>
- 0x88C4,0xE5E0, // <cjk>
- 0x88C5,0x9195, // <cjk>
- 0x88CF,0x97A0, // <cjk>
- 0x88D4,0xE5E1, // <cjk>
- 0x88D5,0x9754, // <cjk>
- 0x88D8,0xE5E2, // <cjk>
- 0x88D9,0xE5E3, // <cjk>
- 0x88DC,0x95E2, // <cjk>
- 0x88DD,0xE5E4, // <cjk>
- 0x88DF,0x8DBE, // <cjk>
- 0x88E1,0x97A1, // <cjk>
- 0x88E8,0xE5E9, // <cjk>
- 0x88F2,0xE5EA, // <cjk>
- 0x88F3,0x8FD6, // <cjk>
- 0x88F4,0xE5E8, // <cjk>
- 0x88F8,0x9787, // <cjk>
- 0x88F9,0xE5E5, // <cjk>
- 0x88FC,0xE5E7, // <cjk>
- 0x88FD,0x90BB, // <cjk>
- 0x88FE,0x909E, // <cjk>
- 0x8902,0xE5E6, // <cjk>
- 0x8904,0xE5EB, // <cjk>
- 0x8907,0x95A1, // <cjk>
- 0x890A,0xE5ED, // <cjk>
- 0x890C,0xE5EC, // <cjk>
- 0x8910,0x8A8C, // <cjk>
- 0x8912,0x964A, // <cjk>
- 0x8913,0xE5EE, // <cjk>
- 0x891D,0xE5FA, // <cjk>
- 0x891E,0xE5F0, // <cjk>
- 0x8925,0xE5F1, // <cjk>
- 0x892A,0xE5F2, // <cjk>
- 0x892B,0xE5F3, // <cjk>
- 0x8936,0xE5F7, // <cjk>
- 0x8938,0xE5F8, // <cjk>
- 0x893B,0xE5F6, // <cjk>
- 0x8941,0xE5F4, // <cjk>
- 0x8943,0xE5EF, // <cjk>
- 0x8944,0xE5F5, // <cjk>
- 0x894C,0xE5F9, // <cjk>
- 0x894D,0xE8B5, // <cjk>
- 0x8956,0x89A6, // <cjk>
- 0x895E,0xE5FC, // <cjk>
- 0x895F,0x8BDD, // <cjk>
- 0x8960,0xE5FB, // <cjk>
- 0x8964,0xE641, // <cjk>
- 0x8966,0xE640, // <cjk>
- 0x896A,0xE643, // <cjk>
- 0x896D,0xE642, // <cjk>
- 0x896F,0xE644, // <cjk>
- 0x8972,0x8F50, // <cjk>
- 0x8974,0xE645, // <cjk>
- 0x8977,0xE646, // <cjk>
- 0x897E,0xE647, // <cjk>
- 0x897F,0x90BC, // <cjk>
- 0x8981,0x9776, // <cjk>
- 0x8983,0xE648, // <cjk>
- 0x8986,0x95A2, // <cjk>
- 0x8987,0x9465, // <cjk>
- 0x8988,0xE649, // <cjk>
- 0x898A,0xE64A, // <cjk>
- 0x898B,0x8CA9, // <cjk>
- 0x898F,0x8B4B, // <cjk>
- 0x8993,0xE64B, // <cjk>
- 0x8996,0x8E8B, // <cjk>
- 0x8997,0x9460, // <cjk>
- 0x8998,0xE64C, // <cjk>
- 0x899A,0x8A6F, // <cjk>
- 0x89A1,0xE64D, // <cjk>
- 0x89A6,0xE64F, // <cjk>
- 0x89A7,0x9797, // <cjk>
- 0x89A9,0xE64E, // <cjk>
- 0x89AA,0x9065, // <cjk>
- 0x89AC,0xE650, // <cjk>
- 0x89AF,0xE651, // <cjk>
- 0x89B2,0xE652, // <cjk>
- 0x89B3,0x8ACF, // <cjk>
- 0x89BA,0xE653, // <cjk>
- 0x89BD,0xE654, // <cjk>
- 0x89BF,0xE655, // <cjk>
- 0x89C0,0xE656, // <cjk>
- 0x89D2,0x8A70, // <cjk>
- 0x89DA,0xE657, // <cjk>
- 0x89DC,0xE658, // <cjk>
- 0x89DD,0xE659, // <cjk>
- 0x89E3,0x89F0, // <cjk>
- 0x89E6,0x9047, // <cjk>
- 0x89E7,0xE65A, // <cjk>
- 0x89F8,0xE65C, // <cjk>
- 0x8A00,0x8CBE, // <cjk>
- 0x8A02,0x92F9, // <cjk>
- 0x8A03,0xE65D, // <cjk>
- 0x8A08,0x8C76, // <cjk>
- 0x8A0A,0x9075, // <cjk>
- 0x8A0C,0xE660, // <cjk>
- 0x8A0E,0x93A2, // <cjk>
- 0x8A10,0xE65F, // <cjk>
- 0x8A13,0x8C50, // <cjk>
- 0x8A16,0xE65E, // <cjk>
- 0x8A17,0x91F5, // <cjk>
- 0x8A18,0x8B4C, // <cjk>
- 0x8A1B,0xE661, // <cjk>
- 0x8A1D,0xE662, // <cjk>
- 0x8A1F,0x8FD7, // <cjk>
- 0x8A23,0x8C8D, // <cjk>
- 0x8A25,0xE663, // <cjk>
- 0x8A2A,0x964B, // <cjk>
- 0x8A2D,0x90DD, // <cjk>
- 0x8A31,0x8B96, // <cjk>
- 0x8A33,0x96F3, // <cjk>
- 0x8A34,0x9169, // <cjk>
- 0x8A36,0xE664, // <cjk>
- 0x8A3A,0x9066, // <cjk>
- 0x8A3B,0x9290, // <cjk>
- 0x8A3C,0x8FD8, // <cjk>
- 0x8A41,0xE665, // <cjk>
- 0x8A46,0xE668, // <cjk>
- 0x8A48,0xE669, // <cjk>
- 0x8A50,0x8DBC, // <cjk>
- 0x8A51,0x91C0, // <cjk>
- 0x8A52,0xE667, // <cjk>
- 0x8A54,0x8FD9, // <cjk>
- 0x8A55,0x955D, // <cjk>
- 0x8A5B,0xE666, // <cjk>
- 0x8A5E,0x8E8C, // <cjk>
- 0x8A60,0x8972, // <cjk>
- 0x8A62,0xE66D, // <cjk>
- 0x8A63,0x8C77, // <cjk>
- 0x8A66,0x8E8E, // <cjk>
- 0x8A69,0x8E8D, // <cjk>
- 0x8A6B,0x986C, // <cjk>
- 0x8A6C,0xE66C, // <cjk>
- 0x8A6D,0xE66B, // <cjk>
- 0x8A6E,0x9146, // <cjk>
- 0x8A70,0x8B6C, // <cjk>
- 0x8A71,0x9862, // <cjk>
- 0x8A72,0x8A59, // <cjk>
- 0x8A73,0x8FDA, // <cjk>
- 0x8A7C,0xE66A, // <cjk>
- 0x8A82,0xE66F, // <cjk>
- 0x8A84,0xE670, // <cjk>
- 0x8A85,0xE66E, // <cjk>
- 0x8A87,0x8CD6, // <cjk>
- 0x8A89,0x975F, // <cjk>
- 0x8A8C,0x8E8F, // <cjk>
- 0x8A8D,0x9446, // <cjk>
- 0x8A91,0xE673, // <cjk>
- 0x8A93,0x90BE, // <cjk>
- 0x8A95,0x9261, // <cjk>
- 0x8A98,0x9755, // <cjk>
- 0x8A9A,0xE676, // <cjk>
- 0x8A9E,0x8CEA, // <cjk>
- 0x8AA0,0x90BD, // <cjk>
- 0x8AA1,0xE672, // <cjk>
- 0x8AA3,0xE677, // <cjk>
- 0x8AA4,0x8CEB, // <cjk>
- 0x8AA5,0xE674, // <cjk>
- 0x8AA6,0xE675, // <cjk>
- 0x8AA8,0xE671, // <cjk>
- 0x8AAC,0x90E0, // <cjk>
- 0x8AAD,0x93C7, // <cjk>
- 0x8AB0,0x924E, // <cjk>
- 0x8AB2,0x89DB, // <cjk>
- 0x8AB9,0x94EE, // <cjk>
- 0x8ABC,0x8B62, // <cjk>
- 0x8ABF,0x92B2, // <cjk>
- 0x8AC2,0xE67A, // <cjk>
- 0x8AC4,0xE678, // <cjk>
- 0x8AC7,0x926B, // <cjk>
- 0x8ACB,0x90BF, // <cjk>
- 0x8ACC,0x8AD0, // <cjk>
- 0x8ACD,0xE679, // <cjk>
- 0x8ACF,0x907A, // <cjk>
- 0x8AD2,0x97C8, // <cjk>
- 0x8AD6,0x985F, // <cjk>
- 0x8ADA,0xE67B, // <cjk>
- 0x8ADB,0xE687, // <cjk>
- 0x8ADC,0x92B3, // <cjk>
- 0x8ADE,0xE686, // <cjk>
- 0x8AE0,0xE683, // <cjk>
- 0x8AE1,0xE68B, // <cjk>
- 0x8AE2,0xE684, // <cjk>
- 0x8AE4,0xE680, // <cjk>
- 0x8AE6,0x92FA, // <cjk>
- 0x8AE7,0xE67E, // <cjk>
- 0x8AEB,0xE67C, // <cjk>
- 0x8AED,0x9740, // <cjk>
- 0x8AEE,0x8E90, // <cjk>
- 0x8AF1,0xE681, // <cjk>
- 0x8AF3,0xE67D, // <cjk>
- 0x8AF7,0xE685, // <cjk>
- 0x8AF8,0x8F94, // <cjk>
- 0x8AFA,0x8CBF, // <cjk>
- 0x8AFE,0x91F8, // <cjk>
- 0x8B00,0x9664, // <cjk>
- 0x8B01,0x8979, // <cjk>
- 0x8B02,0x88E0, // <cjk>
- 0x8B04,0x93A3, // <cjk>
- 0x8B07,0xE689, // <cjk>
- 0x8B0C,0xE688, // <cjk>
- 0x8B0E,0x93E4, // <cjk>
- 0x8B10,0xE68D, // <cjk>
- 0x8B14,0xE682, // <cjk>
- 0x8B16,0xE68C, // <cjk>
- 0x8B17,0xE68E, // <cjk>
- 0x8B19,0x8CAA, // <cjk>
- 0x8B1A,0xE68A, // <cjk>
- 0x8B1B,0x8D75, // <cjk>
- 0x8B1D,0x8ED3, // <cjk>
- 0x8B20,0xE68F, // <cjk>
- 0x8B21,0x9777, // <cjk>
- 0x8B26,0xE692, // <cjk>
- 0x8B28,0xE695, // <cjk>
- 0x8B2B,0xE693, // <cjk>
- 0x8B2C,0x9554, // <cjk>
- 0x8B33,0xE690, // <cjk>
- 0x8B39,0x8BDE, // <cjk>
- 0x8B3E,0xE694, // <cjk>
- 0x8B41,0xE696, // <cjk>
- 0x8B49,0xE69A, // <cjk>
- 0x8B4C,0xE697, // <cjk>
- 0x8B4E,0xE699, // <cjk>
- 0x8B4F,0xE698, // <cjk>
- 0x8B56,0xE69B, // <cjk>
- 0x8B58,0x8EAF, // <cjk>
- 0x8B5A,0xE69D, // <cjk>
- 0x8B5B,0xE69C, // <cjk>
- 0x8B5C,0x9588, // <cjk>
- 0x8B5F,0xE69F, // <cjk>
- 0x8B66,0x8C78, // <cjk>
- 0x8B6B,0xE69E, // <cjk>
- 0x8B6C,0xE6A0, // <cjk>
- 0x8B6F,0xE6A1, // <cjk>
- 0x8B70,0x8B63, // <cjk>
- 0x8B71,0xE3BF, // <cjk>
- 0x8B72,0x8FF7, // <cjk>
- 0x8B74,0xE6A2, // <cjk>
- 0x8B77,0x8CEC, // <cjk>
- 0x8B7D,0xE6A3, // <cjk>
- 0x8B80,0xE6A4, // <cjk>
- 0x8B83,0x8E5D, // <cjk>
- 0x8B8A,0x9DCC, // <cjk>
- 0x8B8C,0xE6A5, // <cjk>
- 0x8B8E,0xE6A6, // <cjk>
- 0x8B90,0x8F51, // <cjk>
- 0x8B92,0xE6A7, // <cjk>
- 0x8B93,0xE6A8, // <cjk>
- 0x8B96,0xE6A9, // <cjk>
- 0x8B99,0xE6AA, // <cjk>
- 0x8B9A,0xE6AB, // <cjk>
- 0x8C37,0x924A, // <cjk>
- 0x8C3A,0xE6AC, // <cjk>
- 0x8C3F,0xE6AE, // <cjk>
- 0x8C41,0xE6AD, // <cjk>
- 0x8C46,0x93A4, // <cjk>
- 0x8C48,0xE6AF, // <cjk>
- 0x8C4A,0x964C, // <cjk>
- 0x8C4C,0xE6B0, // <cjk>
- 0x8C4E,0xE6B1, // <cjk>
- 0x8C50,0xE6B2, // <cjk>
- 0x8C55,0xE6B3, // <cjk>
- 0x8C5A,0x93D8, // <cjk>
- 0x8C61,0x8FDB, // <cjk>
- 0x8C62,0xE6B4, // <cjk>
- 0x8C6A,0x8D8B, // <cjk>
- 0x8C6B,0x98AC, // <cjk>
- 0x8C6C,0xE6B5, // <cjk>
- 0x8C78,0xE6B6, // <cjk>
- 0x8C79,0x955E, // <cjk>
- 0x8C7A,0xE6B7, // <cjk>
- 0x8C7C,0xE6BF, // <cjk>
- 0x8C82,0xE6B8, // <cjk>
- 0x8C85,0xE6BA, // <cjk>
- 0x8C89,0xE6B9, // <cjk>
- 0x8C8A,0xE6BB, // <cjk>
- 0x8C8C,0x9665, // <cjk>
- 0x8C8D,0xE6BC, // <cjk>
- 0x8C8E,0xE6BD, // <cjk>
- 0x8C94,0xE6BE, // <cjk>
- 0x8C98,0xE6C0, // <cjk>
- 0x8C9D,0x8A4C, // <cjk>
- 0x8C9E,0x92E5, // <cjk>
- 0x8CA0,0x9589, // <cjk>
- 0x8CA1,0x8DE0, // <cjk>
- 0x8CA2,0x8D76, // <cjk>
- 0x8CA7,0x956E, // <cjk>
- 0x8CA8,0x89DD, // <cjk>
- 0x8CA9,0x94CC, // <cjk>
- 0x8CAA,0xE6C3, // <cjk>
- 0x8CAB,0x8AD1, // <cjk>
- 0x8CAC,0x90D3, // <cjk>
- 0x8CAD,0xE6C2, // <cjk>
- 0x8CAE,0xE6C7, // <cjk>
- 0x8CAF,0x9299, // <cjk>
- 0x8CB0,0x96E1, // <cjk>
- 0x8CB2,0xE6C5, // <cjk>
- 0x8CB3,0xE6C6, // <cjk>
- 0x8CB4,0x8B4D, // <cjk>
- 0x8CB6,0xE6C8, // <cjk>
- 0x8CB7,0x9483, // <cjk>
- 0x8CB8,0x91DD, // <cjk>
- 0x8CBB,0x94EF, // <cjk>
- 0x8CBC,0x935C, // <cjk>
- 0x8CBD,0xE6C4, // <cjk>
- 0x8CBF,0x9666, // <cjk>
- 0x8CC0,0x89EA, // <cjk>
- 0x8CC1,0xE6CA, // <cjk>
- 0x8CC2,0x9847, // <cjk>
- 0x8CC3,0x92C0, // <cjk>
- 0x8CC4,0x9864, // <cjk>
- 0x8CC7,0x8E91, // <cjk>
- 0x8CC8,0xE6C9, // <cjk>
- 0x8CCA,0x91AF, // <cjk>
- 0x8CCD,0xE6DA, // <cjk>
- 0x8CCE,0x9147, // <cjk>
- 0x8CD1,0x93F6, // <cjk>
- 0x8CD3,0x956F, // <cjk>
- 0x8CDA,0xE6CD, // <cjk>
- 0x8CDB,0x8E5E, // <cjk>
- 0x8CDC,0x8E92, // <cjk>
- 0x8CDE,0x8FDC, // <cjk>
- 0x8CE0,0x9485, // <cjk>
- 0x8CE2,0x8CAB, // <cjk>
- 0x8CE3,0xE6CC, // <cjk>
- 0x8CE4,0xE6CB, // <cjk>
- 0x8CE6,0x958A, // <cjk>
- 0x8CEA,0x8EBF, // <cjk>
- 0x8CED,0x9371, // <cjk>
- 0x8CFA,0xE6CF, // <cjk>
- 0x8CFB,0xE6D0, // <cjk>
- 0x8CFC,0x8D77, // <cjk>
- 0x8CFD,0xE6CE, // <cjk>
- 0x8D04,0xE6D1, // <cjk>
- 0x8D05,0xE6D2, // <cjk>
- 0x8D07,0xE6D4, // <cjk>
- 0x8D08,0x91A1, // <cjk>
- 0x8D0A,0xE6D3, // <cjk>
- 0x8D0B,0x8AE4, // <cjk>
- 0x8D0D,0xE6D6, // <cjk>
- 0x8D0F,0xE6D5, // <cjk>
- 0x8D10,0xE6D7, // <cjk>
- 0x8D13,0xE6D9, // <cjk>
- 0x8D14,0xE6DB, // <cjk>
- 0x8D16,0xE6DC, // <cjk>
- 0x8D64,0x90D4, // <cjk>
- 0x8D66,0x8ECD, // <cjk>
- 0x8D67,0xE6DD, // <cjk>
- 0x8D6B,0x8A71, // <cjk>
- 0x8D6D,0xE6DE, // <cjk>
- 0x8D70,0x9196, // <cjk>
- 0x8D71,0xE6DF, // <cjk>
- 0x8D73,0xE6E0, // <cjk>
- 0x8D74,0x958B, // <cjk>
- 0x8D77,0x8B4E, // <cjk>
- 0x8D81,0xE6E1, // <cjk>
- 0x8D85,0x92B4, // <cjk>
- 0x8D8A,0x897A, // <cjk>
- 0x8D99,0xE6E2, // <cjk>
- 0x8DA3,0x8EEF, // <cjk>
- 0x8DA8,0x9096, // <cjk>
- 0x8DB3,0x91AB, // <cjk>
- 0x8DBA,0xE6E5, // <cjk>
- 0x8DBE,0xE6E4, // <cjk>
- 0x8DC2,0xE6E3, // <cjk>
- 0x8DCB,0xE6EB, // <cjk>
- 0x8DCC,0xE6E9, // <cjk>
- 0x8DCF,0xE6E6, // <cjk>
- 0x8DD6,0xE6E8, // <cjk>
- 0x8DDA,0xE6E7, // <cjk>
- 0x8DDB,0xE6EA, // <cjk>
- 0x8DDD,0x8B97, // <cjk>
- 0x8DDF,0xE6EE, // <cjk>
- 0x8DE1,0x90D5, // <cjk>
- 0x8DE3,0xE6EF, // <cjk>
- 0x8DE8,0x8CD7, // <cjk>
- 0x8DEA,0xE6EC, // <cjk>
- 0x8DEB,0xE6ED, // <cjk>
- 0x8DEF,0x9848, // <cjk>
- 0x8DF3,0x92B5, // <cjk>
- 0x8DF5,0x9148, // <cjk>
- 0x8DFC,0xE6F0, // <cjk>
- 0x8DFF,0xE6F3, // <cjk>
- 0x8E08,0xE6F1, // <cjk>
- 0x8E09,0xE6F2, // <cjk>
- 0x8E0A,0x9778, // <cjk>
- 0x8E0F,0x93A5, // <cjk>
- 0x8E10,0xE6F6, // <cjk>
- 0x8E1D,0xE6F4, // <cjk>
- 0x8E1E,0xE6F5, // <cjk>
- 0x8E1F,0xE6F7, // <cjk>
- 0x8E2A,0xE748, // <cjk>
- 0x8E30,0xE6FA, // <cjk>
- 0x8E34,0xE6FB, // <cjk>
- 0x8E35,0xE6F9, // <cjk>
- 0x8E42,0xE6F8, // <cjk>
- 0x8E44,0x92FB, // <cjk>
- 0x8E47,0xE740, // <cjk>
- 0x8E48,0xE744, // <cjk>
- 0x8E49,0xE741, // <cjk>
- 0x8E4A,0xE6FC, // <cjk>
- 0x8E4C,0xE742, // <cjk>
- 0x8E50,0xE743, // <cjk>
- 0x8E55,0xE74A, // <cjk>
- 0x8E59,0xE745, // <cjk>
- 0x8E5F,0x90D6, // <cjk>
- 0x8E60,0xE747, // <cjk>
- 0x8E63,0xE749, // <cjk>
- 0x8E64,0xE746, // <cjk>
- 0x8E72,0xE74C, // <cjk>
- 0x8E74,0x8F52, // <cjk>
- 0x8E76,0xE74B, // <cjk>
- 0x8E7C,0xE74D, // <cjk>
- 0x8E81,0xE74E, // <cjk>
- 0x8E84,0xE751, // <cjk>
- 0x8E85,0xE750, // <cjk>
- 0x8E87,0xE74F, // <cjk>
- 0x8E8A,0xE753, // <cjk>
- 0x8E8B,0xE752, // <cjk>
- 0x8E8D,0x96F4, // <cjk>
- 0x8E91,0xE755, // <cjk>
- 0x8E93,0xE754, // <cjk>
- 0x8E94,0xE756, // <cjk>
- 0x8E99,0xE757, // <cjk>
- 0x8EA1,0xE759, // <cjk>
- 0x8EAA,0xE758, // <cjk>
- 0x8EAB,0x9067, // <cjk>
- 0x8EAC,0xE75A, // <cjk>
- 0x8EAF,0x8BEB, // <cjk>
- 0x8EB1,0xE75D, // <cjk>
- 0x8EBE,0xE75E, // <cjk>
- 0x8EC5,0xE75F, // <cjk>
- 0x8EC6,0xE75C, // <cjk>
- 0x8EC8,0xE760, // <cjk>
- 0x8ECA,0x8ED4, // <cjk>
- 0x8ECB,0xE761, // <cjk>
- 0x8ECC,0x8B4F, // <cjk>
- 0x8ECD,0x8C52, // <cjk>
- 0x8ED2,0x8CAC, // <cjk>
- 0x8EDB,0xE762, // <cjk>
- 0x8EDF,0x93EE, // <cjk>
- 0x8EE2,0x935D, // <cjk>
- 0x8EE3,0xE763, // <cjk>
- 0x8EEB,0xE766, // <cjk>
- 0x8EF8,0x8EB2, // <cjk>
- 0x8EFB,0xE765, // <cjk>
- 0x8EFC,0xE764, // <cjk>
- 0x8EFD,0x8C79, // <cjk>
- 0x8EFE,0xE767, // <cjk>
- 0x8F03,0x8A72, // <cjk>
- 0x8F05,0xE769, // <cjk>
- 0x8F09,0x8DDA, // <cjk>
- 0x8F0A,0xE768, // <cjk>
- 0x8F0C,0xE771, // <cjk>
- 0x8F12,0xE76B, // <cjk>
- 0x8F13,0xE76D, // <cjk>
- 0x8F14,0x95E3, // <cjk>
- 0x8F15,0xE76A, // <cjk>
- 0x8F19,0xE76C, // <cjk>
- 0x8F1B,0xE770, // <cjk>
- 0x8F1C,0xE76E, // <cjk>
- 0x8F1D,0x8B50, // <cjk>
- 0x8F1F,0xE76F, // <cjk>
- 0x8F26,0xE772, // <cjk>
- 0x8F29,0x9479, // <cjk>
- 0x8F2A,0x97D6, // <cjk>
- 0x8F2F,0x8F53, // <cjk>
- 0x8F33,0xE773, // <cjk>
- 0x8F38,0x9741, // <cjk>
- 0x8F39,0xE775, // <cjk>
- 0x8F3B,0xE774, // <cjk>
- 0x8F3E,0xE778, // <cjk>
- 0x8F3F,0x9760, // <cjk>
- 0x8F42,0xE777, // <cjk>
- 0x8F44,0x8A8D, // <cjk>
- 0x8F45,0xE776, // <cjk>
- 0x8F46,0xE77B, // <cjk>
- 0x8F49,0xE77A, // <cjk>
- 0x8F4C,0xE779, // <cjk>
- 0x8F4D,0x9351, // <cjk>
- 0x8F4E,0xE77C, // <cjk>
- 0x8F57,0xE77D, // <cjk>
- 0x8F5C,0xE77E, // <cjk>
- 0x8F5F,0x8D8C, // <cjk>
- 0x8F61,0x8C44, // <cjk>
- 0x8F62,0xE780, // <cjk>
- 0x8F63,0xE781, // <cjk>
- 0x8F64,0xE782, // <cjk>
- 0x8F9B,0x9068, // <cjk>
- 0x8F9C,0xE783, // <cjk>
- 0x8F9E,0x8EAB, // <cjk>
- 0x8F9F,0xE784, // <cjk>
- 0x8FA3,0xE785, // <cjk>
- 0x8FA7,0x999F, // <cjk>
- 0x8FA8,0x999E, // <cjk>
- 0x8FAD,0xE786, // <cjk>
- 0x8FAE,0xE390, // <cjk>
- 0x8FAF,0xE787, // <cjk>
- 0x8FB0,0x9243, // <cjk>
- 0x8FB1,0x904A, // <cjk>
- 0x8FB2,0x945F, // <cjk>
- 0x8FB7,0xE788, // <cjk>
- 0x8FBA,0x95D3, // <cjk>
- 0x8FBB,0x92D2, // <cjk>
- 0x8FBC,0x8D9E, // <cjk>
- 0x8FBF,0x9248, // <cjk>
- 0x8FC2,0x8949, // <cjk>
- 0x8FC4,0x9698, // <cjk>
- 0x8FC5,0x9076, // <cjk>
- 0x8FCE,0x8C7D, // <cjk>
- 0x8FD1,0x8BDF, // <cjk>
- 0x8FD4,0x95D4, // <cjk>
- 0x8FDA,0xE789, // <cjk>
- 0x8FE2,0xE78B, // <cjk>
- 0x8FE5,0xE78A, // <cjk>
- 0x8FE6,0x89DE, // <cjk>
- 0x8FE9,0x93F4, // <cjk>
- 0x8FEA,0xE78C, // <cjk>
- 0x8FEB,0x9497, // <cjk>
- 0x8FED,0x9352, // <cjk>
- 0x8FEF,0xE78D, // <cjk>
- 0x8FF0,0x8F71, // <cjk>
- 0x8FF4,0xE78F, // <cjk>
- 0x8FF7,0x96C0, // <cjk>
- 0x8FF8,0xE79E, // <cjk>
- 0x8FF9,0xE791, // <cjk>
- 0x8FFA,0xE792, // <cjk>
- 0x8FFD,0x92C7, // <cjk>
- 0x9000,0x91DE, // <cjk>
- 0x9001,0x9197, // <cjk>
- 0x9003,0x93A6, // <cjk>
- 0x9005,0xE790, // <cjk>
- 0x9006,0x8B74, // <cjk>
- 0x900B,0xE799, // <cjk>
- 0x900D,0xE796, // <cjk>
- 0x900E,0xE7A3, // <cjk>
- 0x900F,0x93A7, // <cjk>
- 0x9010,0x9280, // <cjk>
- 0x9011,0xE793, // <cjk>
- 0x9013,0x92FC, // <cjk>
- 0x9014,0x9372, // <cjk>
- 0x9015,0xE794, // <cjk>
- 0x9016,0xE798, // <cjk>
- 0x9017,0x9080, // <cjk>
- 0x9019,0x9487, // <cjk>
- 0x901A,0x92CA, // <cjk>
- 0x901D,0x90C0, // <cjk>
- 0x901E,0xE797, // <cjk>
- 0x901F,0x91AC, // <cjk>
- 0x9020,0x91A2, // <cjk>
- 0x9021,0xE795, // <cjk>
- 0x9022,0x88A7, // <cjk>
- 0x9023,0x9841, // <cjk>
- 0x9027,0xE79A, // <cjk>
- 0x902E,0x91DF, // <cjk>
- 0x9031,0x8F54, // <cjk>
- 0x9032,0x9069, // <cjk>
- 0x9035,0xE79C, // <cjk>
- 0x9036,0xE79B, // <cjk>
- 0x9038,0x88ED, // <cjk>
- 0x9039,0xE79D, // <cjk>
- 0x903C,0x954E, // <cjk>
- 0x903E,0xE7A5, // <cjk>
- 0x9041,0x93D9, // <cjk>
- 0x9042,0x908B, // <cjk>
- 0x9045,0x9278, // <cjk>
- 0x9047,0x8BF6, // <cjk>
- 0x9049,0xE7A4, // <cjk>
- 0x904A,0x9756, // <cjk>
- 0x904B,0x895E, // <cjk>
- 0x904D,0x95D5, // <cjk>
- 0x904E,0x89DF, // <cjk>
- 0x904F,0xE79F, // <cjk>
- 0x9050,0xE7A0, // <cjk>
- 0x9051,0xE7A1, // <cjk>
- 0x9052,0xE7A2, // <cjk>
- 0x9053,0x93B9, // <cjk>
- 0x9054,0x9242, // <cjk>
- 0x9055,0x88E1, // <cjk>
- 0x9056,0xE7A6, // <cjk>
- 0x9058,0xE7A7, // <cjk>
- 0x9059,0xEAA1, // <cjk>
- 0x905C,0x91BB, // <cjk>
- 0x905E,0xE7A8, // <cjk>
- 0x9060,0x8993, // <cjk>
- 0x9061,0x916B, // <cjk>
- 0x9063,0x8CAD, // <cjk>
- 0x9065,0x9779, // <cjk>
- 0x9068,0xE7A9, // <cjk>
- 0x9069,0x934B, // <cjk>
- 0x906D,0x9198, // <cjk>
- 0x906E,0x8ED5, // <cjk>
- 0x906F,0xE7AA, // <cjk>
- 0x9072,0xE7AD, // <cjk>
- 0x9075,0x8F85, // <cjk>
- 0x9076,0xE7AB, // <cjk>
- 0x9077,0x914A, // <cjk>
- 0x9078,0x9149, // <cjk>
- 0x907A,0x88E2, // <cjk>
- 0x907C,0x97C9, // <cjk>
- 0x907D,0xE7AF, // <cjk>
- 0x907F,0x94F0, // <cjk>
- 0x9080,0xE7B1, // <cjk>
- 0x9081,0xE7B0, // <cjk>
- 0x9082,0xE7AE, // <cjk>
- 0x9083,0xE284, // <cjk>
- 0x9084,0x8AD2, // <cjk>
- 0x9087,0xE78E, // <cjk>
- 0x9089,0xE7B3, // <cjk>
- 0x908A,0xE7B2, // <cjk>
- 0x908F,0xE7B4, // <cjk>
- 0x9091,0x9757, // <cjk>
- 0x90A3,0x93DF, // <cjk>
- 0x90A6,0x964D, // <cjk>
- 0x90A8,0xE7B5, // <cjk>
- 0x90AA,0x8ED7, // <cjk>
- 0x90AF,0xE7B6, // <cjk>
- 0x90B1,0xE7B7, // <cjk>
- 0x90B5,0xE7B8, // <cjk>
- 0x90B8,0x9340, // <cjk>
- 0x90C1,0x88E8, // <cjk>
- 0x90CA,0x8D78, // <cjk>
- 0x90CE,0x9859, // <cjk>
- 0x90DB,0xE7BC, // <cjk>
- 0x90E1,0x8C53, // <cjk>
- 0x90E2,0xE7B9, // <cjk>
- 0x90E4,0xE7BA, // <cjk>
- 0x90E8,0x9594, // <cjk>
- 0x90ED,0x8A73, // <cjk>
- 0x90F5,0x9758, // <cjk>
- 0x90F7,0x8BBD, // <cjk>
- 0x90FD,0x9373, // <cjk>
- 0x9102,0xE7BD, // <cjk>
- 0x9112,0xE7BE, // <cjk>
- 0x9119,0xE7BF, // <cjk>
- 0x912D,0x9341, // <cjk>
- 0x9130,0xE7C1, // <cjk>
- 0x9132,0xE7C0, // <cjk>
- 0x9149,0x93D1, // <cjk>
- 0x914A,0xE7C2, // <cjk>
- 0x914B,0x8F55, // <cjk>
- 0x914C,0x8EDE, // <cjk>
- 0x914D,0x947A, // <cjk>
- 0x914E,0x9291, // <cjk>
- 0x9152,0x8EF0, // <cjk>
- 0x9154,0x908C, // <cjk>
- 0x9156,0xE7C3, // <cjk>
- 0x9158,0xE7C4, // <cjk>
- 0x9162,0x907C, // <cjk>
- 0x9163,0xE7C5, // <cjk>
- 0x9165,0xE7C6, // <cjk>
- 0x9169,0xE7C7, // <cjk>
- 0x916A,0x978F, // <cjk>
- 0x916C,0x8F56, // <cjk>
- 0x9172,0xE7C9, // <cjk>
- 0x9173,0xE7C8, // <cjk>
- 0x9175,0x8D79, // <cjk>
- 0x9177,0x8D93, // <cjk>
- 0x9178,0x8E5F, // <cjk>
- 0x9182,0xE7CC, // <cjk>
- 0x9187,0x8F86, // <cjk>
- 0x9189,0xE7CB, // <cjk>
- 0x918B,0xE7CA, // <cjk>
- 0x918D,0x91E7, // <cjk>
- 0x9190,0x8CED, // <cjk>
- 0x9192,0x90C1, // <cjk>
- 0x9197,0x94AE, // <cjk>
- 0x919C,0x8F58, // <cjk>
- 0x91A2,0xE7CD, // <cjk>
- 0x91A4,0x8FDD, // <cjk>
- 0x91AA,0xE7D0, // <cjk>
- 0x91AB,0xE7CE, // <cjk>
- 0x91AF,0xE7CF, // <cjk>
- 0x91B4,0xE7D2, // <cjk>
- 0x91B5,0xE7D1, // <cjk>
- 0x91B8,0x8FF8, // <cjk>
- 0x91BA,0xE7D3, // <cjk>
- 0x91C0,0xE7D4, // <cjk>
- 0x91C1,0xE7D5, // <cjk>
- 0x91C6,0x94CE, // <cjk>
- 0x91C7,0x8DD1, // <cjk>
- 0x91C8,0x8EDF, // <cjk>
- 0x91C9,0xE7D6, // <cjk>
- 0x91CB,0xE7D7, // <cjk>
- 0x91CC,0x97A2, // <cjk>
- 0x91CD,0x8F64, // <cjk>
- 0x91CE,0x96EC, // <cjk>
- 0x91CF,0x97CA, // <cjk>
- 0x91D0,0xE7D8, // <cjk>
- 0x91D1,0x8BE0, // <cjk>
- 0x91D6,0xE7D9, // <cjk>
- 0x91D8,0x9342, // <cjk>
- 0x91DB,0xE7DC, // <cjk>
- 0x91DC,0x8A98, // <cjk>
- 0x91DD,0x906A, // <cjk>
- 0x91DF,0xE7DA, // <cjk>
- 0x91E1,0xE7DB, // <cjk>
- 0x91E3,0x92DE, // <cjk>
- 0x91E6,0x9674, // <cjk>
- 0x91E7,0x8BFA, // <cjk>
- 0x91F5,0xE7DE, // <cjk>
- 0x91F6,0xE7DF, // <cjk>
- 0x91FC,0xE7DD, // <cjk>
- 0x91FF,0xE7E1, // <cjk>
- 0x920D,0x93DD, // <cjk>
- 0x920E,0x8A62, // <cjk>
- 0x9211,0xE7E5, // <cjk>
- 0x9214,0xE7E2, // <cjk>
- 0x9215,0xE7E4, // <cjk>
- 0x921E,0xE7E0, // <cjk>
- 0x9229,0xE86E, // <cjk>
- 0x922C,0xE7E3, // <cjk>
- 0x9234,0x97E9, // <cjk>
- 0x9237,0x8CD8, // <cjk>
- 0x923F,0xE7ED, // <cjk>
- 0x9244,0x9353, // <cjk>
- 0x9245,0xE7E8, // <cjk>
- 0x9248,0xE7EB, // <cjk>
- 0x9249,0xE7E9, // <cjk>
- 0x924B,0xE7EE, // <cjk>
- 0x9250,0xE7EF, // <cjk>
- 0x9257,0xE7E7, // <cjk>
- 0x925A,0xE7F4, // <cjk>
- 0x925B,0x8994, // <cjk>
- 0x925E,0xE7E6, // <cjk>
- 0x9262,0x94AB, // <cjk>
- 0x9264,0xE7EA, // <cjk>
- 0x9266,0x8FDE, // <cjk>
- 0x9271,0x8D7A, // <cjk>
- 0x927E,0x9667, // <cjk>
- 0x9280,0x8BE2, // <cjk>
- 0x9283,0x8F65, // <cjk>
- 0x9285,0x93BA, // <cjk>
- 0x9291,0x914C, // <cjk>
- 0x9293,0xE7F2, // <cjk>
- 0x9295,0xE7EC, // <cjk>
- 0x9296,0xE7F1, // <cjk>
- 0x9298,0x96C1, // <cjk>
- 0x929A,0x92B6, // <cjk>
- 0x929B,0xE7F3, // <cjk>
- 0x929C,0xE7F0, // <cjk>
- 0x92AD,0x914B, // <cjk>
- 0x92B7,0xE7F7, // <cjk>
- 0x92B9,0xE7F6, // <cjk>
- 0x92CF,0xE7F5, // <cjk>
- 0x92D2,0x964E, // <cjk>
- 0x92E4,0x8F9B, // <cjk>
- 0x92E9,0xE7F8, // <cjk>
- 0x92EA,0x95DD, // <cjk>
- 0x92ED,0x8973, // <cjk>
- 0x92F2,0x9565, // <cjk>
- 0x92F3,0x9292, // <cjk>
- 0x92F8,0x8B98, // <cjk>
- 0x92FA,0xE7FA, // <cjk>
- 0x92FC,0x8D7C, // <cjk>
- 0x9306,0x8E4B, // <cjk>
- 0x930F,0xE7F9, // <cjk>
- 0x9310,0x908D, // <cjk>
- 0x9318,0x908E, // <cjk>
- 0x9319,0xE840, // <cjk>
- 0x931A,0xE842, // <cjk>
- 0x9320,0x8FF9, // <cjk>
- 0x9322,0xE841, // <cjk>
- 0x9323,0xE843, // <cjk>
- 0x9326,0x8BD1, // <cjk>
- 0x9328,0x9564, // <cjk>
- 0x932B,0x8EE0, // <cjk>
- 0x932C,0x9842, // <cjk>
- 0x932E,0xE7FC, // <cjk>
- 0x932F,0x8DF6, // <cjk>
- 0x9332,0x985E, // <cjk>
- 0x9335,0xE845, // <cjk>
- 0x933A,0xE844, // <cjk>
- 0x933B,0xE846, // <cjk>
- 0x9344,0xE7FB, // <cjk>
- 0x934B,0x93E7, // <cjk>
- 0x934D,0x9374, // <cjk>
- 0x9354,0x92D5, // <cjk>
- 0x9356,0xE84B, // <cjk>
- 0x935B,0x9262, // <cjk>
- 0x935C,0xE847, // <cjk>
- 0x9360,0xE848, // <cjk>
- 0x936C,0x8C4C, // <cjk>
- 0x936E,0xE84A, // <cjk>
- 0x9375,0x8CAE, // <cjk>
- 0x937C,0xE849, // <cjk>
- 0x937E,0x8FDF, // <cjk>
- 0x938C,0x8A99, // <cjk>
- 0x9394,0xE84F, // <cjk>
- 0x9396,0x8DBD, // <cjk>
- 0x9397,0x9199, // <cjk>
- 0x939A,0x92C8, // <cjk>
- 0x93A7,0x8A5A, // <cjk>
- 0x93AC,0xE84D, // <cjk>
- 0x93AD,0xE84E, // <cjk>
- 0x93AE,0x92C1, // <cjk>
- 0x93B0,0xE84C, // <cjk>
- 0x93B9,0xE850, // <cjk>
- 0x93C3,0xE856, // <cjk>
- 0x93C8,0xE859, // <cjk>
- 0x93D0,0xE858, // <cjk>
- 0x93D1,0x934C, // <cjk>
- 0x93D6,0xE851, // <cjk>
- 0x93D7,0xE852, // <cjk>
- 0x93D8,0xE855, // <cjk>
- 0x93DD,0xE857, // <cjk>
- 0x93E1,0x8BBE, // <cjk>
- 0x93E4,0xE85A, // <cjk>
- 0x93E5,0xE854, // <cjk>
- 0x93E8,0xE853, // <cjk>
- 0x9403,0xE85E, // <cjk>
- 0x9407,0xE85F, // <cjk>
- 0x9410,0xE860, // <cjk>
- 0x9413,0xE85D, // <cjk>
- 0x9414,0xE85C, // <cjk>
- 0x9418,0x8FE0, // <cjk>
- 0x9419,0x93A8, // <cjk>
- 0x9421,0xE864, // <cjk>
- 0x942B,0xE862, // <cjk>
- 0x9435,0xE863, // <cjk>
- 0x9436,0xE861, // <cjk>
- 0x9438,0x91F6, // <cjk>
- 0x943A,0xE865, // <cjk>
- 0x9441,0xE866, // <cjk>
- 0x9444,0xE868, // <cjk>
- 0x9451,0x8AD3, // <cjk>
- 0x9452,0xE867, // <cjk>
- 0x9453,0x96F8, // <cjk>
- 0x945A,0xE873, // <cjk>
- 0x945B,0xE869, // <cjk>
- 0x945E,0xE86C, // <cjk>
- 0x9460,0xE86A, // <cjk>
- 0x9462,0xE86B, // <cjk>
- 0x946A,0xE86D, // <cjk>
- 0x9470,0xE86F, // <cjk>
- 0x9475,0xE870, // <cjk>
- 0x9477,0xE871, // <cjk>
- 0x947C,0xE874, // <cjk>
- 0x947D,0xE872, // <cjk>
- 0x947E,0xE875, // <cjk>
- 0x947F,0xE877, // <cjk>
- 0x9481,0xE876, // <cjk>
- 0x9577,0x92B7, // <cjk>
- 0x9580,0x96E5, // <cjk>
- 0x9582,0xE878, // <cjk>
- 0x9583,0x914D, // <cjk>
- 0x9587,0xE879, // <cjk>
- 0x9589,0x95C2, // <cjk>
- 0x958A,0xE87A, // <cjk>
- 0x958B,0x8A4A, // <cjk>
- 0x9591,0x8AD5, // <cjk>
- 0x9593,0x8AD4, // <cjk>
- 0x9594,0xE87B, // <cjk>
- 0x9596,0xE87C, // <cjk>
- 0x9598,0xE87D, // <cjk>
- 0x9599,0xE87E, // <cjk>
- 0x95A0,0xE880, // <cjk>
- 0x95A2,0x8AD6, // <cjk>
- 0x95A3,0x8A74, // <cjk>
- 0x95A4,0x8D7D, // <cjk>
- 0x95A5,0x94B4, // <cjk>
- 0x95A7,0xE882, // <cjk>
- 0x95A8,0xE881, // <cjk>
- 0x95AD,0xE883, // <cjk>
- 0x95B2,0x897B, // <cjk>
- 0x95B9,0xE886, // <cjk>
- 0x95BB,0xE885, // <cjk>
- 0x95BC,0xE884, // <cjk>
- 0x95BE,0xE887, // <cjk>
- 0x95C3,0xE88A, // <cjk>
- 0x95C7,0x88C5, // <cjk>
- 0x95CA,0xE888, // <cjk>
- 0x95CC,0xE88C, // <cjk>
- 0x95CD,0xE88B, // <cjk>
- 0x95D4,0xE88E, // <cjk>
- 0x95D5,0xE88D, // <cjk>
- 0x95D6,0xE88F, // <cjk>
- 0x95D8,0x93AC, // <cjk>
- 0x95DC,0xE890, // <cjk>
- 0x95E1,0xE891, // <cjk>
- 0x95E2,0xE893, // <cjk>
- 0x95E5,0xE892, // <cjk>
- 0x961C,0x958C, // <cjk>
- 0x9621,0xE894, // <cjk>
- 0x9628,0xE895, // <cjk>
- 0x962A,0x8DE3, // <cjk>
- 0x962E,0xE896, // <cjk>
- 0x962F,0xE897, // <cjk>
- 0x9632,0x9668, // <cjk>
- 0x963B,0x916A, // <cjk>
- 0x963F,0x88A2, // <cjk>
- 0x9640,0x91C9, // <cjk>
- 0x9642,0xE898, // <cjk>
- 0x9644,0x958D, // <cjk>
- 0x964B,0xE89B, // <cjk>
- 0x964C,0xE899, // <cjk>
- 0x964D,0x8D7E, // <cjk>
- 0x964F,0xE89A, // <cjk>
- 0x9650,0x8CC0, // <cjk>
- 0x965B,0x95C3, // <cjk>
- 0x965C,0xE89D, // <cjk>
- 0x965D,0xE89F, // <cjk>
- 0x965E,0xE89E, // <cjk>
- 0x965F,0xE8A0, // <cjk>
- 0x9662,0x8940, // <cjk>
- 0x9663,0x9077, // <cjk>
- 0x9664,0x8F9C, // <cjk>
- 0x9665,0x8AD7, // <cjk>
- 0x9666,0xE8A1, // <cjk>
- 0x966A,0x9486, // <cjk>
- 0x966C,0xE8A3, // <cjk>
- 0x9670,0x8941, // <cjk>
- 0x9672,0xE8A2, // <cjk>
- 0x9673,0x92C2, // <cjk>
- 0x9675,0x97CB, // <cjk>
- 0x9676,0x93A9, // <cjk>
- 0x9677,0xE89C, // <cjk>
- 0x9678,0x97A4, // <cjk>
- 0x967A,0x8CAF, // <cjk>
- 0x967D,0x977A, // <cjk>
- 0x9685,0x8BF7, // <cjk>
- 0x9686,0x97B2, // <cjk>
- 0x9688,0x8C47, // <cjk>
- 0x968A,0x91E0, // <cjk>
- 0x968B,0xE440, // <cjk>
- 0x968D,0xE8A4, // <cjk>
- 0x968E,0x8A4B, // <cjk>
- 0x968F,0x908F, // <cjk>
- 0x9694,0x8A75, // <cjk>
- 0x9695,0xE8A6, // <cjk>
- 0x9697,0xE8A7, // <cjk>
- 0x9698,0xE8A5, // <cjk>
- 0x9699,0x8C84, // <cjk>
- 0x969B,0x8DDB, // <cjk>
- 0x969C,0x8FE1, // <cjk>
- 0x96A0,0x8942, // <cjk>
- 0x96A3,0x97D7, // <cjk>
- 0x96A7,0xE8A9, // <cjk>
- 0x96A8,0xE7AC, // <cjk>
- 0x96AA,0xE8A8, // <cjk>
- 0x96B0,0xE8AC, // <cjk>
- 0x96B1,0xE8AA, // <cjk>
- 0x96B2,0xE8AB, // <cjk>
- 0x96B4,0xE8AD, // <cjk>
- 0x96B6,0xE8AE, // <cjk>
- 0x96B7,0x97EA, // <cjk>
- 0x96B8,0xE8AF, // <cjk>
- 0x96B9,0xE8B0, // <cjk>
- 0x96BB,0x90C7, // <cjk>
- 0x96BC,0x94B9, // <cjk>
- 0x96C0,0x909D, // <cjk>
- 0x96C1,0x8AE5, // <cjk>
- 0x96C4,0x9759, // <cjk>
- 0x96C5,0x89EB, // <cjk>
- 0x96C6,0x8F57, // <cjk>
- 0x96C7,0x8CD9, // <cjk>
- 0x96C9,0xE8B3, // <cjk>
- 0x96CB,0xE8B2, // <cjk>
- 0x96CC,0x8E93, // <cjk>
- 0x96CD,0xE8B4, // <cjk>
- 0x96CE,0xE8B1, // <cjk>
- 0x96D1,0x8E47, // <cjk>
- 0x96D5,0xE8B8, // <cjk>
- 0x96D6,0xE5AB, // <cjk>
- 0x96D9,0x99D4, // <cjk>
- 0x96DB,0x9097, // <cjk>
- 0x96DC,0xE8B6, // <cjk>
- 0x96E2,0x97A3, // <cjk>
- 0x96E3,0x93EF, // <cjk>
- 0x96E8,0x894A, // <cjk>
- 0x96EA,0x90E1, // <cjk>
- 0x96EB,0x8EB4, // <cjk>
- 0x96F0,0x95B5, // <cjk>
- 0x96F2,0x895F, // <cjk>
- 0x96F6,0x97EB, // <cjk>
- 0x96F7,0x978B, // <cjk>
- 0x96F9,0xE8B9, // <cjk>
- 0x96FB,0x9364, // <cjk>
- 0x9700,0x8EF9, // <cjk>
- 0x9704,0xE8BA, // <cjk>
- 0x9706,0xE8BB, // <cjk>
- 0x9707,0x906B, // <cjk>
- 0x9708,0xE8BC, // <cjk>
- 0x970A,0x97EC, // <cjk>
- 0x970D,0xE8B7, // <cjk>
- 0x970E,0xE8BE, // <cjk>
- 0x970F,0xE8C0, // <cjk>
- 0x9711,0xE8BF, // <cjk>
- 0x9713,0xE8BD, // <cjk>
- 0x9716,0xE8C1, // <cjk>
- 0x9719,0xE8C2, // <cjk>
- 0x971C,0x919A, // <cjk>
- 0x971E,0x89E0, // <cjk>
- 0x9724,0xE8C3, // <cjk>
- 0x9727,0x96B6, // <cjk>
- 0x972A,0xE8C4, // <cjk>
- 0x9730,0xE8C5, // <cjk>
- 0x9732,0x9849, // <cjk>
- 0x9738,0x9E50, // <cjk>
- 0x9739,0xE8C6, // <cjk>
- 0x973D,0xE8C7, // <cjk>
- 0x973E,0xE8C8, // <cjk>
- 0x9742,0xE8CC, // <cjk>
- 0x9744,0xE8C9, // <cjk>
- 0x9746,0xE8CA, // <cjk>
- 0x9748,0xE8CB, // <cjk>
- 0x9749,0xE8CD, // <cjk>
- 0x9752,0x90C2, // <cjk>
- 0x9756,0x96F5, // <cjk>
- 0x9759,0x90C3, // <cjk>
- 0x975C,0xE8CE, // <cjk>
- 0x975E,0x94F1, // <cjk>
- 0x9760,0xE8CF, // <cjk>
- 0x9761,0xEA72, // <cjk>
- 0x9762,0x96CA, // <cjk>
- 0x9764,0xE8D0, // <cjk>
- 0x9766,0xE8D1, // <cjk>
- 0x9768,0xE8D2, // <cjk>
- 0x9769,0x8A76, // <cjk>
- 0x976B,0xE8D4, // <cjk>
- 0x976D,0x9078, // <cjk>
- 0x9771,0xE8D5, // <cjk>
- 0x9774,0x8C43, // <cjk>
- 0x9779,0xE8D6, // <cjk>
- 0x977A,0xE8DA, // <cjk>
- 0x977C,0xE8D8, // <cjk>
- 0x9781,0xE8D9, // <cjk>
- 0x9784,0x8A93, // <cjk>
- 0x9785,0xE8D7, // <cjk>
- 0x9786,0xE8DB, // <cjk>
- 0x978B,0xE8DC, // <cjk>
- 0x978D,0x88C6, // <cjk>
- 0x978F,0xE8DD, // <cjk>
- 0x9790,0xE8DE, // <cjk>
- 0x9798,0x8FE2, // <cjk>
- 0x979C,0xE8DF, // <cjk>
- 0x97A0,0x8B66, // <cjk>
- 0x97A3,0xE8E2, // <cjk>
- 0x97A6,0xE8E1, // <cjk>
- 0x97A8,0xE8E0, // <cjk>
- 0x97AB,0xE691, // <cjk>
- 0x97AD,0x95DA, // <cjk>
- 0x97B3,0xE8E3, // <cjk>
- 0x97B4,0xE8E4, // <cjk>
- 0x97C3,0xE8E5, // <cjk>
- 0x97C6,0xE8E6, // <cjk>
- 0x97C8,0xE8E7, // <cjk>
- 0x97CB,0xE8E8, // <cjk>
- 0x97D3,0x8AD8, // <cjk>
- 0x97DC,0xE8E9, // <cjk>
- 0x97ED,0xE8EA, // <cjk>
- 0x97EE,0x9442, // <cjk>
- 0x97F2,0xE8EC, // <cjk>
- 0x97F3,0x89B9, // <cjk>
- 0x97F5,0xE8EF, // <cjk>
- 0x97F6,0xE8EE, // <cjk>
- 0x97FB,0x8943, // <cjk>
- 0x97FF,0x8BBF, // <cjk>
- 0x9801,0x95C5, // <cjk>
- 0x9802,0x92B8, // <cjk>
- 0x9803,0x8DA0, // <cjk>
- 0x9805,0x8D80, // <cjk>
- 0x9806,0x8F87, // <cjk>
- 0x9808,0x907B, // <cjk>
- 0x980C,0xE8F1, // <cjk>
- 0x980F,0xE8F0, // <cjk>
- 0x9810,0x9761, // <cjk>
- 0x9811,0x8AE6, // <cjk>
- 0x9812,0x94D0, // <cjk>
- 0x9813,0x93DA, // <cjk>
- 0x9817,0x909C, // <cjk>
- 0x9818,0x97CC, // <cjk>
- 0x981A,0x8C7A, // <cjk>
- 0x9821,0xE8F4, // <cjk>
- 0x9824,0xE8F3, // <cjk>
- 0x982C,0x966A, // <cjk>
- 0x982D,0x93AA, // <cjk>
- 0x9834,0x896F, // <cjk>
- 0x9837,0xE8F5, // <cjk>
- 0x9838,0xE8F2, // <cjk>
- 0x983B,0x9570, // <cjk>
- 0x983C,0x978A, // <cjk>
- 0x983D,0xE8F6, // <cjk>
- 0x9846,0xE8F7, // <cjk>
- 0x984B,0xE8F9, // <cjk>
- 0x984C,0x91E8, // <cjk>
- 0x984D,0x8A7A, // <cjk>
- 0x984E,0x8A7B, // <cjk>
- 0x984F,0xE8F8, // <cjk>
- 0x9854,0x8AE7, // <cjk>
- 0x9855,0x8CB0, // <cjk>
- 0x9858,0x8AE8, // <cjk>
- 0x985B,0x935E, // <cjk>
- 0x985E,0x97DE, // <cjk>
- 0x9867,0x8CDA, // <cjk>
- 0x986B,0xE8FA, // <cjk>
- 0x986F,0xE8FB, // <cjk>
- 0x9870,0xE8FC, // <cjk>
- 0x9871,0xE940, // <cjk>
- 0x9873,0xE942, // <cjk>
- 0x9874,0xE941, // <cjk>
- 0x98A8,0x9597, // <cjk>
- 0x98AA,0xE943, // <cjk>
- 0x98AF,0xE944, // <cjk>
- 0x98B1,0xE945, // <cjk>
- 0x98B6,0xE946, // <cjk>
- 0x98C3,0xE948, // <cjk>
- 0x98C4,0xE947, // <cjk>
- 0x98C6,0xE949, // <cjk>
- 0x98DB,0x94F2, // <cjk>
- 0x98DC,0xE3CA, // <cjk>
- 0x98DF,0x9048, // <cjk>
- 0x98E2,0x8B51, // <cjk>
- 0x98E9,0xE94A, // <cjk>
- 0x98EB,0xE94B, // <cjk>
- 0x98ED,0x99AA, // <cjk>
- 0x98EE,0x9F5A, // <cjk>
- 0x98EF,0x94D1, // <cjk>
- 0x98F2,0x88F9, // <cjk>
- 0x98F4,0x88B9, // <cjk>
- 0x98FC,0x8E94, // <cjk>
- 0x98FD,0x964F, // <cjk>
- 0x98FE,0x8FFC, // <cjk>
- 0x9903,0xE94C, // <cjk>
- 0x9905,0x96DD, // <cjk>
- 0x9909,0xE94D, // <cjk>
- 0x990A,0x977B, // <cjk>
- 0x990C,0x8961, // <cjk>
- 0x9910,0x8E60, // <cjk>
- 0x9912,0xE94E, // <cjk>
- 0x9913,0x89EC, // <cjk>
- 0x9914,0xE94F, // <cjk>
- 0x9918,0xE950, // <cjk>
- 0x991D,0xE952, // <cjk>
- 0x991E,0xE953, // <cjk>
- 0x9920,0xE955, // <cjk>
- 0x9921,0xE951, // <cjk>
- 0x9924,0xE954, // <cjk>
- 0x9928,0x8AD9, // <cjk>
- 0x992C,0xE956, // <cjk>
- 0x992E,0xE957, // <cjk>
- 0x993D,0xE958, // <cjk>
- 0x993E,0xE959, // <cjk>
- 0x9942,0xE95A, // <cjk>
- 0x9945,0xE95C, // <cjk>
- 0x994B,0xE95E, // <cjk>
- 0x994C,0xE961, // <cjk>
- 0x9950,0xE95D, // <cjk>
- 0x9951,0xE95F, // <cjk>
- 0x9952,0xE960, // <cjk>
- 0x9955,0xE962, // <cjk>
- 0x9957,0x8BC0, // <cjk>
- 0x9996,0x8EF1, // <cjk>
- 0x9997,0xE963, // <cjk>
- 0x9998,0xE964, // <cjk>
- 0x9999,0x8D81, // <cjk>
- 0x99A5,0xE965, // <cjk>
- 0x99A8,0x8A5D, // <cjk>
- 0x99AC,0x946E, // <cjk>
- 0x99AD,0xE966, // <cjk>
- 0x99AE,0xE967, // <cjk>
- 0x99B3,0x9279, // <cjk>
- 0x99B4,0x93E9, // <cjk>
- 0x99BC,0xE968, // <cjk>
- 0x99C1,0x949D, // <cjk>
- 0x99C4,0x91CA, // <cjk>
- 0x99C5,0x8977, // <cjk>
- 0x99C6,0x8BEC, // <cjk>
- 0x99C8,0x8BED, // <cjk>
- 0x99D0,0x9293, // <cjk>
- 0x99D1,0xE96D, // <cjk>
- 0x99D2,0x8BEE, // <cjk>
- 0x99D5,0x89ED, // <cjk>
- 0x99D8,0xE96C, // <cjk>
- 0x99DB,0xE96A, // <cjk>
- 0x99DD,0xE96B, // <cjk>
- 0x99DF,0xE969, // <cjk>
- 0x99E2,0xE977, // <cjk>
- 0x99ED,0xE96E, // <cjk>
- 0x99EE,0xE96F, // <cjk>
- 0x99F1,0xE970, // <cjk>
- 0x99F2,0xE971, // <cjk>
- 0x99F8,0xE973, // <cjk>
- 0x99FB,0xE972, // <cjk>
- 0x99FF,0x8F78, // <cjk>
- 0x9A01,0xE974, // <cjk>
- 0x9A05,0xE976, // <cjk>
- 0x9A0E,0x8B52, // <cjk>
- 0x9A0F,0xE975, // <cjk>
- 0x9A12,0x919B, // <cjk>
- 0x9A13,0x8CB1, // <cjk>
- 0x9A19,0xE978, // <cjk>
- 0x9A28,0x91CB, // <cjk>
- 0x9A2B,0xE979, // <cjk>
- 0x9A30,0x93AB, // <cjk>
- 0x9A37,0xE97A, // <cjk>
- 0x9A3E,0xE980, // <cjk>
- 0x9A40,0xE97D, // <cjk>
- 0x9A42,0xE97C, // <cjk>
- 0x9A43,0xE97E, // <cjk>
- 0x9A45,0xE97B, // <cjk>
- 0x9A4D,0xE982, // <cjk>
- 0x9A55,0xE981, // <cjk>
- 0x9A57,0xE984, // <cjk>
- 0x9A5A,0x8BC1, // <cjk>
- 0x9A5B,0xE983, // <cjk>
- 0x9A5F,0xE985, // <cjk>
- 0x9A62,0xE986, // <cjk>
- 0x9A64,0xE988, // <cjk>
- 0x9A65,0xE987, // <cjk>
- 0x9A69,0xE989, // <cjk>
- 0x9A6A,0xE98B, // <cjk>
- 0x9A6B,0xE98A, // <cjk>
- 0x9AA8,0x8D9C, // <cjk>
- 0x9AAD,0xE98C, // <cjk>
- 0x9AB0,0xE98D, // <cjk>
- 0x9ABC,0xE98E, // <cjk>
- 0x9AC0,0xE98F, // <cjk>
- 0x9AC4,0x9091, // <cjk>
- 0x9ACF,0xE990, // <cjk>
- 0x9AD1,0xE991, // <cjk>
- 0x9AD3,0xE992, // <cjk>
- 0x9AD4,0xE993, // <cjk>
- 0x9AD8,0x8D82, // <cjk>
- 0x9ADE,0xE994, // <cjk>
- 0x9ADF,0xE995, // <cjk>
- 0x9AE2,0xE996, // <cjk>
- 0x9AE3,0xE997, // <cjk>
- 0x9AE6,0xE998, // <cjk>
- 0x9AEA,0x94AF, // <cjk>
- 0x9AEB,0xE99A, // <cjk>
- 0x9AED,0x9545, // <cjk>
- 0x9AEE,0xE99B, // <cjk>
- 0x9AEF,0xE999, // <cjk>
- 0x9AF1,0xE99D, // <cjk>
- 0x9AF4,0xE99C, // <cjk>
- 0x9AF7,0xE99E, // <cjk>
- 0x9AFB,0xE99F, // <cjk>
- 0x9B06,0xE9A0, // <cjk>
- 0x9B18,0xE9A1, // <cjk>
- 0x9B1A,0xE9A2, // <cjk>
- 0x9B1F,0xE9A3, // <cjk>
- 0x9B22,0xE9A4, // <cjk>
- 0x9B23,0xE9A5, // <cjk>
- 0x9B25,0xE9A6, // <cjk>
- 0x9B27,0xE9A7, // <cjk>
- 0x9B28,0xE9A8, // <cjk>
- 0x9B29,0xE9A9, // <cjk>
- 0x9B2A,0xE9AA, // <cjk>
- 0x9B2E,0xE9AB, // <cjk>
- 0x9B2F,0xE9AC, // <cjk>
- 0x9B31,0x9F54, // <cjk>
- 0x9B32,0xE9AD, // <cjk>
- 0x9B3B,0xE2F6, // <cjk>
- 0x9B3C,0x8B53, // <cjk>
- 0x9B41,0x8A40, // <cjk>
- 0x9B42,0x8DB0, // <cjk>
- 0x9B43,0xE9AF, // <cjk>
- 0x9B44,0xE9AE, // <cjk>
- 0x9B45,0x96A3, // <cjk>
- 0x9B4D,0xE9B1, // <cjk>
- 0x9B4E,0xE9B2, // <cjk>
- 0x9B4F,0xE9B0, // <cjk>
- 0x9B51,0xE9B3, // <cjk>
- 0x9B54,0x9682, // <cjk>
- 0x9B58,0xE9B4, // <cjk>
- 0x9B5A,0x8B9B, // <cjk>
- 0x9B6F,0x9844, // <cjk>
- 0x9B74,0xE9B5, // <cjk>
- 0x9B83,0xE9B7, // <cjk>
- 0x9B8E,0x88BC, // <cjk>
- 0x9B91,0xE9B8, // <cjk>
- 0x9B92,0x95A9, // <cjk>
- 0x9B93,0xE9B6, // <cjk>
- 0x9B96,0xE9B9, // <cjk>
- 0x9B97,0xE9BA, // <cjk>
- 0x9B9F,0xE9BB, // <cjk>
- 0x9BA0,0xE9BC, // <cjk>
- 0x9BA8,0xE9BD, // <cjk>
- 0x9BAA,0x968E, // <cjk>
- 0x9BAB,0x8E4C, // <cjk>
- 0x9BAD,0x8DF8, // <cjk>
- 0x9BAE,0x914E, // <cjk>
- 0x9BB4,0xE9BE, // <cjk>
- 0x9BB9,0xE9C1, // <cjk>
- 0x9BC0,0xE9BF, // <cjk>
- 0x9BC6,0xE9C2, // <cjk>
- 0x9BC9,0x8CEF, // <cjk>
- 0x9BCA,0xE9C0, // <cjk>
- 0x9BCF,0xE9C3, // <cjk>
- 0x9BD1,0xE9C4, // <cjk>
- 0x9BD2,0xE9C5, // <cjk>
- 0x9BD4,0xE9C9, // <cjk>
- 0x9BD6,0x8E49, // <cjk>
- 0x9BDB,0x91E2, // <cjk>
- 0x9BE1,0xE9CA, // <cjk>
- 0x9BE2,0xE9C7, // <cjk>
- 0x9BE3,0xE9C6, // <cjk>
- 0x9BE4,0xE9C8, // <cjk>
- 0x9BE8,0x8C7E, // <cjk>
- 0x9BF0,0xE9CE, // <cjk>
- 0x9BF1,0xE9CD, // <cjk>
- 0x9BF2,0xE9CC, // <cjk>
- 0x9BF5,0x88B1, // <cjk>
- 0x9C04,0xE9D8, // <cjk>
- 0x9C06,0xE9D4, // <cjk>
- 0x9C08,0xE9D5, // <cjk>
- 0x9C09,0xE9D1, // <cjk>
- 0x9C0A,0xE9D7, // <cjk>
- 0x9C0C,0xE9D3, // <cjk>
- 0x9C0D,0x8A82, // <cjk>
- 0x9C10,0x986B, // <cjk>
- 0x9C12,0xE9D6, // <cjk>
- 0x9C13,0xE9D2, // <cjk>
- 0x9C14,0xE9D0, // <cjk>
- 0x9C15,0xE9CF, // <cjk>
- 0x9C1B,0xE9DA, // <cjk>
- 0x9C21,0xE9DD, // <cjk>
- 0x9C24,0xE9DC, // <cjk>
- 0x9C25,0xE9DB, // <cjk>
- 0x9C2D,0x9568, // <cjk>
- 0x9C2E,0xE9D9, // <cjk>
- 0x9C2F,0x88F1, // <cjk>
- 0x9C30,0xE9DE, // <cjk>
- 0x9C32,0xE9E0, // <cjk>
- 0x9C39,0x8A8F, // <cjk>
- 0x9C3A,0xE9CB, // <cjk>
- 0x9C3B,0x8956, // <cjk>
- 0x9C3E,0xE9E2, // <cjk>
- 0x9C46,0xE9E1, // <cjk>
- 0x9C47,0xE9DF, // <cjk>
- 0x9C48,0x924C, // <cjk>
- 0x9C52,0x9690, // <cjk>
- 0x9C57,0x97D8, // <cjk>
- 0x9C5A,0xE9E3, // <cjk>
- 0x9C60,0xE9E4, // <cjk>
- 0x9C67,0xE9E5, // <cjk>
- 0x9C76,0xE9E6, // <cjk>
- 0x9C78,0xE9E7, // <cjk>
- 0x9CE5,0x92B9, // <cjk>
- 0x9CE7,0xE9E8, // <cjk>
- 0x9CE9,0x94B5, // <cjk>
- 0x9CEB,0xE9ED, // <cjk>
- 0x9CEC,0xE9E9, // <cjk>
- 0x9CF0,0xE9EA, // <cjk>
- 0x9CF3,0x9650, // <cjk>
- 0x9CF4,0x96C2, // <cjk>
- 0x9CF6,0x93CE, // <cjk>
- 0x9D03,0xE9EE, // <cjk>
- 0x9D06,0xE9EF, // <cjk>
- 0x9D07,0x93BC, // <cjk>
- 0x9D08,0xE9EC, // <cjk>
- 0x9D09,0xE9EB, // <cjk>
- 0x9D0E,0x89A8, // <cjk>
- 0x9D12,0xE9F7, // <cjk>
- 0x9D15,0xE9F6, // <cjk>
- 0x9D1B,0x8995, // <cjk>
- 0x9D1F,0xE9F4, // <cjk>
- 0x9D23,0xE9F3, // <cjk>
- 0x9D26,0xE9F1, // <cjk>
- 0x9D28,0x8A9B, // <cjk>
- 0x9D2A,0xE9F0, // <cjk>
- 0x9D2B,0x8EB0, // <cjk>
- 0x9D2C,0x89A7, // <cjk>
- 0x9D3B,0x8D83, // <cjk>
- 0x9D3E,0xE9FA, // <cjk>
- 0x9D3F,0xE9F9, // <cjk>
- 0x9D41,0xE9F8, // <cjk>
- 0x9D44,0xE9F5, // <cjk>
- 0x9D46,0xE9FB, // <cjk>
- 0x9D48,0xE9FC, // <cjk>
- 0x9D50,0xEA44, // <cjk>
- 0x9D51,0xEA43, // <cjk>
- 0x9D59,0xEA45, // <cjk>
- 0x9D5C,0x894C, // <cjk>
- 0x9D5D,0xEA40, // <cjk>
- 0x9D5E,0xEA41, // <cjk>
- 0x9D60,0x8D94, // <cjk>
- 0x9D61,0x96B7, // <cjk>
- 0x9D64,0xEA42, // <cjk>
- 0x9D6C,0x9651, // <cjk>
- 0x9D6F,0xEA4A, // <cjk>
- 0x9D72,0xEA46, // <cjk>
- 0x9D7A,0xEA4B, // <cjk>
- 0x9D87,0xEA48, // <cjk>
- 0x9D89,0xEA47, // <cjk>
- 0x9D8F,0x8C7B, // <cjk>
- 0x9D9A,0xEA4C, // <cjk>
- 0x9DA4,0xEA4D, // <cjk>
- 0x9DA9,0xEA4E, // <cjk>
- 0x9DAB,0xEA49, // <cjk>
- 0x9DAF,0xE9F2, // <cjk>
- 0x9DB2,0xEA4F, // <cjk>
- 0x9DB4,0x92DF, // <cjk>
- 0x9DB8,0xEA53, // <cjk>
- 0x9DBA,0xEA54, // <cjk>
- 0x9DBB,0xEA52, // <cjk>
- 0x9DC1,0xEA51, // <cjk>
- 0x9DC2,0xEA57, // <cjk>
- 0x9DC4,0xEA50, // <cjk>
- 0x9DC6,0xEA55, // <cjk>
- 0x9DCF,0xEA56, // <cjk>
- 0x9DD3,0xEA59, // <cjk>
- 0x9DD9,0xEA58, // <cjk>
- 0x9DED,0xEA5C, // <cjk>
- 0x9DEF,0xEA5D, // <cjk>
- 0x9DF2,0x9868, // <cjk>
- 0x9DF8,0xEA5A, // <cjk>
- 0x9DF9,0x91E9, // <cjk>
- 0x9DFA,0x8DEB, // <cjk>
- 0x9DFD,0xEA5E, // <cjk>
- 0x9E1A,0xEA5F, // <cjk>
- 0x9E1B,0xEA60, // <cjk>
- 0x9E1E,0xEA61, // <cjk>
- 0x9E75,0xEA62, // <cjk>
- 0x9E78,0x8CB2, // <cjk>
- 0x9E79,0xEA63, // <cjk>
- 0x9E7D,0xEA64, // <cjk>
- 0x9E7F,0x8EAD, // <cjk>
- 0x9E81,0xEA65, // <cjk>
- 0x9E88,0xEA66, // <cjk>
- 0x9E8B,0xEA67, // <cjk>
- 0x9E8C,0xEA68, // <cjk>
- 0x9E91,0xEA6B, // <cjk>
- 0x9E92,0xEA69, // <cjk>
- 0x9E95,0xEA6A, // <cjk>
- 0x9E97,0x97ED, // <cjk>
- 0x9E9D,0xEA6C, // <cjk>
- 0x9E9F,0x97D9, // <cjk>
- 0x9EA5,0xEA6D, // <cjk>
- 0x9EA6,0x949E, // <cjk>
- 0x9EA9,0xEA6E, // <cjk>
- 0x9EAA,0xEA70, // <cjk>
- 0x9EAD,0xEA71, // <cjk>
- 0x9EB8,0xEA6F, // <cjk>
- 0x9EB9,0x8D8D, // <cjk>
- 0x9EBA,0x96CB, // <cjk>
- 0x9EBB,0x9683, // <cjk>
- 0x9EBC,0x9BF5, // <cjk>
- 0x9EBE,0x9F80, // <cjk>
- 0x9EBF,0x969B, // <cjk>
- 0x9EC4,0x89A9, // <cjk>
- 0x9ECC,0xEA73, // <cjk>
- 0x9ECD,0x8B6F, // <cjk>
- 0x9ECE,0xEA74, // <cjk>
- 0x9ECF,0xEA75, // <cjk>
- 0x9ED0,0xEA76, // <cjk>
- 0x9ED2,0x8D95, // <cjk>
- 0x9ED4,0xEA77, // <cjk>
- 0x9ED8,0xE0D2, // <cjk>
- 0x9ED9,0x96D9, // <cjk>
- 0x9EDB,0x91E1, // <cjk>
- 0x9EDC,0xEA78, // <cjk>
- 0x9EDD,0xEA7A, // <cjk>
- 0x9EDE,0xEA79, // <cjk>
- 0x9EE0,0xEA7B, // <cjk>
- 0x9EE5,0xEA7C, // <cjk>
- 0x9EE8,0xEA7D, // <cjk>
- 0x9EEF,0xEA7E, // <cjk>
- 0x9EF4,0xEA80, // <cjk>
- 0x9EF6,0xEA81, // <cjk>
- 0x9EF7,0xEA82, // <cjk>
- 0x9EF9,0xEA83, // <cjk>
- 0x9EFB,0xEA84, // <cjk>
- 0x9EFC,0xEA85, // <cjk>
- 0x9EFD,0xEA86, // <cjk>
- 0x9F07,0xEA87, // <cjk>
- 0x9F08,0xEA88, // <cjk>
- 0x9F0E,0x9343, // <cjk>
- 0x9F13,0x8CDB, // <cjk>
- 0x9F15,0xEA8A, // <cjk>
- 0x9F20,0x916C, // <cjk>
- 0x9F21,0xEA8B, // <cjk>
- 0x9F2C,0xEA8C, // <cjk>
- 0x9F3B,0x9540, // <cjk>
- 0x9F3E,0xEA8D, // <cjk>
- 0x9F4A,0xEA8E, // <cjk>
- 0x9F4B,0xE256, // <cjk>
- 0x9F4E,0xE6D8, // <cjk>
- 0x9F4F,0xE8EB, // <cjk>
- 0x9F52,0xEA8F, // <cjk>
- 0x9F54,0xEA90, // <cjk>
- 0x9F5F,0xEA92, // <cjk>
- 0x9F60,0xEA93, // <cjk>
- 0x9F61,0xEA94, // <cjk>
- 0x9F62,0x97EE, // <cjk>
- 0x9F63,0xEA91, // <cjk>
- 0x9F66,0xEA95, // <cjk>
- 0x9F67,0xEA96, // <cjk>
- 0x9F6A,0xEA98, // <cjk>
- 0x9F6C,0xEA97, // <cjk>
- 0x9F72,0xEA9A, // <cjk>
- 0x9F76,0xEA9B, // <cjk>
- 0x9F77,0xEA99, // <cjk>
- 0x9F8D,0x97B4, // <cjk>
- 0x9F95,0xEA9C, // <cjk>
- 0x9F9C,0xEA9D, // <cjk>
- 0x9F9D,0xE273, // <cjk>
- 0x9FA0,0xEA9E, // <cjk>
- 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
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+INTERNAL int sjis_wctomb_zint(unsigned int* r, unsigned int wc);
+INTERNAL int sjis_utf8tomb(struct zint_symbol *symbol, const unsigned char source[], size_t* p_length, unsigned int* jisdata);
+INTERNAL int sjis_utf8tosb(int eci, const unsigned char source[], size_t* p_length, unsigned int* jisdata, int full_multibyte);
+INTERNAL void sjis_cpy(const unsigned char source[], size_t* p_length, unsigned int* jisdata, int full_multibyte);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SJIS_H */
diff --git a/backend/stdint_msvc.h b/backend/stdint_msvc.h
new file mode 100644
index 0000000..2d7c82d
--- /dev/null
+++ b/backend/stdint_msvc.h
@@ -0,0 +1,54 @@
+/* stdint_msvc.h - definitions for libzint
+
+ libzint - the open source barcode library
+ Copyright (C) 2009-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+
+#ifndef STDINT_MSVC_H
+#define STDINT_MSVC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifdef _MSC_VER
+
+typedef BYTE uint8_t;
+typedef WORD uint16_t;
+typedef DWORD uint32_t;
+typedef INT32 int32_t;
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* STDINT_MSVC_H */
+
+
diff --git a/backend/svg.c b/backend/svg.c
new file mode 100644
index 0000000..98cca3d
--- /dev/null
+++ b/backend/svg.c
@@ -0,0 +1,248 @@
+/* svg.c - Scalable Vector Graphics */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2009 - 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <locale.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+
+#include "common.h"
+
+void pick_colour(int colour, char colour_code[]) {
+ switch(colour) {
+ case 0: // White
+ strcpy(colour_code, "ffffff");
+ break;
+ case 1: // Cyan
+ strcpy(colour_code, "00ffff");
+ break;
+ case 2: // Blue
+ strcpy(colour_code, "0000ff");
+ break;
+ case 3: // Magenta
+ strcpy(colour_code, "ff00ff");
+ break;
+ case 4: // Red
+ strcpy(colour_code, "ff0000");
+ break;
+ case 5: // Yellow
+ strcpy(colour_code, "ffff00");
+ break;
+ case 6: // Green
+ strcpy(colour_code, "00ff00");
+ break;
+ default: // Black
+ strcpy(colour_code, "000000");
+ break;
+ }
+}
+
+static void make_html_friendly(unsigned char * string, char * html_version) {
+ /* Converts text to use HTML entity codes */
+
+ int i, html_pos;
+
+ html_pos = 0;
+ html_version[html_pos] = '\0';
+
+ for (i = 0; i < (int) ustrlen(string); i++) {
+ switch(string[i]) {
+ case '>':
+ strcat(html_version, "&gt;");
+ html_pos += 4;
+ break;
+
+ case '<':
+ strcat(html_version, "&lt;");
+ html_pos += 4;
+ break;
+
+ case '&':
+ strcat(html_version, "&amp;");
+ html_pos += 5;
+ break;
+
+ case '"':
+ strcat(html_version, "&quot;");
+ html_pos += 6;
+ break;
+
+ case '\'':
+ strcat(html_version, "&apos;");
+ html_pos += 6;
+ break;
+
+ default:
+ html_version[html_pos] = string[i];
+ html_pos++;
+ html_version[html_pos] = '\0';
+ break;
+ }
+ }
+}
+
+INTERNAL int svg_plot(struct zint_symbol *symbol) {
+ FILE *fsvg;
+ int error_number = 0;
+ const char *locale = NULL;
+ float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy;
+ float radius;
+ int i;
+
+ struct zint_vector_rect *rect;
+ struct zint_vector_hexagon *hex;
+ struct zint_vector_circle *circle;
+ struct zint_vector_string *string;
+
+ char colour_code[7];
+
+#ifdef _MSC_VER
+ char* html_string;
+#endif
+
+ int html_len = strlen((char *)symbol->text) + 1;
+
+ for (i = 0; i < (int) strlen((char *)symbol->text); i++) {
+ switch(symbol->text[i]) {
+ case '>':
+ case '<':
+ case '"':
+ case '&':
+ case '\'':
+ html_len += 6;
+ break;
+ }
+ }
+
+#ifndef _MSC_VER
+ char html_string[html_len];
+#else
+ html_string = (char*) _alloca(html_len);
+#endif
+
+ /* Check for no created vector set */
+ /* E-Mail Christian Schmitz 2019-09-10: reason unknown Ticket #164*/
+ if (symbol->vector == NULL) {
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ if (symbol->output_options & BARCODE_STDOUT) {
+ fsvg = stdout;
+ } else {
+ fsvg = fopen(symbol->outfile, "w");
+ }
+ if (fsvg == NULL) {
+ strcpy(symbol->errtxt, "660: Could not open output file");
+ return ZINT_ERROR_FILE_ACCESS;
+ }
+
+ locale = setlocale(LC_ALL, "C");
+
+ /* Start writing the header */
+ fprintf(fsvg, "<?xml version=\"1.0\" standalone=\"no\"?>\n");
+ fprintf(fsvg, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n");
+ fprintf(fsvg, " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
+ fprintf(fsvg, "<svg width=\"%d\" height=\"%d\" version=\"1.1\"\n", (int) ceil(symbol->vector->width), (int) ceil(symbol->vector->height));
+ fprintf(fsvg, " xmlns=\"http://www.w3.org/2000/svg\">\n");
+ fprintf(fsvg, " <desc>Zint Generated Symbol\n");
+ fprintf(fsvg, " </desc>\n");
+ fprintf(fsvg, "\n <g id=\"barcode\" fill=\"#%s\">\n", symbol->fgcolour);
+
+ fprintf(fsvg, " <rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\" fill=\"#%s\" />\n", (int) ceil(symbol->vector->width), (int) ceil(symbol->vector->height), symbol->bgcolour);
+
+ rect = symbol->vector->rectangles;
+ while (rect) {
+ if (rect->colour == -1) {
+ fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" />\n", rect->x, rect->y, rect->width, rect->height);
+ } else {
+ pick_colour(rect->colour, colour_code);
+ fprintf(fsvg, " <rect x=\"%.2f\" y=\"%.2f\" width=\"%.2f\" height=\"%.2f\" fill=\"#%s\" />\n", rect->x, rect->y, rect->width, rect->height, colour_code);
+ }
+ rect = rect->next;
+ }
+
+ hex = symbol->vector->hexagons;
+ while (hex) {
+ radius = hex->diameter / 2.0;
+ ay = hex->y + (1.0 * radius);
+ by = hex->y + (0.5 * radius);
+ cy = hex->y - (0.5 * radius);
+ dy = hex->y - (1.0 * radius);
+ ey = hex->y - (0.5 * radius);
+ fy = hex->y + (0.5 * radius);
+ ax = hex->x;
+ bx = hex->x + (0.86 * radius);
+ cx = hex->x + (0.86 * radius);
+ dx = hex->x;
+ ex = hex->x - (0.86 * radius);
+ fx = hex->x - (0.86 * radius);
+ fprintf(fsvg, " <path d=\"M %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f L %.2f %.2f Z\" />\n", ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy);
+ hex = hex->next;
+ }
+
+ circle = symbol->vector->circles;
+ while (circle) {
+ if (circle->colour) {
+ fprintf(fsvg, " <circle cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\" fill=\"#%s\" />\n", circle->x, circle->y, circle->diameter / 2.0, symbol->bgcolour);
+ } else {
+ fprintf(fsvg, " <circle cx=\"%.2f\" cy=\"%.2f\" r=\"%.2f\" fill=\"#%s\" />\n", circle->x, circle->y, circle->diameter / 2.0, symbol->fgcolour);
+ }
+ circle = circle->next;
+ }
+
+ string = symbol->vector->strings;
+ while (string) {
+ fprintf(fsvg, " <text x=\"%.2f\" y=\"%.2f\" text-anchor=\"middle\"\n", string->x, string->y);
+ fprintf(fsvg, " font-family=\"Helvetica\" font-size=\"%.1f\" fill=\"#%s\" >\n", string->fsize, symbol->fgcolour);
+ make_html_friendly(string->text, html_string);
+ fprintf(fsvg, " %s\n", html_string);
+ fprintf(fsvg, " </text>\n");
+ string = string->next;
+ }
+
+ fprintf(fsvg, " </g>\n");
+ fprintf(fsvg, "</svg>\n");
+
+ if (symbol->output_options & BARCODE_STDOUT) {
+ fflush(fsvg);
+ } else {
+ 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 0000000..9db20b9
--- /dev/null
+++ b/backend/telepen.c
@@ -0,0 +1,168 @@
+/* telepen.c - Handles Telepen and Telepen numeric */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2008-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+/* Telepen Barcode Symbology information and History (BSiH) https://telepen.co.uk/wp-content/uploads/2018/10/Barcode-Symbology-information-and-History.pdf */
+
+#define SODIUM "0123456789X"
+
+#include <stdio.h>
+#include "common.h"
+
+static char *TeleTable[] = {
+ "31313131", "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", "1111111111111111",
+};
+
+INTERNAL int telepen(struct zint_symbol *symbol, unsigned char source[], const size_t src_len) {
+ unsigned int i, count, check_digit;
+ int error_number;
+ char dest[521]; /* 12 (start) + 30 * 16 (max for DELs) + 16 (check digit) + 12 (stop) + 1 = 521 */
+
+ error_number = 0;
+
+ count = 0;
+
+ if (src_len > 30) {
+ strcpy(symbol->errtxt, "390: Input too long");
+ return ZINT_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, "391: Invalid characters in input data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ strcat(dest, TeleTable[source[i]]);
+ count += source[i];
+ }
+
+ check_digit = 127 - (count % 127);
+ if (check_digit == 127) {
+ check_digit = 0;
+ }
+ strcat(dest, TeleTable[check_digit]);
+
+ /* Stop character */
+ strcat(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;
+}
+
+INTERNAL int telepen_num(struct zint_symbol *symbol, unsigned char source[], const size_t src_len) {
+ unsigned int count, check_digit, glyph;
+ int error_number;
+ size_t i, temp_length = src_len;
+ char dest[521]; /* 12 (start) + 30 * 16 (max for DELs) + 16 (check digit) + 12 (stop) + 1 = 521 */
+ unsigned char temp[64];
+
+ count = 0;
+
+ if (temp_length > 60) {
+ strcpy(symbol->errtxt, "392: Input too long");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ ustrcpy(temp, source);
+ to_upper(temp);
+ error_number = is_sane(SODIUM, temp, temp_length);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "393: Invalid characters in data");
+ return error_number;
+ }
+
+ /* Add a leading zero if required */
+ if (temp_length & 1) {
+ 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, "394: Invalid position of X in Telepen data");
+ return ZINT_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;
+ }
+ strcat(dest, TeleTable[glyph]);
+ }
+
+ check_digit = 127 - (count % 127);
+ if (check_digit == 127) {
+ check_digit = 0;
+ }
+ strcat(dest, TeleTable[check_digit]);
+
+ /* Stop character */
+ strcat(dest, TeleTable['z']);
+
+ expand(symbol, dest);
+ ustrcpy(symbol->text, temp);
+ return error_number;
+}
diff --git a/backend/tif.c b/backend/tif.c
new file mode 100644
index 0000000..0e29691
--- /dev/null
+++ b/backend/tif.c
@@ -0,0 +1,346 @@
+/* tif.c - Aldus Tagged Image File Format support */
+/* TIFF Revision 6.0 https://www.adobe.io/content/dam/udp/en/open/standards/tiff/TIFF6.pdf */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2016 - 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <stdio.h>
+#include <math.h>
+#include <assert.h>
+#include "common.h"
+#include "tif.h"
+#ifdef _MSC_VER
+#include <io.h>
+#include <fcntl.h>
+#include <malloc.h>
+#endif
+
+INTERNAL int tif_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
+ int fgred, fggrn, fgblu, bgred, bggrn, bgblu;
+ int i;
+ int rows_per_strip, strip_count;
+ unsigned int free_memory;
+ int row, column, strip;
+ unsigned int bytes_put;
+ FILE *tif_file;
+#ifdef _MSC_VER
+ uint32_t* strip_offset;
+ uint32_t* strip_bytes;
+#endif
+
+ tiff_header_t header;
+ tiff_ifd_t ifd;
+ uint16_t temp;
+ uint32_t temp32;
+
+ 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]);
+
+ /* TIFF Rev 6 Section 7 p.27 "Set RowsPerStrip such that the size of each strip is about 8K bytes...
+ * Note that extremely wide high resolution images may have rows larger than 8K bytes; in this case,
+ * RowsPerStrip should be 1, and the strip will be larger than 8K." */
+ rows_per_strip = 8192 / (symbol->bitmap_width * 3);
+ if (rows_per_strip == 0) {
+ rows_per_strip = 1;
+ }
+
+ /* Suppresses clang-tidy clang-analyzer-core.VLASize warning */
+ assert(symbol->bitmap_height > 0);
+
+ strip_count = symbol->bitmap_height / rows_per_strip;
+ if ((symbol->bitmap_height % rows_per_strip) != 0) {
+ strip_count++;
+ }
+
+ if (rows_per_strip > symbol->bitmap_height) {
+ rows_per_strip = symbol->bitmap_height;
+ }
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("TIFF (%dx%d) Strip Count %d, Rows Per Strip %d\n", symbol->bitmap_width, symbol->bitmap_height, strip_count, rows_per_strip);
+ }
+
+#ifndef _MSC_VER
+ uint32_t strip_offset[strip_count];
+ uint32_t strip_bytes[strip_count];
+#else
+ strip_offset = (uint32_t*) _alloca(strip_count * sizeof(uint32_t));
+ strip_bytes = (uint32_t*) _alloca(strip_count * sizeof(uint32_t));
+#endif
+ free_memory = 8;
+
+ for(i = 0; i < strip_count; i++) {
+ strip_offset[i] = free_memory;
+ if (i != (strip_count - 1)) {
+ strip_bytes[i] = rows_per_strip * symbol->bitmap_width * 3;
+ } else {
+ if ((symbol->bitmap_height % rows_per_strip) != 0) {
+ strip_bytes[i] = (symbol->bitmap_height % rows_per_strip) * symbol->bitmap_width * 3;
+ } else {
+ strip_bytes[i] = rows_per_strip * symbol->bitmap_width * 3;
+ }
+ }
+ free_memory += strip_bytes[i];
+ if ((free_memory % 2) == 1) {
+ free_memory++;
+ }
+ }
+
+ if (free_memory > 0xffff0000) {
+ strcpy(symbol->errtxt, "670: Output file size too big");
+ return ZINT_ERROR_MEMORY;
+ }
+
+ /* Open output file in binary mode */
+ if (symbol->output_options & BARCODE_STDOUT) {
+#ifdef _MSC_VER
+ if (-1 == _setmode(_fileno(stdout), _O_BINARY)) {
+ strcpy(symbol->errtxt, "671: Can't open output file");
+ return ZINT_ERROR_FILE_ACCESS;
+ }
+#endif
+ tif_file = stdout;
+ } else {
+ if (!(tif_file = fopen(symbol->outfile, "wb"))) {
+ strcpy(symbol->errtxt, "672: Can't open output file");
+ return ZINT_ERROR_FILE_ACCESS;
+ }
+ }
+
+ /* Header */
+ header.byte_order = 0x4949;
+ header.identity = 42;
+ header.offset = free_memory;
+
+ fwrite(&header, sizeof(tiff_header_t), 1, tif_file);
+ free_memory += sizeof(tiff_ifd_t);
+
+ /* Pixel data */
+ strip = 0;
+ bytes_put = 0;
+ for (row = 0; row < symbol->bitmap_height; row++) {
+ for (column = 0; column < symbol->bitmap_width; column++) {
+ switch(pixelbuf[(row * symbol->bitmap_width) + column]) {
+ case 'W': // White
+ putc(255, tif_file);
+ putc(255, tif_file);
+ putc(255, tif_file);
+ break;
+ case 'C': // Cyan
+ putc(0, tif_file);
+ putc(255, tif_file);
+ putc(255, tif_file);
+ break;
+ case 'B': // Blue
+ putc(0, tif_file);
+ putc(0, tif_file);
+ putc(255, tif_file);
+ break;
+ case 'M': // Magenta
+ putc(255, tif_file);
+ putc(0, tif_file);
+ putc(255, tif_file);
+ break;
+ case 'R': // Red
+ putc(255, tif_file);
+ putc(0, tif_file);
+ putc(0, tif_file);
+ break;
+ case 'Y': // Yellow
+ putc(255, tif_file);
+ putc(255, tif_file);
+ putc(0, tif_file);
+ break;
+ case 'G': // Green
+ putc(0, tif_file);
+ putc(255, tif_file);
+ putc(0, tif_file);
+ break;
+ case 'K': // Black
+ putc(0, tif_file);
+ putc(0, tif_file);
+ putc(0, tif_file);
+ break;
+ case '1':
+ putc(fgred, tif_file);
+ putc(fggrn, tif_file);
+ putc(fgblu, tif_file);
+ break;
+ default:
+ putc(bgred, tif_file);
+ putc(bggrn, tif_file);
+ putc(bgblu, tif_file);
+ break;
+ }
+ bytes_put += 3;
+ }
+
+ if (strip < strip_count && (bytes_put + 3) >= strip_bytes[strip]) {
+ // End of strip, pad if strip length is odd
+ if (strip_bytes[strip] % 2 == 1) {
+ putc(0, tif_file);
+ }
+ strip++;
+ bytes_put = 0;
+ }
+ }
+
+ /* Image File Directory */
+ ifd.entries = 14;
+ ifd.offset = 0;
+
+ ifd.new_subset.tag = 0xfe;
+ ifd.new_subset.type = 4;
+ ifd.new_subset.count = 1;
+ ifd.new_subset.offset = 0;
+
+ ifd.image_width.tag = 0x0100;
+ ifd.image_width.type = 3; // SHORT
+ ifd.image_width.count = 1;
+ ifd.image_width.offset = symbol->bitmap_width;
+
+ ifd.image_length.tag = 0x0101;
+ ifd.image_length.type = 3; // SHORT
+ ifd.image_length.count = 1;
+ ifd.image_length.offset = symbol->bitmap_height;
+
+ ifd.bits_per_sample.tag = 0x0102;
+ ifd.bits_per_sample.type = 3; // SHORT
+ ifd.bits_per_sample.count = 3;
+ ifd.bits_per_sample.offset = free_memory;
+ free_memory += 6;
+
+ ifd.compression.tag = 0x0103;
+ ifd.compression.type = 3;
+ ifd.compression.count = 1;
+ ifd.compression.offset = 1; // Uncompressed
+
+ ifd.photometric.tag = 0x0106;
+ ifd.photometric.type = 3; // SHORT
+ ifd.photometric.count = 1;
+ ifd.photometric.offset = 2; // RGB Model
+
+ ifd.strip_offsets.tag = 0x0111;
+ ifd.strip_offsets.type = 4; // LONG
+ ifd.strip_offsets.count = strip_count;
+ if (strip_count == 1) {
+ ifd.strip_offsets.offset = strip_offset[0];
+ } else {
+ ifd.strip_offsets.offset = free_memory;
+ free_memory += strip_count * 4;
+ }
+
+ ifd.samples_per_pixel.tag = 0x0115;
+ ifd.samples_per_pixel.type = 3;
+ ifd.samples_per_pixel.count = 1;
+ ifd.samples_per_pixel.offset = 3;
+
+ ifd.rows_per_strip.tag = 0x0116;
+ ifd.rows_per_strip.type = 4;
+ ifd.rows_per_strip.count = 1;
+ ifd.rows_per_strip.offset = rows_per_strip;
+
+ ifd.strip_byte_counts.tag = 0x0117;
+ ifd.strip_byte_counts.type = 4;
+ ifd.strip_byte_counts.count = strip_count;
+ if (strip_count == 1) {
+ ifd.strip_byte_counts.offset = strip_bytes[0];
+ } else {
+ ifd.strip_byte_counts.offset = free_memory;
+ free_memory += strip_count * 4;
+ }
+
+ ifd.x_resolution.tag = 0x011a;
+ ifd.x_resolution.type = 5;
+ ifd.x_resolution.count = 1;
+ ifd.x_resolution.offset = free_memory;
+ free_memory += 8;
+
+ ifd.y_resolution.tag = 0x011b;
+ ifd.y_resolution.type = 5;
+ ifd.y_resolution.count = 1;
+ ifd.y_resolution.offset = free_memory;
+// free_memory += 8;
+
+ ifd.planar_config.tag = 0x11c;
+ ifd.planar_config.type = 3;
+ ifd.planar_config.count = 1;
+ ifd.planar_config.offset = 1;
+
+ ifd.resolution_unit.tag = 0x0128;
+ ifd.resolution_unit.type = 3;
+ ifd.resolution_unit.count = 1;
+ ifd.resolution_unit.offset = 2; // Inches
+
+ fwrite(&ifd, sizeof(tiff_ifd_t), 1, tif_file);
+
+ /* Bits per sample */
+ temp = 8;
+ fwrite(&temp, 2, 1, tif_file); // Red Bytes
+ fwrite(&temp, 2, 1, tif_file); // Green Bytes
+ fwrite(&temp, 2, 1, tif_file); // Blue Bytes
+
+ if (strip_count != 1) {
+ /* Strip offsets */
+ for (i = 0; i < strip_count; i++) {
+ fwrite(&strip_offset[i], 4, 1, tif_file);
+ }
+
+ /* Strip byte lengths */
+ for (i = 0; i < strip_count; i++) {
+ fwrite(&strip_bytes[i], 4, 1, tif_file);
+ }
+ }
+
+ /* X Resolution */
+ temp32 = 72;
+ fwrite(&temp32, 4, 1, tif_file);
+ temp32 = 1;
+ fwrite(&temp32, 4, 1, tif_file);
+
+ /* Y Resolution */
+ temp32 = 72;
+ fwrite(&temp32, 4, 1, tif_file);
+ temp32 = 1;
+ fwrite(&temp32, 4, 1, tif_file);
+
+ if (symbol->output_options & BARCODE_STDOUT) {
+ fflush(tif_file);
+ } else {
+ fclose(tif_file);
+ }
+
+ return 0;
+}
diff --git a/backend/tif.h b/backend/tif.h
new file mode 100644
index 0000000..3e3c459
--- /dev/null
+++ b/backend/tif.h
@@ -0,0 +1,88 @@
+/* tif.h - Aldus Tagged Image File Format */
+
+/*
+ libzint - the open source barcode library
+ Copyright (C) 2016-2017 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+#ifndef TIF_H
+#define TIF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef _MSC_VER
+#include <windows.h>
+#include "stdint_msvc.h"
+#else
+#include <stdint.h>
+#endif
+
+#pragma pack(1)
+
+ typedef struct tiff_header {
+ uint16_t byte_order;
+ uint16_t identity;
+ uint32_t offset;
+ } tiff_header_t;
+
+ typedef struct tiff_tag {
+ uint16_t tag;
+ uint16_t type;
+ uint32_t count;
+ uint32_t offset;
+ } tiff_tag_t;
+
+ typedef struct tiff_ifd {
+ uint16_t entries;
+ tiff_tag_t new_subset;
+ tiff_tag_t image_width;
+ tiff_tag_t image_length;
+ tiff_tag_t bits_per_sample;
+ tiff_tag_t compression;
+ tiff_tag_t photometric;
+ tiff_tag_t strip_offsets;
+ tiff_tag_t samples_per_pixel;
+ tiff_tag_t rows_per_strip;
+ tiff_tag_t strip_byte_counts;
+ tiff_tag_t x_resolution;
+ tiff_tag_t y_resolution;
+ tiff_tag_t planar_config;
+ tiff_tag_t resolution_unit;
+ uint32_t offset;
+ } tiff_ifd_t;
+
+#pragma pack()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TIF_H */
+
+
diff --git a/backend/ultra.c b/backend/ultra.c
new file mode 100644
index 0000000..58d0da8
--- /dev/null
+++ b/backend/ultra.c
@@ -0,0 +1,1115 @@
+/* ultra.c - Ultracode
+
+ libzint - the open source barcode library
+ Copyright (C) 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+ /* This version was developed using AIMD/TSC15032-43 v0.99c Edit 60, dated 4th Nov 2015 */
+
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+#include <stdio.h>
+#include "common.h"
+
+#define EIGHTBIT_MODE 10
+#define ASCII_MODE 20
+#define C43_MODE 30
+
+#define PREDICT_WINDOW 12
+
+#define GFMUL(i, j) ((((i) == 0)||((j) == 0)) ? 0 : gfPwr[(gfLog[i] + gfLog[j])])
+
+static const char fragment[27][14] = {"http://", "https://", "http://www.", "https://www.",
+ "ftp://", "www.", ".com", ".edu", ".gov", ".int", ".mil", ".net", ".org",
+ ".mobi", ".coop", ".biz", ".info", "mailto:", "tel:", ".cgi", ".asp",
+ ".aspx", ".php", ".htm", ".html", ".shtml", "file:"};
+
+static const char ultra_c43_set1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 .,%";
+static const char ultra_c43_set2[] = "abcdefghijklmnopqrstuvwxyz:/?#[]@=_~!.,-";
+static const char ultra_c43_set3[] = "{}`()\"+'<>|$;&\\^*";
+static const char ultra_digit[] = "0123456789,/";
+static const char ultra_colour[] = "WCBMRYGK";
+
+//static const int ultra_maxsize[] = {34, 78, 158, 282}; // According to Table 1
+static const int ultra_maxsize[] = {34, 81, 158, 282}; // Adjusted to allow 79-81 codeword range in 3-row symbols (only 1 secondary vertical clock track, not 2, so 3 extra)
+
+static const int ultra_mincols[] = {5, 13, 23, 30}; // # Total Tile Columns from Table 1
+
+static const int kec[] = {0, 1, 2, 4, 6, 8}; // Value K(EC) from Table 12
+
+static const int dccu[] = {
+ 051363, 051563, 051653, 053153, 053163, 053513, 053563, 053613, // 0-7
+ 053653, 056153, 056163, 056313, 056353, 056363, 056513, 056563, // 8-15
+ 051316, 051356, 051536, 051616, 053156, 053516, 053536, 053616, // 16-23
+ 053636, 053656, 056136, 056156, 056316, 056356, 056516, 056536 // 24-31
+};
+
+static const int dccl[] = {
+ 061351, 061361, 061531, 061561, 061631, 061651, 063131, 063151, // 0-7
+ 063161, 063531, 063561, 063631, 065131, 065161, 065351, 065631, // 8-15
+ 031351, 031361, 031531, 031561, 031631, 031651, 035131, 035151, // 16-23
+ 035161, 035361, 035631, 035651, 036131, 036151, 036351, 036531 // 24-31
+};
+
+static const int tiles[] = {
+ 013135, 013136, 013153, 013156, 013163, 013165, 013513, 013515, 013516, 013531, // 0-9
+ 013535, 013536, 013561, 013563, 013565, 013613, 013615, 013616, 013631, 013635, // 10-19
+ 013636, 013651, 013653, 013656, 015135, 015136, 015153, 015163, 015165, 015313, // 20-29
+ 015315, 015316, 015351, 015353, 015356, 015361, 015363, 015365, 015613, 015615, // 30-39
+ 015616, 015631, 015635, 015636, 015651, 015653, 015656, 016135, 016136, 016153, // 40-49
+ 016156, 016165, 016313, 016315, 016316, 016351, 016353, 016356, 016361, 016363, // 50-59
+ 016365, 016513, 016515, 016516, 016531, 016535, 016536, 016561, 016563, 016565, // 60-69
+ 031315, 031316, 031351, 031356, 031361, 031365, 031513, 031515, 031516, 031531, // 70-79
+ 031535, 031536, 031561, 031563, 031565, 031613, 031615, 031631, 031635, 031636, // 80-89
+ 031651, 031653, 031656, 035131, 035135, 035136, 035151, 035153, 035156, 035161, // 90-99
+ 035163, 035165, 035315, 035316, 035351, 035356, 035361, 035365, 035613, 035615, // 100-109
+ 035616, 035631, 035635, 035636, 035651, 035653, 035656, 036131, 036135, 036136, // 110-119
+ 036151, 036153, 036156, 036163, 036165, 036315, 036316, 036351, 036356, 036361, // 120-129
+ 036365, 036513, 036515, 036516, 036531, 036535, 036536, 036561, 036563, 036565, // 130-139
+ 051313, 051315, 051316, 051351, 051353, 051356, 051361, 051363, 051365, 051513, // 140-149
+ 051516, 051531, 051536, 051561, 051563, 051613, 051615, 051616, 051631, 051635, // 150-159
+ 051636, 051651, 051653, 051656, 053131, 053135, 053136, 053151, 053153, 053156, // 160-169
+ 053161, 053163, 053165, 053513, 053516, 053531, 053536, 053561, 053563, 053613, // 170-179
+ 053615, 053616, 053631, 053635, 053636, 053651, 053653, 053656, 056131, 056135, // 180-189
+ 056136, 056151, 056153, 056156, 056161, 056163, 056165, 056313, 056315, 056316, // 190-199
+ 056351, 056353, 056356, 056361, 056363, 056365, 056513, 056516, 056531, 056536, // 200-209
+ 056561, 056563, 061313, 061315, 061316, 061351, 061353, 061356, 061361, 061363, // 210-219
+ 061365, 061513, 061515, 061516, 061531, 061535, 061536, 061561, 061563, 061565, // 220-229
+ 061615, 061631, 061635, 061651, 061653, 063131, 063135, 063136, 063151, 063153, // 230-239
+ 063156, 063161, 063163, 063165, 063513, 063515, 063516, 063531, 063535, 063536, // 240-249
+ 063561, 063563, 063565, 063613, 063615, 063631, 063635, 063651, 063653, 065131, // 250-259
+ 065135, 065136, 065151, 065153, 065156, 065161, 065163, 065165, 065313, 065315, // 260-269
+ 065316, 065351, 065353, 065356, 065361, 065363, 065365, 065613, 065615, 065631, // 270-279
+ 065635, 065651, 065653, 056565, 051515 // 280-284
+};
+
+/* The following adapted from ECC283.C "RSEC codeword generator"
+ * from Annex B of Ultracode draft
+ * originally written by Ted Williams of Symbol Vision Corp.
+ * Dated 2001-03-09
+ * Corrected thanks to input from Terry Burton */
+
+/*
+ * NOTE: Included here is an attempt to allow code compression within Ultracode. Unfortunately
+ * the copy of the standard this was written from was an early draft which includes self
+ * contradictions, so this is a "best guess" implementation. Because it is not guaranteed
+ * to be correct this compression is not applied by default. To enable compression set
+ *
+ * symbol->option_3 = ULTRA_COMPRESSION;
+ *
+ * Code compression should be enabled by default when it has been implemented according to
+ * a more reliable version of the specification.
+ */
+
+/* Generate divisor polynomial gQ(x) for GF283() given the required ECC size, 3 to 101 */
+static void ultra_genPoly(short EccSize, unsigned short gPoly[], unsigned short gfPwr[], unsigned short gfLog[]) {
+ int i, j;
+
+ gPoly[0] = 1;
+ for (i = 1; i < (EccSize + 1); i++) gPoly[i] = 0;
+
+ for (i = 0; i < EccSize; i++) {
+ for (j = i; j >= 0; j--)
+ gPoly[j + 1] = (gPoly[j] + GFMUL(gPoly[j + 1], gfPwr[i + 1])) % 283;
+ gPoly[0] = GFMUL(gPoly[0], gfPwr[i + 1]);
+ }
+ for (i = EccSize - 1; i >= 0; i -= 2) gPoly[i] = 283 - gPoly[i];
+
+ /* gPoly[i] is > 0 so modulo operation not needed */
+}
+
+/* Generate the log and antilog tables for GF283() multiplication & division */
+static void ultra_initLogTables(unsigned short gfPwr[], unsigned short gfLog[]) {
+ int i, j;
+
+ for (j = 0; j < 283; j++) gfLog[j] = 0;
+ i = 1;
+ for (j = 0; j < 282; j++) {
+ /* j + 282 indicies save doing the modulo operation in GFMUL */
+ gfPwr[j + 282] = gfPwr[j] = (short) i;
+ gfLog[i] = (short) j;
+ i = (i * 3) % 283;
+ }
+}
+
+static void ultra_gf283(short DataSize, short EccSize, int Message[]) {
+ /* Input is complete message codewords in array Message[282]
+ * DataSize is number of message codewords
+ * EccSize is number of Reed-Solomon GF(283) check codewords to generate
+ *
+ * Upon exit, Message[282] contains complete 282 codeword Symbol Message
+ * including leading zeroes corresponding to each truncated codeword */
+
+ unsigned short gPoly[283], gfPwr[(282 * 2)], gfLog[283];
+ int i, j, n;
+ unsigned short t;
+
+ /* first build the log & antilog tables used in multiplication & division */
+ ultra_initLogTables(gfPwr, gfLog);
+
+ /* then generate the division polynomial of length EccSize */
+ ultra_genPoly(EccSize, gPoly, gfPwr, gfLog);
+
+ /* zero all EccSize codeword values */
+ for (j = 281; (j > (281 - EccSize)); j--) Message[j] = 0;
+
+ /* shift message codewords to the right, leave space for ECC checkwords */
+ for (i = DataSize - 1; (i >= 0); j--, i--) Message[j] = Message[i];
+
+ /* add zeroes to pad left end Message[] for truncated codewords */
+ j++;
+ for (i = 0; i < j; i++) Message[i] = 0;
+
+ /* generate (EccSize) Reed-Solomon checkwords */
+ for (n = j; n < (j + DataSize); n++) {
+ t = (Message[j + DataSize] + Message[n]) % 283;
+ for (i = 0; i < (EccSize - 1); i++) {
+ Message[j + DataSize + i] = (Message[j + DataSize + i + 1] + 283
+ - GFMUL(t, gPoly[EccSize - 1 - i])) % 283;
+ }
+ Message[j + DataSize + EccSize - 1] = (283 - GFMUL(t, gPoly[0])) % 283;
+ }
+ for (i = j + DataSize; i < (j + DataSize + EccSize); i++)
+ Message[i] = (283 - Message[i]) % 283;
+}
+
+/* End of Ted Williams code */
+
+static int ultra_find_fragment(const unsigned char source[], int source_length, int position) {
+ int retval = -1;
+ int j, k, latch, fraglen;
+
+ for (j = 0; j < 27; j++) {
+ latch = 0;
+ fraglen = strlen(fragment[j]);
+ if ((position + fraglen) <= source_length) {
+ latch = 1;
+ for (k = 0; k < fraglen; k++) {
+ if (source[position + k] != fragment[j][k]) {
+ latch = 0;
+ break;
+ }
+ }
+ }
+
+ if (latch) {
+ retval = j;
+ }
+ }
+
+ return retval;
+}
+
+/* Encode characters in 8-bit mode */
+static float look_ahead_eightbit(unsigned char source[], int in_length, int in_locn, char current_mode, int end_char, int cw[], int* cw_len, int gs1)
+{
+ int codeword_count = 0;
+ int i;
+ int letters_encoded = 0;
+
+ if (current_mode != EIGHTBIT_MODE) {
+ cw[codeword_count] = 282; // Unlatch
+ codeword_count += 1;
+ }
+
+ i = in_locn;
+ while ((i < in_length) && (i < end_char)) {
+ if ((source[i] == '[') && gs1) {
+ cw[codeword_count] = 268; // FNC1
+ } else {
+ cw[codeword_count] = source[i];
+ }
+ i++;
+ codeword_count++;
+ }
+
+ letters_encoded = i - in_locn;
+
+ *cw_len = codeword_count;
+
+ if (codeword_count == 0) {
+ return 0.0;
+ } else {
+ return (float)letters_encoded / (float)codeword_count;
+ }
+}
+
+/* Encode character in the ASCII mode/submode (including numeric compression) */
+static float look_ahead_ascii(unsigned char source[], int in_length, int in_locn, char current_mode, int symbol_mode, int end_char, int cw[], int* cw_len, int* encoded, int gs1) {
+ int codeword_count = 0;
+ int i;
+ int first_digit, second_digit, done;
+ int letters_encoded = 0;
+
+ if (current_mode == EIGHTBIT_MODE) {
+ cw[codeword_count] = 267; // Latch ASCII Submode
+ codeword_count++;
+ }
+
+ if (current_mode == C43_MODE) {
+ cw[codeword_count] = 282; // Unlatch
+ codeword_count++;
+ if (symbol_mode == EIGHTBIT_MODE) {
+ cw[codeword_count] = 267; // Latch ASCII Submode
+ codeword_count++;
+ }
+ }
+
+ i = in_locn;
+ do {
+ /* Check for double digits */
+ done = 0;
+ if (i + 1 < in_length) {
+ first_digit = posn(ultra_digit, source[i]);
+ second_digit = posn(ultra_digit, source[i + 1]);
+ if ((first_digit != -1) && (second_digit != -1)) {
+ /* Double digit can be encoded */
+ if ((first_digit >= 0) && (first_digit <= 9) && (second_digit >= 0) && (second_digit <= 9)) {
+ /* Double digit numerics */
+ cw[codeword_count] = (10 * first_digit) + second_digit + 128;
+ codeword_count++;
+ i += 2;
+ done = 1;
+ } else if ((first_digit >= 0) && (first_digit <= 9) && (second_digit == 10)) {
+ /* Single digit followed by selected decimal point character */
+ cw[codeword_count] = first_digit + 228;
+ codeword_count++;
+ i += 2;
+ done = 1;
+ } else if ((first_digit == 10) && (second_digit >= 0) && (second_digit <= 9)) {
+ /* Selected decimal point character followed by single digit */
+ cw[codeword_count] = second_digit + 238;
+ codeword_count++;
+ i += 2;
+ done = 1;
+ } else if ((first_digit >= 0) && (first_digit <= 9) && (second_digit == 11)) {
+ /* Single digit or decimal point followed by field deliminator */
+ cw[codeword_count] = first_digit + 248;
+ codeword_count++;
+ i += 2;
+ done = 1;
+ } else if ((first_digit == 11) && (second_digit >= 0) && (second_digit <= 9)) {
+ /* Field deliminator followed by single digit or decimal point */
+ cw[codeword_count] = second_digit + 259;
+ codeword_count++;
+ i += 2;
+ done = 1;
+ }
+ }
+ }
+
+ if (!done && source[i] < 0x80) {
+ if ((source[i] == '[') && gs1) {
+ cw[codeword_count] = 272; // FNC1
+ } else {
+ cw[codeword_count] = source[i];
+ }
+ codeword_count++;
+ i++;
+ }
+ } while ((i < in_length) && (i < end_char) && (source[i] < 0x80));
+
+ letters_encoded = i - in_locn;
+ if (encoded != NULL) {
+ *encoded = letters_encoded;
+ }
+
+ *cw_len = codeword_count;
+
+ if (codeword_count == 0) {
+ return 0.0;
+ } else {
+ return (float)letters_encoded / (float)codeword_count;
+ }
+}
+
+/* Returns true if should latch to subset other than given `subset` */
+static int c43_should_latch_other(const unsigned char data[], const size_t length, const unsigned int locn, int subset, int gs1) {
+ unsigned int i, fraglen, predict_window;
+ int cnt, alt_cnt, fragno;
+ const char* set = subset == 1 ? ultra_c43_set1 : ultra_c43_set2;
+ const char* alt_set = subset == 2 ? ultra_c43_set1 : ultra_c43_set2;
+
+ if (locn + 3 > length) {
+ return 0;
+ }
+ predict_window = locn + 3;
+
+ for (i = locn, cnt = 0, alt_cnt = 0; i < predict_window; i++) {
+ if (data[i] <= 0x1F || data[i] >= 0x7F || (gs1 && data[i] == '[')) {
+ break;
+ }
+
+ fragno = ultra_find_fragment(data, length, i);
+ if (fragno != -1 && fragno != 26) {
+ fraglen = strlen(fragment[fragno]);
+ predict_window += fraglen;
+ if (predict_window > length) {
+ predict_window = length;
+ }
+ i += fraglen - 1;
+ } else {
+ if (strchr(set, data[i]) != NULL) {
+ cnt++;
+ }
+ if (strchr(alt_set, data[i]) != NULL) {
+ alt_cnt++;
+ }
+ }
+ }
+
+ return alt_cnt > cnt;
+}
+
+static int get_subset(unsigned char source[], int in_length, int in_locn, int current_subset) {
+ int fragno;
+ int subset = 0;
+
+ fragno = ultra_find_fragment(source, in_length, in_locn);
+ if ((fragno != -1) && (fragno != 26)) {
+ subset = 3;
+ } else if (current_subset == 2) {
+ if (posn(ultra_c43_set2, source[in_locn]) != -1) {
+ subset = 2;
+ } else if (posn(ultra_c43_set1, source[in_locn]) != -1) {
+ subset = 1;
+ }
+ } else {
+ if (posn(ultra_c43_set1, source[in_locn]) != -1) {
+ subset = 1;
+ } else if (posn(ultra_c43_set2, source[in_locn]) != -1) {
+ subset = 2;
+ }
+ }
+
+ if (subset == 0) {
+ if (posn(ultra_c43_set3, source[in_locn]) != -1) {
+ subset = 3;
+ }
+ }
+
+ return subset;
+}
+
+/* Encode characters in the C43 compaction submode */
+static float look_ahead_c43(unsigned char source[], int in_length, int in_locn, char current_mode, int end_char, int subset, int cw[], int* cw_len, int* encoded, int gs1, int debug) {
+ int codeword_count = 0;
+ int subcodeword_count = 0;
+ int i;
+ int fragno;
+ int sublocn = in_locn;
+ int new_subset;
+ int unshift_set;
+ int base43_value;
+ int letters_encoded = 0;
+ int pad;
+
+#ifndef _MSC_VER
+ int subcw[(in_length + 3) * 2];
+#else
+ int * subcw = (int *) _alloca((in_length + 3) * 2 * sizeof (int));
+#endif /* _MSC_VER */
+
+ if (current_mode == EIGHTBIT_MODE) {
+ /* Check for permissable URL C43 macro sequences, otherwise encode directly */
+ fragno = ultra_find_fragment(source, in_length, sublocn);
+
+ if ((fragno == 2) || (fragno == 3)) {
+ // http://www. > http://
+ // https://www. > https://
+ fragno -= 2;
+ }
+
+ switch(fragno) {
+ case 17: // mailto:
+ cw[codeword_count] = 276;
+ sublocn += strlen(fragment[fragno]);
+ codeword_count++;
+ break;
+ case 18: // tel:
+ cw[codeword_count] = 277;
+ sublocn += strlen(fragment[fragno]);
+ codeword_count++;
+ break;
+ case 26: // file:
+ cw[codeword_count] = 278;
+ sublocn += strlen(fragment[fragno]);
+ codeword_count++;
+ break;
+ case 0: // http://
+ cw[codeword_count] = 279;
+ sublocn += strlen(fragment[fragno]);
+ codeword_count++;
+ break;
+ case 1: // https://
+ cw[codeword_count] = 280;
+ sublocn += strlen(fragment[fragno]);
+ codeword_count++;
+ break;
+ case 4: // ftp://
+ cw[codeword_count] = 281;
+ sublocn += strlen(fragment[fragno]);
+ codeword_count++;
+ break;
+ default:
+ if (subset == 1) {
+ cw[codeword_count] = 260; // C43 Compaction Submode C1
+ codeword_count++;
+ }
+
+ if ((subset == 2) || (subset == 3)) {
+ cw[codeword_count] = 266; // C43 Compaction Submode C2
+ codeword_count++;
+ }
+ break;
+ }
+ }
+
+ if (current_mode == ASCII_MODE) {
+ if (subset == 1) {
+ cw[codeword_count] = 278; // C43 Compaction Submode C1
+ codeword_count++;
+ }
+
+ if ((subset == 2) || (subset == 3)) {
+ cw[codeword_count] = 280; // C43 Compaction Submode C2
+ codeword_count++;
+ }
+ }
+ unshift_set = subset;
+
+ while ((sublocn < in_length) && (sublocn < end_char)) {
+ /* Check for FNC1 */
+ if (gs1 && source[sublocn] == '[') {
+ break;
+ }
+
+ new_subset = get_subset(source, in_length, sublocn, subset);
+
+ if (new_subset == 0) {
+ break;
+ }
+
+ if ((new_subset != subset) && ((new_subset == 1) || (new_subset == 2))) {
+ if (c43_should_latch_other(source, in_length, sublocn, subset, gs1)) {
+ subcw[subcodeword_count] = 42; // Latch to other C43 set
+ subcodeword_count++;
+ unshift_set = new_subset;
+ } else {
+ subcw[subcodeword_count] = 40; // Shift to other C43 set for 1 char
+ subcodeword_count++;
+ subcw[subcodeword_count] = posn(new_subset == 1 ? ultra_c43_set1 : ultra_c43_set2, source[sublocn]);
+ subcodeword_count++;
+ sublocn++;
+ continue;
+ }
+ }
+
+ subset = new_subset;
+
+ if (subset == 1) {
+ subcw[subcodeword_count] = posn(ultra_c43_set1, source[sublocn]);
+ subcodeword_count++;
+ sublocn++;
+ }
+
+ if (subset == 2) {
+ subcw[subcodeword_count] = posn(ultra_c43_set2, source[sublocn]);
+ subcodeword_count++;
+ sublocn++;
+ }
+
+ if (subset == 3) {
+ subcw[subcodeword_count] = 41; // Shift to set 3
+ subcodeword_count++;
+
+ fragno = ultra_find_fragment(source, in_length, sublocn);
+ if (fragno == 26) {
+ fragno = -1;
+ }
+ if ((fragno >= 0) && (fragno <= 18)) {
+ subcw[subcodeword_count] = fragno; // C43 Set 3 codewords 0 to 18
+ subcodeword_count++;
+ sublocn += strlen(fragment[fragno]);
+ }
+ if ((fragno >= 19) && (fragno <= 25)) {
+ subcw[subcodeword_count] = fragno + 17; // C43 Set 3 codewords 36 to 42
+ subcodeword_count++;
+ sublocn += strlen(fragment[fragno]);
+ }
+ if (fragno == -1) {
+ subcw[subcodeword_count] = posn(ultra_c43_set3, source[sublocn]) + 19; // C43 Set 3 codewords 19 to 35
+ subcodeword_count++;
+ sublocn++;
+ }
+ subset = unshift_set;
+ }
+ }
+
+ pad = 3 - (subcodeword_count % 3);
+ if (pad == 3) {
+ pad = 0;
+ }
+
+ for (i = 0; i < pad; i++) {
+ subcw[subcodeword_count] = 42; // Latch to other C43 set used as pad
+ subcodeword_count++;
+ }
+
+ if (debug & ZINT_DEBUG_PRINT) {
+ printf("C43 codewords %.*s: (%d)", in_length, source + in_locn, subcodeword_count);
+ for (i = 0; i < subcodeword_count; i++) printf( " %d", subcw[i]);
+ printf("\n");
+ }
+
+ letters_encoded = sublocn - in_locn;
+ if (encoded != NULL) {
+ *encoded = letters_encoded;
+ }
+
+ for (i = 0; i < subcodeword_count; i += 3) {
+ base43_value = (43 * 43 * subcw[i]) + (43 * subcw[i + 1]) + subcw[i + 2];
+ cw[codeword_count] = base43_value / 282;
+ codeword_count++;
+ cw[codeword_count] = base43_value % 282;
+ codeword_count++;
+ }
+
+ *cw_len = codeword_count;
+
+ if (codeword_count == 0) {
+ return 0.0;
+ } else {
+ return (float)letters_encoded / (float)codeword_count;
+ }
+}
+
+/* Produces a set of codewords which are "somewhat" optimised - this could be improved on */
+static int ultra_generate_codewords(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length, int codewords[]) {
+ int i;
+ int crop_length;
+ int codeword_count = 0;
+ int input_locn = 0;
+ char symbol_mode;
+ char current_mode;
+ int subset;
+ float eightbit_score;
+ float ascii_score;
+ float c43_score;
+ int end_char;
+ int block_length;
+ int fragment_length;
+ int fragno;
+ int gs1 = 0;
+ int ascii_encoded, c43_encoded;
+
+#ifndef _MSC_VER
+ unsigned char crop_source[in_length + 1];
+ char mode[in_length + 1];
+ int cw_fragment[in_length * 2 + 1];
+#else
+ unsigned char * crop_source = (unsigned char *) _alloca((in_length + 1) * sizeof (unsigned char));
+ char * mode = (char *) _alloca((in_length + 1) * sizeof (char));
+ int * cw_fragment = (int *) _alloca((in_length * 2 + 1) * sizeof (int));
+#endif /* _MSC_VER */
+
+ if ((symbol->input_mode & 0x07) == GS1_MODE) {
+ gs1 = 1;
+ }
+
+ // Decide start character codeword (from Table 5)
+ symbol_mode = ASCII_MODE;
+ for (i = 0; i < (int) in_length; i++) {
+ if (source[i] >= 0x80) {
+ symbol_mode = EIGHTBIT_MODE;
+ break;
+ }
+ }
+
+ if (symbol->option_3 != ULTRA_COMPRESSION && !gs1) {
+ // Force eight-bit mode by default as other modes are poorly documented
+ symbol_mode = EIGHTBIT_MODE;
+ }
+
+ if (symbol->output_options & READER_INIT) {
+ /* Reader Initialisation mode */
+ if (symbol_mode == ASCII_MODE) {
+ codewords[0] = 272; // 7-bit ASCII mode
+ codewords[1] = 271; // FNC3
+ } else {
+ codewords[0] = 257; // 8859-1
+ codewords[1] = 269; // FNC3
+ }
+ codeword_count = 2;
+ } else {
+ /* Calculate start character codeword */
+ if (symbol_mode == ASCII_MODE) {
+ if (gs1) {
+ codewords[0] = 273;
+ } else {
+ codewords[0] = 272;
+ }
+ } else {
+ if ((symbol->eci >= 3) && (symbol->eci <= 18) && (symbol->eci != 14)) {
+ // ECI indicates use of character set within ISO/IEC 8859
+ codewords[0] = 257 + (symbol->eci - 3);
+ if (codewords[0] > 267) {
+ // Avoids ECI 14 for non-existant ISO/IEC 8859-12
+ codewords[0]--;
+ }
+ } else if ((symbol->eci > 18) && (symbol->eci <= 898)) {
+ // ECI indicates use of character set outside ISO/IEC 8859
+ codewords[0] = 275 + (symbol->eci / 256);
+ codewords[1] = symbol->eci % 256;
+ codeword_count++;
+ } else if (symbol->eci == 899) {
+ // Non-language byte data
+ codewords[0] = 280;
+ } else if ((symbol->eci > 899) && (symbol->eci <= 9999)) {
+ // ECI beyond 899 needs to use fixed length encodable ECI invocation (section 7.6.2)
+ // Encode as 3 codewords
+ codewords[0] = 257; // ISO/IEC 8859-1 used to enter 8-bit mode
+ codewords[1] = 274; // Encode ECI as 3 codewords
+ codewords[2] = (symbol->eci / 100) + 128;
+ codewords[3] = (symbol->eci % 100) + 128;
+ codeword_count += 3;
+ } else if (symbol->eci >= 10000) {
+ // Encode as 4 codewords
+ codewords[0] = 257; // ISO/IEC 8859-1 used to enter 8-bit mode
+ codewords[1] = 275; // Encode ECI as 4 codewords
+ codewords[2] = (symbol->eci / 10000) + 128;
+ codewords[3] = ((symbol->eci % 10000) / 100) + 128;
+ codewords[4] = (symbol->eci % 100) + 128;
+ codeword_count += 4;
+ } else {
+ codewords[0] = 257; // Default is assumed to be ISO/IEC 8859-1 (ECI 3)
+ }
+ }
+
+ if ((codewords[0] == 257) || (codewords[0] == 272)) {
+ fragno = ultra_find_fragment((unsigned char *)source, in_length, 0);
+
+ // Check for http:// at start of input
+ if ((fragno == 0) || (fragno == 2)) {
+ codewords[0] = 281;
+ input_locn = 7;
+ symbol_mode = EIGHTBIT_MODE;
+ }
+
+
+ // Check for https:// at start of input
+ if ((fragno == 1) || (fragno == 3)) {
+ codewords[0] = 282;
+ input_locn = 8;
+ symbol_mode = EIGHTBIT_MODE;
+ }
+ }
+ }
+
+ codeword_count++;
+
+ /* Check for 06 Macro Sequence and crop accordingly */
+ if (in_length >= 9
+ && source[0] == '[' && source[1] == ')' && source[2] == '>' && source[3] == '\x1e'
+ && source[4] == '0' && source[5] == '6' && source[6] == '\x1d'
+ && source[in_length - 2] == '\x1e' && source[in_length - 1] == '\x04') {
+
+ if (symbol_mode == EIGHTBIT_MODE) {
+ codewords[codeword_count] = 271; // 06 Macro
+ } else {
+ codewords[codeword_count] = 273; // 06 Macro
+ }
+ codeword_count++;
+
+ for (i = 7; i < ((int) in_length - 2); i++) {
+ crop_source[i - 7] = source[i];
+ }
+ crop_length = in_length - 9;
+ crop_source[crop_length] = '\0';
+ } else {
+ /* Make a cropped version of input data - removes http:// and https:// if needed */
+ for (i = input_locn; i < (int) in_length; i++) {
+ crop_source[i - input_locn] = source[i];
+ }
+ crop_length = in_length - input_locn;
+ crop_source[crop_length] = '\0';
+ }
+
+ /* Attempt encoding in all three modes to see which offers best compaction and store results */
+ if (symbol->option_3 == ULTRA_COMPRESSION || gs1) {
+ current_mode = symbol_mode;
+ input_locn = 0;
+ do {
+ end_char = input_locn + PREDICT_WINDOW;
+ eightbit_score = look_ahead_eightbit(crop_source, crop_length, input_locn, current_mode, end_char, cw_fragment, &fragment_length, gs1);
+ ascii_score = look_ahead_ascii(crop_source, crop_length, input_locn, current_mode, symbol_mode, end_char, cw_fragment, &fragment_length, &ascii_encoded, gs1);
+ subset = c43_should_latch_other(crop_source, crop_length, input_locn, 1 /*subset*/, gs1) ? 2 : 1;
+ c43_score = look_ahead_c43(crop_source, crop_length, input_locn, current_mode, end_char, subset, cw_fragment, &fragment_length, &c43_encoded, gs1, 0 /*debug*/);
+
+ mode[input_locn] = 'a';
+ current_mode = ASCII_MODE;
+
+ if ((c43_score > ascii_score) && (c43_score > eightbit_score)) {
+ mode[input_locn] = 'c';
+ current_mode = C43_MODE;
+ }
+
+ if ((eightbit_score > ascii_score) && (eightbit_score > c43_score)) {
+ mode[input_locn] = '8';
+ current_mode = EIGHTBIT_MODE;
+ }
+ if (mode[input_locn] == 'a') {
+ for (i = 0; i < ascii_encoded; i++) {
+ mode[input_locn + i] = 'a';
+ }
+ input_locn += ascii_encoded;
+ } else if (mode[input_locn] == 'c') {
+ for (i = 0; i < c43_encoded; i++) {
+ mode[input_locn + i] = 'c';
+ }
+ input_locn += c43_encoded;
+ } else {
+ input_locn++;
+ }
+ } while (input_locn < crop_length);
+ } else {
+ // Force eight-bit mode
+ for (input_locn = 0; input_locn < crop_length; input_locn++) {
+ mode[input_locn] = '8';
+ }
+ }
+ mode[crop_length] = '\0';
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Mode: %s (%d)\n", mode, (int) strlen(mode));
+ }
+
+ /* Use results from test to perform actual mode switching */
+ current_mode = symbol_mode;
+ input_locn = 0;
+ do {
+ fragment_length = 0;
+ block_length = 0;
+ while (input_locn + block_length < crop_length && mode[input_locn + block_length] == mode[input_locn]) {
+ block_length++;
+ }
+
+ switch(mode[input_locn]) {
+ case 'a':
+ look_ahead_ascii(crop_source, crop_length, input_locn, current_mode, symbol_mode, input_locn + block_length, cw_fragment, &fragment_length, NULL, gs1);
+ current_mode = ASCII_MODE;
+ break;
+ case 'c':
+ subset = c43_should_latch_other(crop_source, crop_length, input_locn, 1 /*subset*/, gs1) ? 2 : 1;
+ look_ahead_c43(crop_source, crop_length, input_locn, current_mode, input_locn + block_length, subset, cw_fragment, &fragment_length, NULL, gs1, symbol->debug);
+
+ /* Substitute temporary latch if possible */
+ if ((current_mode == EIGHTBIT_MODE) && (cw_fragment[0] == 260) && (fragment_length >= 5) && (fragment_length <= 11)) {
+ /* Temporary latch to submode 1 from Table 11 */
+ cw_fragment[0] = 256 + ((fragment_length - 5) / 2);
+ } else if ((current_mode == EIGHTBIT_MODE) && (cw_fragment[0] == 266) && (fragment_length >= 5) && (fragment_length <= 11)) {
+ /* Temporary latch to submode 2 from Table 11 */
+ cw_fragment[0] = 262 + ((fragment_length - 5) / 2);
+ } else if ((current_mode == ASCII_MODE) && (cw_fragment[0] == 278) && (fragment_length >= 5) && (fragment_length <= 11)) {
+ /* Temporary latch to submode 1 from Table 9 */
+ cw_fragment[0] = 274 + ((fragment_length - 5) / 2);
+ } else {
+ current_mode = C43_MODE;
+ }
+ break;
+ case '8':
+ look_ahead_eightbit(crop_source, crop_length, input_locn, current_mode, input_locn + block_length, cw_fragment, &fragment_length, gs1);
+ current_mode = EIGHTBIT_MODE;
+ break;
+ }
+
+ for (i = 0; i < fragment_length; i++) {
+ codewords[codeword_count + i] = cw_fragment[i];
+ }
+ codeword_count += fragment_length;
+
+ input_locn += block_length;
+ } while (input_locn < crop_length);
+
+ return codeword_count;
+}
+
+INTERNAL int ultracode(struct zint_symbol *symbol, const unsigned char source[], const size_t in_length) {
+ int data_cw_count = 0;
+ int acc, qcc;
+ int ecc_level;
+ int rows, columns;
+ int total_cws;
+ int pads;
+ int cw_memalloc;
+ int codeword[282 + 3]; // Allow for 3 pads in final 57th (60th incl. clock tracks) column of 5-row symbol (57 * 5 == 285)
+ int i, j, locn;
+ int total_height, total_width;
+ char tilepat[6];
+ int tilex, tiley;
+ int dcc;
+#ifdef _MSC_VER
+ int* data_codewords;
+ char* pattern;
+#endif /* _MSC_VER */
+
+ cw_memalloc = in_length * 2;
+ if (cw_memalloc < 283) {
+ cw_memalloc = 283;
+ }
+
+ if (symbol->eci > 811799) {
+ strcpy(symbol->errtxt, "590: ECI value not supported by Ultracode");
+ return ZINT_ERROR_INVALID_OPTION;
+ }
+
+#ifndef _MSC_VER
+ int data_codewords[cw_memalloc];
+#else
+ data_codewords = (int *) _alloca(cw_memalloc * sizeof (int));
+#endif /* _MSC_VER */
+
+ data_cw_count = ultra_generate_codewords(symbol, source, in_length, data_codewords);
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Codewords returned = %d\n", data_cw_count);
+ }
+#ifdef ZINT_TEST
+ if (symbol->debug & ZINT_DEBUG_TEST) {
+ debug_test_codeword_dump_int(symbol, data_codewords, data_cw_count);
+ }
+#endif
+
+ data_cw_count += 2; // 2 == MCC + ACC (data codeword count includes start char)
+
+ /* Default ECC level is EC2 */
+ if ((symbol->option_1 <= 0) || (symbol->option_1 > 6)) {
+ ecc_level = 2;
+ } else {
+ ecc_level = symbol->option_1 - 1;
+ }
+
+ /* ECC calculation from section 7.7.2 */
+ if (ecc_level == 0) {
+ qcc = 3;
+ } else {
+ if ((data_cw_count % 25) == 0) {
+ qcc = (kec[ecc_level] * (data_cw_count / 25)) + 3 + 2;
+ } else {
+ qcc = (kec[ecc_level] * ((data_cw_count / 25) + 1)) + 3 + 2;
+ }
+
+ }
+ acc = qcc - 3;
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("ECC codewords: %d\n", qcc);
+ }
+
+ /* Maximum capacity is 282 codewords */
+ total_cws = data_cw_count + qcc + 3; // 3 == TCC pattern + RSEC pattern + QCC pattern
+ if (total_cws > 282) {
+ strcpy(symbol->errtxt, "591: Data too long for selected error correction capacity");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ rows = 5;
+ for (i = 2; i >= 0; i--) {
+ if (total_cws - 6 <= ultra_maxsize[i]) { // Total codewords less 6 overhead (Start + MCC + ACC + 3 TCC/RSEC/QCC patterns)
+ rows--;
+ }
+ }
+
+ if ((total_cws % rows) == 0) {
+ pads = 0;
+ columns = total_cws / rows;
+ } else {
+ pads = rows - (total_cws % rows);
+ columns = (total_cws / rows) + 1;
+ }
+ columns += columns / 15; // Secondary vertical clock tracks
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Calculated size is %d rows by %d columns\n", rows, columns);
+ }
+
+ /* Insert MCC and ACC into data codewords */
+ for (i = 282; i > 2; i--) {
+ data_codewords[i] = data_codewords[i - 2];
+ }
+ data_codewords[1] = data_cw_count; // MCC
+ data_codewords[2] = acc; // ACC
+
+ locn = 0;
+ /* Calculate error correction codewords (RSEC) */
+ ultra_gf283((short) data_cw_count, (short) qcc, data_codewords);
+
+ /* Rearrange to make final codeword sequence */
+ codeword[locn++] = data_codewords[282 - (data_cw_count + qcc)]; // Start Character
+ codeword[locn++] = data_cw_count; // MCC
+ for (i = 0; i < qcc; i++) {
+ codeword[locn++] = data_codewords[(282 - qcc) + i]; // RSEC Region
+ }
+ codeword[locn++] = data_cw_count + qcc; // TCC = C + Q - section 6.11.4
+ codeword[locn++] = 283; // Separator
+ codeword[locn++] = acc; // ACC
+ for (i = 0; i < (data_cw_count - 3); i++) {
+ codeword[locn++] = data_codewords[(282 - ((data_cw_count - 3) + qcc)) + i]; // Data Region
+ }
+ for (i = 0; i < pads; i++) {
+ codeword[locn++] = 284; // Pad pattern
+ }
+ codeword[locn++] = qcc; // QCC
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("Rearranged codewords with ECC:\n");
+ for (i = 0; i < locn; i++) {
+ printf("%d ", codeword[i]);
+ }
+ printf("\n");
+ }
+
+ total_height = (rows * 6) + 1;
+ total_width = columns + 6;
+
+ /* Build symbol */
+#ifndef _MSC_VER
+ char pattern[total_height * total_width];
+#else
+ pattern = (char *) _alloca(total_height * total_width * sizeof (char));
+#endif /* _MSC_VER */
+
+ for (i = 0; i < (total_height * total_width); i++) {
+ pattern[i] = 'W';
+ }
+
+ /* Border */
+ for (i = 0; i < total_width; i++) {
+ pattern[i] = 'K'; // Top
+ pattern[(total_height * total_width) - i - 1] = 'K'; // Bottom
+ }
+ for (i = 0; i < total_height; i++) {
+ pattern[total_width * i] = 'K'; // Left
+ pattern[(total_width * i) + 3] = 'K';
+ pattern[(total_width * i) + (total_width - 1)] = 'K'; // Right
+ }
+
+ /* Clock tracks */
+ for (i = 0; i < total_height; i += 2) {
+ pattern[(total_width * i) + 1] = 'K'; // Primary vertical clock track
+ if (total_width > 20) {
+ pattern[(total_width * i) + 19] = 'K'; // Secondary vertical clock track
+ }
+ if (total_width > 36) {
+ pattern[(total_width * i) + 35] = 'K'; // Secondary vertical clock track
+ }
+ if (total_width > 52) {
+ pattern[(total_width * i) + 51] = 'K'; // Secondary vertical clock track
+ }
+ }
+ for (i = 6; i < total_height; i += 6) {
+ for (j = 5; j < total_width; j += 2) {
+ pattern[(total_width * i) + j] = 'K'; // Horizontal clock track
+ }
+ }
+
+ /* Place tiles */
+ tilepat[5] = '\0';
+ tilex = 0;
+ tiley = 0;
+ for (i = 0; i < locn; i++) {
+ for (j = 0; j < 5; j++) {
+ tilepat[4 - j] = ultra_colour[(tiles[codeword[i]] >> (3 * j)) & 0x07];
+ }
+ if ((tiley + 1) >= total_height) {
+ tiley = 0;
+ tilex++;
+
+ if (tilex == 14) {
+ tilex++;
+ }
+ if (tilex == 30) {
+ tilex++;
+ }
+ if (tilex == 46) {
+ tilex++;
+ }
+ }
+
+ for (j = 0; j < 5; j++) {
+ pattern[((tiley + j + 1) * total_width) + (tilex + 5)] = tilepat[j];
+ }
+ tiley += 6;
+ }
+
+ /* Add data column count */
+ dcc = columns - ultra_mincols[rows - 2];
+ tilex = 2;
+ tiley = (total_height - 11) / 2;
+ /* DCCU */
+ for (j = 0; j < 5; j++) {
+ tilepat[4 - j] = ultra_colour[(dccu[dcc] >> (3 * j)) & 0x07];
+ }
+ for (j = 0; j < 5; j++) {
+ pattern[((tiley + j) * total_width) + tilex] = tilepat[j];
+ }
+ /* DCCL */
+ tiley += 6;
+ for (j = 0; j < 5; j++) {
+ tilepat[4 - j] = ultra_colour[(dccl[dcc] >> (3 * j)) & 0x07];
+ }
+ for (j = 0; j < 5; j++) {
+ pattern[((tiley + j) * total_width) + tilex] = tilepat[j];
+ }
+
+ if (symbol->debug & ZINT_DEBUG_PRINT) {
+ printf("DCC: %d\n", dcc);
+
+ for (i = 0; i < (total_height * total_width); i++) {
+ printf("%c", pattern[i]);
+ if ((i + 1) % total_width == 0) {
+ printf("\n");
+ }
+ }
+ }
+
+ /* Put pattern into symbol */
+ symbol->rows = total_height;
+ symbol->width = total_width;
+
+ for (i = 0; i < total_height; i++) {
+ symbol->row_height[i] = 1;
+ for(j = 0; j < total_width; j++) {
+ set_module_colour(symbol, i, j, posn(ultra_colour, pattern[(i * total_width) + j]));
+ }
+ }
+
+ return 0;
+}
diff --git a/backend/upcean.c b/backend/upcean.c
index c99091b..15fac07 100644
--- a/backend/upcean.c
+++ b/backend/upcean.c
@@ -1,7 +1,7 @@
/* upcean.c - Handles UPC, EAN and ISBN
libzint - the open source barcode library
- Copyright (C) 2008 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2008-2017 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -27,7 +27,8 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
#define SODIUM "0123456789+"
#define EAN2 102
@@ -40,769 +41,889 @@
/* UPC and EAN tables checked against EN 797:1996 */
-static const char *UPCParity0[10] = {"BBBAAA", "BBABAA", "BBAABA", "BBAAAB", "BABBAA", "BAABBA", "BAAABB",
- "BABABA", "BABAAB", "BAABAB"}; /* Number set for UPC-E symbol (EN Table 4) */
-static const char *UPCParity1[10] = {"AAABBB", "AABABB", "AABBAB", "AABBBA", "ABAABB", "ABBAAB", "ABBBAA",
- "ABABAB", "ABABBA", "ABBABA"}; /* Not covered by BS EN 797:1995 */
-static const char *EAN2Parity[4] = {"AA", "AB", "BA", "BB"}; /* Number sets for 2-digit add-on (EN Table 6) */
-static const char *EAN5Parity[10] = {"BBAAA", "BABAA", "BAABA", "BAAAB", "ABBAA", "AABBA", "AAABB", "ABABA",
- "ABAAB", "AABAB"}; /* Number set for 5-digit add-on (EN Table 7) */
-static const char *EAN13Parity[10] = {"AAAAA", "ABABB", "ABBAB", "ABBBA", "BAABB", "BBAAB", "BBBAA", "BABAB",
- "BABBA", "BBABA"}; /* Left hand of the EAN-13 symbol (EN Table 3) */
-static const char *EANsetA[10] = {"3211", "2221", "2122", "1411", "1132", "1231", "1114", "1312", "1213",
- "3112"}; /* Representation set A and C (EN Table 1) */
-static const 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 & 1)) {
- count += 2 * (ctoi(source[i]));
- }
- }
-
- check_digit = 10 - (count%10);
- if (check_digit == 10) { check_digit = 0; }
- return itoc(check_digit);
+static const char *UPCParity0[10] = {
+ /* Number set for UPC-E symbol (EN Table 4) */
+ "BBBAAA", "BBABAA", "BBAABA", "BBAAAB", "BABBAA", "BAABBA", "BAAABB",
+ "BABABA", "BABAAB", "BAABAB"
+};
+
+static const char *UPCParity1[10] = {
+ /* Not covered by BS EN 797:1995 */
+ "AAABBB", "AABABB", "AABBAB", "AABBBA", "ABAABB", "ABBAAB", "ABBBAA",
+ "ABABAB", "ABABBA", "ABBABA"
+};
+
+static const char *EAN2Parity[4] = {
+ /* Number sets for 2-digit add-on (EN Table 6) */
+ "AA", "AB", "BA", "BB"
+};
+
+static const char *EAN5Parity[10] = {
+ /* Number set for 5-digit add-on (EN Table 7) */
+ "BBAAA", "BABAA", "BAABA", "BAAAB", "ABBAA", "AABBA", "AAABB", "ABABA",
+ "ABAAB", "AABAB"
+};
+
+static const char *EAN13Parity[10] = {
+ /* Left hand of the EAN-13 symbol (EN Table 3) */
+ "AAAAA", "ABABB", "ABBAB", "ABBBA", "BAABB", "BBAAB", "BBBAA", "BABAB",
+ "BABBA", "BBABA"
+};
+
+static const char *EANsetA[10] = {
+ /* Representation set A and C (EN Table 1) */
+ "3211", "2221", "2122", "1411", "1132", "1231", "1114", "1312", "1213", "3112"
+};
+
+static const char *EANsetB[10] = {
+ /* Representation set B (EN Table 1) */
+ "1123", "1222", "2212", "1141", "2311", "1321", "4111", "2131", "3121", "2113"
+};
+
+/* Calculate the correct check digit for a UPC barcode */
+static char upc_check(char source[]) {
+ unsigned int i, count, check_digit;
+
+ count = 0;
+
+ for (i = 0; i < strlen(source); i++) {
+ count += ctoi(source[i]);
+
+ if (!(i & 1)) {
+ 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;
+/* UPC A is usually used for 12 digit numbers, but this function takes a source of any length */
+static void upca_draw(char source[], char dest[]) {
+ unsigned int i, half_way;
- half_way = strlen(source) / 2;
+ half_way = strlen(source) / 2;
- /* start character */
- concat (dest, "111");
+ /* start character */
+ strcat(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");
- }
+ for (i = 0; i <= strlen(source); i++) {
+ if (i == half_way) {
+ /* middle character - separates manufacturer no. from product no. */
+ /* also inverts right hand characters */
+ strcat(dest, "11111");
+ }
- lookup(NEON, EANsetA, source[i], dest);
- }
+ lookup(NEON, EANsetA, source[i], dest);
+ }
- /* stop character */
- concat (dest, "111");
+ /* stop character */
+ strcat(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);
+/* Make a UPC A barcode when we haven't been given the check digit */
+static int upca(struct zint_symbol *symbol, unsigned char source[], char dest[]) {
+ int length;
+ char gtin[15];
+
+ strcpy(gtin, (char*) source);
+ length = strlen(gtin);
+
+ if (length == 11) {
+ gtin[length] = upc_check(gtin);
+ gtin[length + 1] = '\0';
+ } else {
+ gtin[length - 1] = '\0';
+ if (source[length - 1] != upc_check(gtin)) {
+ strcpy(symbol->errtxt, "270: Invalid check digit");
+ return ZINT_ERROR_INVALID_CHECK;
+ }
+ gtin[length - 1] = upc_check(gtin);
+ }
+ upca_draw(gtin, dest);
+ ustrcpy(symbol->text, (unsigned char*) gtin);
+ return 0;
}
-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);
+/* UPC E is a zero-compressed version of UPC A */
+static int upce(struct zint_symbol *symbol, unsigned char source[], char dest[]) {
+ unsigned int i, num_system;
+ char emode, equivalent[12], check_digit, parity[8], temp[9];
+ char hrt[9];
+
+ /* Two number systems can be used - system 0 and system 1 */
+ if (symbol->symbology != BARCODE_UPCE_CHK) {
+ /* No check digit in input data */
+ 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';
+ strcat(hrt, (char*) source);
+ }
+ } else {
+ /* Check digit is included in input data */
+ if (ustrlen(source) == 8) {
+ 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 <= 8; i++) {
+ source[i - 1] = temp[i];
+ }
+ } else {
+ num_system = 0;
+ hrt[0] = '0';
+ hrt[1] = '\0';
+ strcat(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, "271: Invalid UPC-E data");
+ return ZINT_ERROR_INVALID_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, "272: Invalid UPC-E data");
+ return ZINT_ERROR_INVALID_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, "273: Invalid UPC-E data");
+ return ZINT_ERROR_INVALID_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 */
+ strcat(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 */
+ strcat(dest, "111111");
+
+ if (symbol->symbology != BARCODE_UPCE_CHK) {
+ hrt[7] = check_digit;
+ hrt[8] = '\0';
+ } else {
+ if (hrt[7] != check_digit) {
+ strcpy(symbol->errtxt, "274: Invalid check digit");
+ return ZINT_ERROR_INVALID_CHECK;
+ }
+ }
+ ustrcpy(symbol->text, (unsigned char*) hrt);
+ return 0;
}
-
-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-2 and EAN-5 add-on codes */
+static void add_on(unsigned char source[], char dest[], int mode) {
+ char parity[6];
+ unsigned int i, code_type;
+
+ /* If an add-on then append with space */
+ if (mode != 0) {
+ strcat(dest, "9");
+ }
+
+ /* Start character */
+ strcat(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)) {
+ strcat(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 & 1) {
- count += 2 * ctoi(source[i]);
- }
- }
- check_digit = 10 - (count%10);
- if (check_digit == 10) { check_digit = 0; }
- return itoc(check_digit);
+/* Calculate the correct check digit for a EAN-13 barcode */
+static char ean_check(char source[]) {
+ 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 & 1) {
+ 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);
+static int 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);
+
+ if (length == 12) {
+ gtin[length] = ean_check(gtin);
+ gtin[length + 1] = '\0';
+ } else {
+ gtin[length - 1] = '\0';
+ if (source[length - 1] != ean_check(gtin)) {
+ strcpy(symbol->errtxt, "275: Invalid check digit");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ gtin[length - 1] = ean_check(gtin);
+ }
+
+ /* 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 */
+ strcat(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 */
+ strcat(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 */
+ strcat(dest, "111");
+
+ ustrcpy(symbol->text, (unsigned char*) gtin);
+ return 0;
}
-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);
+/* Make an EAN-8 barcode when we haven't been given the check digit */
+static int ean8(struct zint_symbol *symbol, unsigned char source[], char dest[]) {
+ /* 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);
+
+ if (length == 7) {
+ gtin[length] = upc_check(gtin);
+ gtin[length + 1] = '\0';
+ } else {
+ gtin[length - 1] = '\0';
+ if (source[length - 1] != upc_check(gtin)) {
+ strcpy(symbol->errtxt, "276: Invalid check digit");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+ gtin[length - 1] = upc_check(gtin);
+ }
+ upca_draw(gtin, dest);
+ ustrcpy(symbol->text, (unsigned char*) gtin);
+
+ return 0;
}
-char isbn13_check(unsigned char source[]) /* For ISBN(13) only */
-{
- unsigned int i, weight, sum, check, h;
+/* For ISBN(13) only */
+static char isbn13_check(unsigned char source[]) {
+ unsigned int i, weight, sum, check, h;
- sum = 0;
- weight = 1;
- h = ustrlen(source) - 1;
+ 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;
- }
+ 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;
- if(check == 10) check = 0;
- return itoc(check);
+ check = sum % 10;
+ check = 10 - check;
+ if (check == 10) check = 0;
+ 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;
+/* For ISBN(10) and SBN only */
+static char isbn_check(unsigned char source[]) {
+ 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;
+/* Make an EAN-13 barcode from an SBN or ISBN */
+static int isbn(struct zint_symbol *symbol, unsigned char source[], const size_t src_len, char dest[]) {
+ int i, error_number;
+ char check_digit;
+
+ to_upper(source);
+ error_number = is_sane("0123456789X", source, src_len);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "277: Invalid characters in input");
+ return error_number;
+ }
+
+ /* Input must be 9, 10 or 13 characters */
+ if (src_len != 9 && src_len != 10 && src_len != 13) {
+ strcpy(symbol->errtxt, "278: Input wrong length");
+ return ZINT_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, "279: Invalid ISBN");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ check_digit = isbn13_check(source);
+ if (source[src_len - 1] != check_digit) {
+ strcpy(symbol->errtxt, "280: Incorrect ISBN check");
+ return ZINT_ERROR_INVALID_CHECK;
+ }
+ source[12] = '\0';
+ }
+
+ 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';
+ }
+
+ if (src_len == 9 || src_len == 10) /* Using 10 digit ISBN or 9 digit SBN padded with leading zero */ {
+ check_digit = isbn_check(source);
+ if (check_digit != source[ustrlen(source) - 1]) {
+ strcpy(symbol->errtxt, src_len == 9 ? "281: Incorrect SBN check" : "281: Incorrect ISBN check");
+ return ZINT_ERROR_INVALID_CHECK;
+ }
+ for (i = 11; i > 2; i--) {
+ source[i] = source[i - 3];
+ }
+ source[0] = '9';
+ source[1] = '7';
+ source[2] = '8';
+ source[12] = '\0';
+ }
+
+ return ean13(symbol, source, dest);
}
-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);
- }
+/* Add leading zeroes to EAN and UPC strings */
+INTERNAL void ean_leading_zeroes(struct zint_symbol *symbol, unsigned char source[], unsigned char local_source[]) {
+ 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';
+ }
+
+ if (second_len >= 6) { /* Allow 6 (actual max 5) so as to trigger too long error */
+ second_len = 6;
+ }
+ 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 && symbol->symbology == BARCODE_EANX) { /* No composite EAN-2/5 */
+ if (first_len <= 5) {
+ zfirst_len = 5;
+ }
+ if (first_len <= 2) {
+ zfirst_len = 2;
+ }
+ }
+ break;
+ case BARCODE_EANX_CHK:
+ if (first_len <= 13) {
+ zfirst_len = 13;
+ }
+ if (first_len <= 8) {
+ zfirst_len = 8;
+ }
+ 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_UPCA_CHK:
+ zfirst_len = 12;
+ 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_UPCE_CHK:
+ if (first_len == 8) {
+ zfirst_len = 8;
+ }
+ if (first_len <= 7) {
+ zfirst_len = 7;
+ }
+ break;
+ case BARCODE_ISBNX:
+ if (first_len <= 9) {
+ zfirst_len = 9;
+ }
+ break;
+ }
+
+
+ /* Add leading zeroes */
+ for (i = 0; i < (zfirst_len - first_len); i++) {
+ strcat((char*) zfirst_part, "0");
+ }
+ strcat((char*) zfirst_part, (char*) first_part);
+ for (i = 0; i < (zsecond_len - second_len); i++) {
+ strcat((char*) zsecond_part, "0");
+ }
+ strcat((char*) zsecond_part, (char*) second_part);
+
+ /* Copy adjusted data back to local_source */
+ strcat((char*) local_source, (char*) zfirst_part);
+ if (ustrlen(zsecond_part)) {
+ strcat((char*) local_source, "+");
+ strcat((char*) local_source, (char*) 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;
+/* splits string to parts before and after '+' parts */
+INTERNAL int eanx(struct zint_symbol *symbol, unsigned char source[], int src_len) {
+ unsigned char first_part[20] = {0}, second_part[7] = {0}, dest[1000] = {0};
+ unsigned char local_source[20] = {0};
+ unsigned int latch, reader, writer, with_addon;
+ int error_number, i, plus_count;
+
+ with_addon = FALSE;
+ latch = FALSE;
+ writer = 0;
+
+ if (src_len > 19) {
+ strcpy(symbol->errtxt, "283: Input too long");
+ return ZINT_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 == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "284: Invalid characters in data");
+ return error_number;
+ }
+ } else {
+ error_number = is_sane("0123456789Xx+", source, src_len);
+ if (error_number == ZINT_ERROR_INVALID_DATA) {
+ strcpy(symbol->errtxt, "285: Invalid characters in input");
+ return error_number;
+ }
+ }
+
+ /* Check for multiple '+' characters */
+ plus_count = 0;
+ for (i = 0; i < src_len; i++) {
+ if (source[i] == '+') {
+ plus_count++;
+ }
+ }
+ if (plus_count > 1) {
+ strcpy(symbol->errtxt, "293: Invalid add-on data");
+ return ZINT_ERROR_INVALID_DATA;
+ }
+
+ /* 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 (local_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:
+ case BARCODE_EANX_CHK:
+ 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:
+ case 8: error_number = ean8(symbol, first_part, (char*) dest);
+ break;
+ case 12:
+ case 13: error_number = ean13(symbol, first_part, (char*) dest);
+ break;
+ default: strcpy(symbol->errtxt, "286: Invalid length input");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ 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 + 2, 67);
+ symbol->row_height[symbol->rows] = 2;
+ symbol->row_height[symbol->rows + 1] = 2;
+ symbol->row_height[symbol->rows + 2] = 2;
+ symbol->rows += 3;
+ error_number = 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;
+ error_number = ean13(symbol, first_part, (char*) dest);
+ break;
+ default: strcpy(symbol->errtxt, "287: Invalid length EAN input");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ break;
+ case BARCODE_UPCA:
+ case BARCODE_UPCA_CHK:
+ if ((ustrlen(first_part) == 11) || (ustrlen(first_part) == 12)) {
+ error_number = upca(symbol, first_part, (char*) dest);
+ } else {
+ strcpy(symbol->errtxt, "288: Input wrong length (C6I)");
+ return ZINT_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;
+ error_number = upca(symbol, first_part, (char*) dest);
+ } else {
+ strcpy(symbol->errtxt, "289: UPCA input wrong length");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ break;
+ case BARCODE_UPCE:
+ case BARCODE_UPCE_CHK:
+ if ((ustrlen(first_part) >= 6) && (ustrlen(first_part) <= (symbol->symbology == BARCODE_UPCE ? 7 : 8))) {
+ error_number = upce(symbol, first_part, (char*) dest);
+ } else {
+ strcpy(symbol->errtxt, "290: Input wrong length");
+ return ZINT_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;
+ error_number = upce(symbol, first_part, (char*) dest);
+ } else {
+ strcpy(symbol->errtxt, "291: UPCE input wrong length");
+ return ZINT_ERROR_TOO_LONG;
+ }
+ break;
+ case BARCODE_ISBNX:
+ error_number = isbn(symbol, first_part, ustrlen(first_part), (char*) dest);
+ break;
+ }
+
+ if (error_number > 4) {
+ return error_number;
+ }
+
+ switch (ustrlen(second_part)) {
+ case 0: break;
+ case 2:
+ add_on(second_part, (char*) dest, 1);
+ strcat((char*) symbol->text, "+");
+ strcat((char*) symbol->text, (char*) second_part);
+ break;
+ case 5:
+ add_on(second_part, (char*) dest, 1);
+ strcat((char*) symbol->text, "+");
+ strcat((char*) symbol->text, (char*) second_part);
+ break;
+ default:
+ strcpy(symbol->errtxt, "292: Invalid length input");
+ return ZINT_ERROR_TOO_LONG;
+ }
+
+ 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;
+ }
+
+ return 0;
}
-
-
-
-
diff --git a/backend/vector.c b/backend/vector.c
new file mode 100644
index 0000000..5313b60
--- /dev/null
+++ b/backend/vector.c
@@ -0,0 +1,823 @@
+/* vector.c - Creates vector image objects
+
+ libzint - the open source barcode library
+ Copyright (C) 2018 - 2020 Robin Stuart <rstuart114@gmail.com>
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the project nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ */
+/* vim: set ts=4 sw=4 et : */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#ifdef _MSC_VER
+#include <malloc.h>
+#endif
+
+#include "common.h"
+#include "output.h"
+
+INTERNAL int ps_plot(struct zint_symbol *symbol);
+INTERNAL int svg_plot(struct zint_symbol *symbol);
+INTERNAL int emf_plot(struct zint_symbol *symbol);
+
+static struct zint_vector_rect *vector_plot_create_rect(float x, float y, float width, float height) {
+ struct zint_vector_rect *rect;
+
+ rect = (struct zint_vector_rect*) malloc(sizeof (struct zint_vector_rect));
+ if (!rect) return NULL;
+
+ rect->next = NULL;
+ rect->x = x;
+ rect->y = y;
+ rect->width = width;
+ rect->height = height;
+ rect->colour = -1; // Default colour
+
+ return rect;
+}
+
+static int vector_plot_add_rect(struct zint_symbol *symbol, struct zint_vector_rect *rect, struct zint_vector_rect **last_rect) {
+ if (!rect) return ZINT_ERROR_MEMORY;
+ if (*last_rect)
+ (*last_rect)->next = rect;
+ else
+ symbol->vector->rectangles = rect; // first rectangle
+
+ *last_rect = rect;
+ return 1;
+}
+
+static struct zint_vector_hexagon *vector_plot_create_hexagon(float x, float y, float diameter) {
+ struct zint_vector_hexagon *hexagon;
+
+ hexagon = (struct zint_vector_hexagon*) malloc(sizeof (struct zint_vector_hexagon));
+ if (!hexagon) return NULL;
+ hexagon->next = NULL;
+ hexagon->x = x;
+ hexagon->y = y;
+ hexagon->diameter = (float)((diameter * 5.0) / 4.0); // Ugly kludge for legacy support
+
+ return hexagon;
+}
+
+static int vector_plot_add_hexagon(struct zint_symbol *symbol, struct zint_vector_hexagon *hexagon, struct zint_vector_hexagon **last_hexagon) {
+ if (!hexagon) return ZINT_ERROR_MEMORY;
+ if (*last_hexagon)
+ (*last_hexagon)->next = hexagon;
+ else
+ symbol->vector->hexagons = hexagon; // first hexagon
+
+ *last_hexagon = hexagon;
+ return 1;
+}
+
+static struct zint_vector_circle *vector_plot_create_circle(float x, float y, float diameter, int colour) {
+ struct zint_vector_circle *circle;
+
+ circle = (struct zint_vector_circle *) malloc(sizeof (struct zint_vector_circle));
+ if (!circle) return NULL;
+ circle->next = NULL;
+ circle->x = x;
+ circle->y = y;
+ circle->diameter = diameter;
+ circle->colour = colour;
+
+ return circle;
+}
+
+static int vector_plot_add_circle(struct zint_symbol *symbol, struct zint_vector_circle *circle, struct zint_vector_circle **last_circle) {
+ if (!circle) return ZINT_ERROR_MEMORY;
+ if (*last_circle)
+ (*last_circle)->next = circle;
+ else
+ symbol->vector->circles = circle; // first circle
+
+ *last_circle = circle;
+ return 1;
+}
+
+static int vector_plot_add_string(struct zint_symbol *symbol,
+ unsigned char *text, float x, float y, float fsize, float width,
+ struct zint_vector_string **last_string) {
+ struct zint_vector_string *string;
+
+ string = (struct zint_vector_string*) malloc(sizeof (struct zint_vector_string));
+ string->next = NULL;
+ string->x = x;
+ string->y = y;
+ string->width = width;
+ string->fsize = fsize;
+ string->length = ustrlen(text);
+ string->text = (unsigned char*) malloc(sizeof (unsigned char) * (ustrlen(text) + 1));
+ ustrcpy(string->text, text);
+
+ if (*last_string)
+ (*last_string)->next = string;
+ else
+ symbol->vector->strings = string; // First text portion
+ *last_string = string;
+
+ return 1;
+}
+
+INTERNAL void vector_free(struct zint_symbol *symbol) {
+ if (symbol->vector != NULL) {
+ struct zint_vector_rect *rect;
+ struct zint_vector_hexagon *hex;
+ struct zint_vector_circle *circle;
+ struct zint_vector_string *string;
+
+ // Free Rectangles
+ rect = symbol->vector->rectangles;
+ while (rect) {
+ struct zint_vector_rect *r = rect;
+ rect = rect->next;
+ free(r);
+ }
+
+ // Free Hexagons
+ hex = symbol->vector->hexagons;
+ while (hex) {
+ struct zint_vector_hexagon *h = hex;
+ hex = hex->next;
+ free(h);
+ }
+
+ // Free Circles
+ circle = symbol->vector->circles;
+ while (circle) {
+ struct zint_vector_circle *c = circle;
+ circle = circle->next;
+ free(c);
+ }
+
+ // Free Strings
+ string = symbol->vector->strings;
+ while (string) {
+ struct zint_vector_string *s = string;
+ string = string->next;
+ free(s->text);
+ free(s);
+ }
+
+ // Free vector
+ free(symbol->vector);
+ symbol->vector = NULL;
+ }
+}
+
+static void vector_scale(struct zint_symbol *symbol, int file_type) {
+ struct zint_vector_rect *rect;
+ struct zint_vector_hexagon *hex;
+ struct zint_vector_circle *circle;
+ struct zint_vector_string *string;
+ float scale = symbol->scale * 2.0f;
+
+ if ((file_type == OUT_EMF_FILE) && (symbol->symbology == BARCODE_MAXICODE)) {
+ // Increase size to overcome limitations in EMF file format
+ scale *= 20;
+ }
+
+ symbol->vector->width *= scale;
+ symbol->vector->height *= scale;
+
+ rect = symbol->vector->rectangles;
+ while (rect) {
+ rect->x *= scale;
+ rect->y *= scale;
+ rect->height *= scale;
+ rect->width *= scale;
+ rect = rect->next;
+ }
+
+ hex = symbol->vector->hexagons;
+ while (hex) {
+ hex->x *= scale;
+ hex->y *= scale;
+ hex->diameter *= scale;
+ hex = hex->next;
+ }
+
+ circle = symbol->vector->circles;
+ while (circle) {
+ circle->x *= scale;
+ circle->y *= scale;
+ circle->diameter *= scale;
+ circle = circle->next;
+ }
+
+ string = symbol->vector->strings;
+ while (string) {
+ string->x *= scale;
+ string->y *= scale;
+ string->width *= scale;
+ string->fsize *= scale;
+ string = string->next;
+ }
+ return;
+}
+
+static void vector_reduce_rectangles(struct zint_symbol *symbol) {
+ // Looks for vertically aligned rectangles and merges them together
+ struct zint_vector_rect *rect, *target, *prev;
+
+ rect = symbol->vector->rectangles;
+ while (rect) {
+ prev = rect;
+ target = prev->next;
+
+ while (target) {
+ if ((rect->x == target->x) && (rect->width == target->width) && ((rect->y + rect->height) == target->y) && (rect->colour == target->colour)) {
+ rect->height += target->height;
+ prev->next = target->next;
+ free(target);
+ } else {
+ prev = target;
+ }
+ target = prev->next;
+ }
+
+ rect = rect->next;
+ }
+
+ return;
+}
+
+INTERNAL int plot_vector(struct zint_symbol *symbol, int rotate_angle, int file_type) {
+ int error_number;
+ struct zint_vector *vector;
+ struct zint_vector_rect *rectangle, *rect, *last_rectangle = NULL;
+ struct zint_vector_hexagon *last_hexagon = NULL;
+ struct zint_vector_string *last_string = NULL;
+ struct zint_vector_circle *last_circle = NULL;
+
+ int i, r, latch;
+ float textpos, large_bar_height, preset_height, row_height, row_posn = 0.0;
+ float text_offset, text_height;
+ int xoffset, yoffset, textdone, main_symbol_width_x;
+ int roffset, boffset;
+ char addon[6];
+ int large_bar_count, symbol_lead_in;
+ float addon_text_posn;
+ float default_text_posn;
+ int hide_text = 0;
+ int upceanflag = 0;
+ int rect_count, last_row_start;
+ int this_row;
+ int addon_latch = 0;
+ struct zint_vector_string *string;
+
+ (void)rotate_angle; /* Not currently implemented */
+
+ // Sanity check colours
+ error_number = check_colour_options(symbol);
+ if (error_number != 0) {
+ return error_number;
+ }
+
+ // Free any previous rendering structures
+ vector_free(symbol);
+
+ // Allocate memory
+ vector = symbol->vector = (struct zint_vector *) malloc(sizeof (struct zint_vector));
+ if (!vector) return ZINT_ERROR_MEMORY;
+ vector->rectangles = NULL;
+ vector->hexagons = NULL;
+ vector->circles = NULL;
+ vector->strings = NULL;
+
+ row_height = 0;
+ textdone = 0;
+ main_symbol_width_x = symbol->width;
+ strcpy(addon, "");
+ symbol_lead_in = 0;
+ addon_text_posn = 0.0;
+ rect_count = 0;
+ last_row_start = 0;
+
+ /*
+ * Determine if there will be any addon texts and text height
+ */
+ latch = 0;
+ r = 0;
+ /* Isolate add-on text */
+ if (is_extendable(symbol->symbology)) {
+ for (i = 0; i < (int) ustrlen(symbol->text); i++) {
+ if (latch == 1) {
+ addon[r] = symbol->text[i];
+ r++;
+ }
+ if (symbol->text[i] == '+') {
+ latch = 1;
+ }
+ }
+ }
+ addon[r] = '\0';
+
+
+ /*
+ * Calculate the width of the barcode, especially if there are any extra
+ * borders or white space to add.
+ */
+
+ if (is_composite(symbol->symbology)) {
+ while (!(module_is_set(symbol, symbol->rows - 1, symbol_lead_in))) {
+ symbol_lead_in++;
+ }
+ }
+
+ /* Certain symbols need whitespace otherwise characters get chopped off the sides */
+ if ((symbol->symbology == BARCODE_EANX) || (symbol->symbology == BARCODE_EANX_CHK)
+ || (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_symbol_width_x = 96 + symbol_lead_in;
+ upceanflag = 13;
+ break;
+ case 2:
+ main_symbol_width_x = 22 + symbol_lead_in;
+ upceanflag = 2;
+ break;
+ case 5:
+ main_symbol_width_x = 49 + symbol_lead_in;
+ upceanflag = 5;
+ break;
+ default:
+ main_symbol_width_x = 68 + symbol_lead_in;
+ upceanflag = 8;
+ }
+ } else if ((symbol->symbology == BARCODE_UPCA) || (symbol->symbology == BARCODE_UPCA_CHK)
+ || (symbol->symbology == BARCODE_UPCA_CC)) {
+ upceanflag = 12;
+ if (symbol->whitespace_width == 0) {
+ symbol->whitespace_width = 10;
+ }
+ main_symbol_width_x = 96 + symbol_lead_in;
+ } else if ((symbol->symbology == BARCODE_UPCE) || (symbol->symbology == BARCODE_UPCE_CHK)
+ || (symbol->symbology == BARCODE_UPCE_CC)) {
+ upceanflag = 6;
+ if (symbol->whitespace_width == 0) {
+ symbol->whitespace_width = 10;
+ }
+ main_symbol_width_x = 51 + symbol_lead_in;
+ }
+
+ if ((!symbol->show_hrt) || (ustrlen(symbol->text) == 0)) {
+ hide_text = 1;
+ text_height = 0.0;
+ text_offset = upceanflag ? 9.0f : 0.0f;
+ } else {
+ text_height = upceanflag ? 11.0f : 9.0f;
+ text_offset = 9.0;
+ }
+ if (symbol->output_options & SMALL_TEXT)
+ text_height *= 0.8f;
+
+ set_whitespace_offsets(symbol, &xoffset, &yoffset, &roffset, &boffset);
+
+ // Determine if height should be overridden
+ 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++;
+ }
+ }
+
+ vector->width = (float)ceil(symbol->width + (xoffset + roffset));
+ vector->height = (float)ceil(symbol->height + text_offset + (yoffset + boffset));
+
+ large_bar_height = large_bar_count ? (symbol->height - preset_height) / large_bar_count : 0 /*Not used if large_bar_count zero*/;
+
+ if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) {
+ default_text_posn = symbol->height + text_offset + symbol->border_width + symbol->border_width;
+ } else {
+ default_text_posn = symbol->height + text_offset;
+ }
+
+ // Plot rectangles - most symbols created here
+ if ((symbol->symbology != BARCODE_MAXICODE) && ((symbol->output_options & BARCODE_DOTTY_MODE) == 0)) {
+ for (r = 0; r < symbol->rows; r++) {
+ this_row = r;
+ last_row_start = rect_count;
+ if (symbol->row_height[this_row] == 0) {
+ row_height = large_bar_height;
+ } else {
+ row_height = (float)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;
+
+ do {
+ int block_width = 0;
+ do {
+ block_width++;
+ } while (i + block_width < symbol->width && module_is_set(symbol, this_row, i + block_width) == module_is_set(symbol, this_row, i));
+ if ((addon_latch == 0) && (r == (symbol->rows - 1)) && (i > main_symbol_width_x)) {
+ addon_text_posn = row_posn + 8.0f;
+ addon_latch = 1;
+ }
+ if (module_is_set(symbol, this_row, i)) {
+ /* a bar or colour block */
+ if (addon_latch == 0) {
+ rectangle = vector_plot_create_rect((float)(i + xoffset), row_posn, (float)block_width, row_height);
+ if (symbol->symbology == BARCODE_ULTRA) {
+ rectangle->colour = module_is_set(symbol, this_row, i);
+ }
+ } else {
+ rectangle = vector_plot_create_rect((float)(i + xoffset), row_posn + 10.0f, (float)block_width, row_height - 5.0f);
+ }
+ vector_plot_add_rect(symbol, rectangle, &last_rectangle);
+ rect_count++;
+ }
+ i += block_width;
+
+ } while (i < symbol->width);
+ }
+ }
+
+ // Plot Maxicode symbols
+ if (symbol->symbology == BARCODE_MAXICODE) {
+ struct zint_vector_circle *circle;
+ vector->width = 37.0f + (xoffset + roffset);
+ vector->height = 36.0f + (yoffset + boffset);
+
+ // Bullseye
+ circle = vector_plot_create_circle(17.88f + xoffset, 17.8f + yoffset, 10.85f, 0);
+ vector_plot_add_circle(symbol, circle, &last_circle);
+ circle = vector_plot_create_circle(17.88f + xoffset, 17.8f + yoffset, 8.97f, 1);
+ vector_plot_add_circle(symbol, circle, &last_circle);
+ circle = vector_plot_create_circle(17.88f + xoffset, 17.8f + yoffset, 7.10f, 0);
+ vector_plot_add_circle(symbol, circle, &last_circle);
+ circle = vector_plot_create_circle(17.88f + xoffset, 17.8f + yoffset, 5.22f, 1);
+ vector_plot_add_circle(symbol, circle, &last_circle);
+ circle = vector_plot_create_circle(17.88f + xoffset, 17.8f + yoffset, 3.31f, 0);
+ vector_plot_add_circle(symbol, circle, &last_circle);
+ circle = vector_plot_create_circle(17.88f + xoffset, 17.8f + yoffset, 1.43f, 1);
+ vector_plot_add_circle(symbol, circle, &last_circle);
+
+ /* Hexagons */
+ for (r = 0; r < symbol->rows; r++) {
+ for (i = 0; i < symbol->width; i++) {
+ if (module_is_set(symbol, r, i)) {
+ //struct zint_vector_hexagon *hexagon = vector_plot_create_hexagon(((i * 0.88) + ((r & 1) ? 1.76 : 1.32)), ((r * 0.76) + 0.76), symbol->dot_size);
+ struct zint_vector_hexagon *hexagon = vector_plot_create_hexagon(((i * 1.23f) + 0.615f + ((r & 1) ? 0.615f : 0.0f)) + xoffset,
+ ((r * 1.067f) + 0.715f) + yoffset, symbol->dot_size);
+ vector_plot_add_hexagon(symbol, hexagon, &last_hexagon);
+ }
+ }
+ }
+ }
+
+ // Dotty mode
+ if ((symbol->symbology != BARCODE_MAXICODE) && (symbol->output_options & BARCODE_DOTTY_MODE)) {
+ for (r = 0; r < symbol->rows; r++) {
+ for (i = 0; i < symbol->width; i++) {
+ if (module_is_set(symbol, r, i)) {
+ struct zint_vector_circle *circle = vector_plot_create_circle(i + 0.5f + xoffset, r + 0.5f + yoffset, 1.0f, 0);
+ vector_plot_add_circle(symbol, circle, &last_circle);
+ }
+ }
+ }
+ }
+
+ /* Guard bar extension */
+ if (upceanflag == 6) {
+ i = 0;
+ for (rect = symbol->vector->rectangles; rect != NULL; rect = rect->next) {
+ switch (i - last_row_start) {
+ case 0:
+ case 1:
+ case 14:
+ case 15:
+ case 16:
+ rect->height += 5.0;
+ break;
+ }
+ i++;
+ }
+ }
+
+ if (upceanflag == 8) {
+ i = 0;
+ for (rect = symbol->vector->rectangles; rect != NULL; rect = rect->next) {
+ switch (i - last_row_start) {
+ case 0:
+ case 1:
+ case 10:
+ case 11:
+ case 20:
+ case 21:
+ rect->height += 5.0;
+ break;
+ }
+ i++;
+ }
+ }
+
+ if (upceanflag == 12) {
+ i = 0;
+ for (rect = symbol->vector->rectangles; rect != NULL; rect = rect->next) {
+ switch (i - last_row_start) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 14:
+ case 15:
+ case 26:
+ case 27:
+ case 28:
+ case 29:
+ rect->height += 5.0;
+ break;
+ }
+ i++;
+ }
+ }
+
+ if (upceanflag == 13) {
+ i = 0;
+ for (rect = symbol->vector->rectangles; rect != NULL; rect = rect->next) {
+ switch (i - last_row_start) {
+ case 0:
+ case 1:
+ case 14:
+ case 15:
+ case 28:
+ case 29:
+ rect->height += 5.0;
+ break;
+ }
+ i++;
+ }
+ }
+
+ /* Add the text */
+
+ if (!hide_text) {
+ char textpart[10];
+ float textwidth;
+
+ xoffset += symbol_lead_in;
+
+ if (upceanflag == 8) {
+ for (i = 0; i < 4; i++) {
+ textpart[i] = symbol->text[i];
+ }
+ textpart[4] = '\0';
+ textpos = 17;
+ textwidth = 4.0 * 8.5;
+ vector_plot_add_string(symbol, (unsigned char *) textpart, textpos + xoffset, default_text_posn, text_height, textwidth, &last_string);
+ for (i = 0; i < 4; i++) {
+ textpart[i] = symbol->text[i + 4];
+ }
+ textpart[4] = '\0';
+ textpos = 50;
+ vector_plot_add_string(symbol, (unsigned char *) textpart, (textpos + xoffset), default_text_posn, text_height, textwidth, &last_string);
+ textdone = 1;
+ switch (strlen(addon)) {
+ case 2:
+ textpos = (float)(xoffset + 86);
+ textwidth = 2.0f * 8.5f;
+ vector_plot_add_string(symbol, (unsigned char *) addon, textpos, addon_text_posn, text_height, textwidth, &last_string);
+ break;
+ case 5:
+ textpos = (float)(xoffset + 100);
+ textwidth = 5.0f * 8.5f;
+ vector_plot_add_string(symbol, (unsigned char *) addon, textpos, addon_text_posn, text_height, textwidth, &last_string);
+ break;
+ }
+
+ }
+
+ if (upceanflag == 13) {
+ textpart[0] = symbol->text[0];
+ textpart[1] = '\0';
+ textpos = -5; // 7
+ textwidth = 8.5;
+ vector_plot_add_string(symbol, (unsigned char *) textpart, textpos + xoffset, default_text_posn, text_height, textwidth, &last_string);
+
+ for (i = 0; i < 6; i++) {
+ textpart[i] = symbol->text[i + 1];
+ }
+ textpart[6] = '\0';
+ textpos = 25;
+ textwidth = 6.0 * 8.5;
+ vector_plot_add_string(symbol, (unsigned char *) textpart, textpos + xoffset, default_text_posn, text_height, textwidth, &last_string);
+ for (i = 0; i < 6; i++) {
+ textpart[i] = symbol->text[i + 7];
+ }
+ textpart[6] = '\0';
+ textpos = 72;
+ vector_plot_add_string(symbol, (unsigned char *) textpart, textpos + xoffset, default_text_posn, text_height, textwidth, &last_string);
+ textdone = 1;
+ switch (strlen(addon)) {
+ case 2:
+ textpos = (float)(xoffset + 114);
+ textwidth = 2.0f * 8.5f;
+ vector_plot_add_string(symbol, (unsigned char *) addon, textpos, addon_text_posn, text_height, textwidth, &last_string);
+ break;
+ case 5:
+ textpos = (float)(xoffset + 128);
+ textwidth = 5.0f * 8.5f;
+ vector_plot_add_string(symbol, (unsigned char *) addon, textpos, addon_text_posn, text_height, textwidth, &last_string);
+ break;
+ }
+ }
+
+ if (upceanflag == 12) {
+ textpart[0] = symbol->text[0];
+ textpart[1] = '\0';
+ textpos = -5;
+ textwidth = 6.2f;
+ vector_plot_add_string(symbol, (unsigned char *) textpart, textpos + xoffset, default_text_posn - 2.0f, text_height * (8.0f / 11.0f), textwidth, &last_string);
+ for (i = 0; i < 5; i++) {
+ textpart[i] = symbol->text[i + 1];
+ }
+ textpart[5] = '\0';
+ textpos = 27;
+ textwidth = 5.0f * 8.5f;
+ vector_plot_add_string(symbol, (unsigned char *) textpart, textpos + xoffset, default_text_posn, text_height, textwidth, &last_string);
+ for (i = 0; i < 5; i++) {
+ textpart[i] = symbol->text[i + 6];
+ }
+ textpos = 68;
+ vector_plot_add_string(symbol, (unsigned char *) textpart, textpos + xoffset, default_text_posn, text_height, textwidth, &last_string);
+ textpart[0] = symbol->text[11];
+ textpart[1] = '\0';
+ textpos = 100;
+ textwidth = 6.2f;
+ vector_plot_add_string(symbol, (unsigned char *) textpart, textpos + xoffset, default_text_posn - 2.0f, text_height * (8.0f / 11.0f), textwidth, &last_string);
+ textdone = 1;
+ switch (strlen(addon)) {
+ case 2:
+ textpos = (float)(xoffset + 116);
+ textwidth = 2.0f * 8.5f;
+ vector_plot_add_string(symbol, (unsigned char *) addon, textpos, addon_text_posn, text_height, textwidth, &last_string);
+ break;
+ case 5:
+ textpos = (float)(xoffset + 130);
+ textwidth = 5.0f * 8.5f;
+ vector_plot_add_string(symbol, (unsigned char *) addon, textpos, addon_text_posn, text_height, textwidth, &last_string);
+ break;
+ }
+ }
+
+ if (upceanflag == 6) {
+ textpart[0] = symbol->text[0];
+ textpart[1] = '\0';
+ textpos = -5;
+ textwidth = 6.2f;
+ vector_plot_add_string(symbol, (unsigned char *) textpart, textpos + xoffset, default_text_posn - 2.0f, text_height * (8.0f / 11.0f), textwidth, &last_string);
+ for (i = 0; i < 6; i++) {
+ textpart[i] = symbol->text[i + 1];
+ }
+ textpart[6] = '\0';
+ textpos = 24;
+ textwidth = 6.0 * 8.5;
+ vector_plot_add_string(symbol, (unsigned char *) textpart, textpos + xoffset, default_text_posn, text_height, textwidth, &last_string);
+ textpart[0] = symbol->text[7];
+ textpart[1] = '\0';
+ textpos = 55;
+ textwidth = 6.2f;
+ vector_plot_add_string(symbol, (unsigned char *) textpart, textpos + xoffset, default_text_posn - 2.0f, text_height * (8.0f / 11.0f), textwidth, &last_string);
+ textdone = 1;
+ switch (strlen(addon)) {
+ case 2:
+ textpos = (float)(xoffset + 70);
+ textwidth = 2.0f * 8.5f;
+ vector_plot_add_string(symbol, (unsigned char *) addon, textpos, addon_text_posn, text_height, textwidth, &last_string);
+ break;
+ case 5:
+ textpos = (float)(xoffset + 84);
+ textwidth = 5.0f * 8.5f;
+ vector_plot_add_string(symbol, (unsigned char *) addon, textpos, addon_text_posn, text_height, textwidth, &last_string);
+ break;
+ }
+ }
+
+ /* Put normal human readable text at the bottom (and centered) */
+ if (textdone == 0) {
+ // caculate start xoffset to center text
+ vector_plot_add_string(symbol, symbol->text, (symbol->width / 2.0f) + xoffset, default_text_posn, text_height, (float)symbol->width, &last_string);
+ }
+
+ xoffset -= symbol_lead_in; // Restore xoffset
+ }
+
+ //Remove control characters from readable text
+ // This only applies to Code 128
+ string = symbol->vector->strings;
+ if (string) {
+ for (i = 0; i < string->length; i++) {
+ if (string->text[i] < ' ') {
+ string->text[i] = ' ';
+ }
+ }
+ }
+
+ // Binding and boxes
+ if ((symbol->output_options & BARCODE_BIND) != 0) {
+ if ((symbol->rows > 1) && (is_stackable(symbol->symbology) == 1)) {
+ double sep_height = 1;
+ if (symbol->option_3 > 0 && symbol->option_3 <= 4) {
+ sep_height = symbol->option_3;
+ }
+ /* row binding */
+ for (r = 1; r < symbol->rows; r++) {
+ if (symbol->symbology != BARCODE_CODABLOCKF && symbol->symbology != BARCODE_HIBC_BLOCKF) {
+ rectangle = vector_plot_create_rect((float)xoffset, (r * row_height) + yoffset - sep_height / 2, (float)symbol->width, sep_height);
+ vector_plot_add_rect(symbol, rectangle, &last_rectangle);
+ } else {
+ /* Avoid 11-module start and 13-module stop chars */
+ rectangle = vector_plot_create_rect(xoffset + 11, (r * row_height) + yoffset - sep_height / 2, symbol->width - 24, sep_height);
+ vector_plot_add_rect(symbol, rectangle, &last_rectangle);
+ }
+ }
+ }
+ }
+ if ((symbol->output_options & BARCODE_BOX) || (symbol->output_options & BARCODE_BIND)) {
+ // Top
+ rectangle = vector_plot_create_rect(0.0f, 0.0f, vector->width, (float)symbol->border_width);
+ if (!(symbol->output_options & BARCODE_BOX) && (symbol->symbology == BARCODE_CODABLOCKF || symbol->symbology == BARCODE_HIBC_BLOCKF)) {
+ rectangle->x = (float)xoffset;
+ rectangle->width -= (2.0f * xoffset);
+ }
+ vector_plot_add_rect(symbol, rectangle, &last_rectangle);
+ // Bottom
+ rectangle = vector_plot_create_rect(0.0f, vector->height - symbol->border_width - text_offset, vector->width, (float)symbol->border_width);
+ if (!(symbol->output_options & BARCODE_BOX) && (symbol->symbology == BARCODE_CODABLOCKF || symbol->symbology == BARCODE_HIBC_BLOCKF)) {
+ rectangle->x = (float)xoffset;
+ rectangle->width -= (2.0f * xoffset);
+ }
+ vector_plot_add_rect(symbol, rectangle, &last_rectangle);
+ }
+ if (symbol->output_options & BARCODE_BOX) {
+ // Left
+ rectangle = vector_plot_create_rect(0.0f, 0.0f, (float)symbol->border_width, vector->height - text_offset);
+ vector_plot_add_rect(symbol, rectangle, &last_rectangle);
+ // Right
+ rectangle = vector_plot_create_rect(vector->width - symbol->border_width, 0.0f, (float)symbol->border_width, vector->height - text_offset);
+ vector_plot_add_rect(symbol, rectangle, &last_rectangle);
+ }
+
+ vector_reduce_rectangles(symbol);
+
+ vector_scale(symbol, file_type);
+
+ switch (file_type) {
+ case OUT_EPS_FILE:
+ error_number = ps_plot(symbol);
+ break;
+ case OUT_SVG_FILE:
+ error_number = svg_plot(symbol);
+ break;
+ case OUT_EMF_FILE:
+ error_number = emf_plot(symbol);
+ break;
+ /* case OUT_BUFFER: No more work needed */
+ }
+
+ return error_number;
+}
diff --git a/backend/zint.def b/backend/zint.def
deleted file mode 100644
index 262390f..0000000
--- a/backend/zint.def
+++ /dev/null
@@ -1,27 +0,0 @@
-;------------------------------------------
-; LIBZINT module definition file for Windows
-;------------------------------------------
-
-LIBRARY
-
-EXPORTS
-;Version 2.4.3
-DllGetVersion
-
-ZBarcode_Create
-ZBarcode_Clear
-ZBarcode_Delete
-
-ZBarcode_Encode
-ZBarcode_Encode_File
-ZBarcode_Print
-ZBarcode_Encode_and_Print
-ZBarcode_Encode_File_and_Print
-
-ZBarcode_Render
-
-ZBarcode_Buffer
-ZBarcode_Encode_and_Buffer
-ZBarcode_Encode_File_and_Buffer
-
-ZBarcode_ValidID \ No newline at end of file
diff --git a/backend/zint.h b/backend/zint.h
index 1efb96e..4d28369 100644
--- a/backend/zint.h
+++ b/backend/zint.h
@@ -1,7 +1,7 @@
/* zint.h - definitions for libzint
libzint - the open source barcode library
- Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
+ Copyright (C) 2009-2020 Robin Stuart <rstuart114@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -27,7 +27,8 @@
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.
-*/
+ */
+/* vim: set ts=4 sw=4 et : */
#ifndef ZINT_H
#define ZINT_H
@@ -36,222 +37,304 @@
extern "C" {
#endif /* __cplusplus */
-#include <stdio.h>
-
-struct zint_render_line {
- float x, y, length, width;
- struct zint_render_line *next; /* Pointer to next line */
-};
-
-struct zint_render_string {
- float x, y, fsize;
- float width; /* Suggested string width, may be 0 if none recommended */
- int length;
- unsigned char *text;
- struct zint_render_string *next; /* Pointer to next character */
-};
-
-struct zint_render_ring {
- float x, y, radius, line_width;
- struct zint_render_ring *next; /* Pointer to next ring */
-};
-
-struct zint_render_hexagon {
- float x, y;
- struct zint_render_hexagon *next; /* Pointer to next hexagon */
-};
-
-struct zint_render {
- float width, height;
- struct zint_render_line *lines; /* Pointer to first line */
- struct zint_render_string *strings; /* Pointer to first string */
- struct zint_render_ring *rings; /* Pointer to first ring */
- struct zint_render_hexagon *hexagons; /* Pointer to first hexagon */
-};
-
-struct zint_symbol {
- int symbology;
- int height;
- int whitespace_width;
- int border_width;
- int output_options;
-#define ZINT_COLOUR_SIZE 10
- char fgcolour[ZINT_COLOUR_SIZE];
- char bgcolour[ZINT_COLOUR_SIZE];
- char outfile[FILENAME_MAX];
- float scale;
- int option_1;
- int option_2;
- int option_3;
- int show_hrt;
- int input_mode;
-#define ZINT_TEXT_SIZE 128
- unsigned char text[ZINT_TEXT_SIZE];
- int rows;
- int width;
-#define ZINT_PRIMARY_SIZE 128
- char primary[ZINT_PRIMARY_SIZE];
-#define ZINT_ROWS_MAX 178
-#define ZINT_COLS_MAX 178
- unsigned char encoded_data[ZINT_ROWS_MAX][ZINT_COLS_MAX];
- int row_height[ZINT_ROWS_MAX]; /* Largest symbol is 177x177 QR Code */
-#define ZINT_ERR_SIZE 100
- char errtxt[ZINT_ERR_SIZE];
- char *bitmap;
- int bitmap_width;
- int bitmap_height;
- struct zint_render *rendered;
-};
-
-
-/* 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 SMALL_TEXT 32
-
-#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
+ struct zint_render_line {
+ float x, y, length, width;
+ struct zint_render_line *next; /* Pointer to next line */
+ };
+
+ struct zint_vector_rect {
+ float x, y, height, width;
+ int colour;
+ struct zint_vector_rect *next;
+ };
+
+ struct zint_render_string {
+ float x, y, fsize;
+ float width; /* Suggested string width, may be 0 if none recommended */
+ int length;
+ unsigned char *text;
+ struct zint_render_string *next; /* Pointer to next character */
+ };
+
+ struct zint_vector_string {
+ float x, y, fsize;
+ float width; /* Suggested string width, may be 0 if none recommended */
+ int length;
+ unsigned char *text;
+ struct zint_vector_string *next; /* Pointer to next character */
+ };
+
+ struct zint_render_ring {
+ float x, y, radius, line_width;
+ struct zint_render_ring *next; /* Pointer to next ring */
+ };
+
+ struct zint_vector_circle {
+ float x, y, diameter;
+ int colour;
+ struct zint_vector_circle *next; /* Pointer to next circle */
+ };
+
+ struct zint_render_hexagon {
+ float x, y, height;
+ struct zint_render_hexagon *next; /* Pointer to next hexagon */
+ };
+
+ struct zint_vector_hexagon {
+ float x, y, diameter;
+ struct zint_vector_hexagon *next; /* Pointer to next hexagon */
+ };
+
+ struct zint_render {
+ float width, height;
+ struct zint_render_line *lines; /* Pointer to first line */
+ struct zint_render_string *strings; /* Pointer to first string */
+ struct zint_render_ring *rings; /* Pointer to first ring */
+ struct zint_render_hexagon *hexagons; /* Pointer to first hexagon */
+ };
+
+ struct zint_vector {
+ float width, height;
+ struct zint_vector_rect *rectangles; /* Pointer to first rectangle */
+ struct zint_vector_hexagon *hexagons; /* Pointer to first hexagon */
+ struct zint_vector_string *strings; /* Points to first string */
+ struct zint_vector_circle *circles; /* Points to first circle */
+ };
+
+ 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 fontsize;
+ int input_mode;
+ int eci;
+ unsigned char text[128];
+ int rows;
+ int width;
+ char primary[128];
+ unsigned char encoded_data[200][143];
+ int row_height[200]; /* Largest symbol is 189 x 189 Han Xin */
+ char errtxt[100];
+ unsigned char *bitmap;
+ int bitmap_width;
+ int bitmap_height;
+ unsigned int bitmap_byte_length;
+ float dot_size;
+ struct zint_vector *vector;
+ struct zint_render *rendered;
+ int debug;
+ };
+
+#define ZINT_VERSION_MAJOR 2
+#define ZINT_VERSION_MINOR 8
+#define ZINT_VERSION_RELEASE 0
+
+ /* 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_EANX_CHK 14
+#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_UPCA_CHK 35
+#define BARCODE_UPCE 37
+#define BARCODE_UPCE_CHK 38
+#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_VIN 73
+#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
+
+ /* Tbarcode 10 codes */
+#define BARCODE_DOTCODE 115
+#define BARCODE_HANXIN 116
+
+ /*Tbarcode 11 codes*/
+#define BARCODE_MAILMARK 121
+
+ /* 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_UPNQR 143
+#define BARCODE_ULTRA 144
+#define BARCODE_RMQR 145
+
+// Output options
+#define BARCODE_NO_ASCII 1
+#define BARCODE_BIND 2
+#define BARCODE_BOX 4
+#define BARCODE_STDOUT 8
+#define READER_INIT 16
+#define SMALL_TEXT 32
+#define BOLD_TEXT 64
+#define CMYK_COLOUR 128
+#define BARCODE_DOTTY_MODE 256
+#define GS1_GS_SEPARATOR 512
+
+// Input data types
+#define DATA_MODE 0
+#define UNICODE_MODE 1
+#define GS1_MODE 2
+#define ESCAPE_MODE 8
+
+// Data Matrix specific options (option_3)
+#define DM_SQUARE 100
+#define DM_DMRE 101
+
+// QR, Han Xin, Grid Matrix specific options (option_3)
+#define ZINT_FULL_MULTIBYTE 200
+
+// Ultracode specific option (option_3)
+#define ULTRA_COMPRESSION 128
+
+// Warning and error conditions
+#define ZINT_WARN_INVALID_OPTION 2
+#define ZINT_WARN_USES_ECI 3
+#define ZINT_ERROR_TOO_LONG 5
+#define ZINT_ERROR_INVALID_DATA 6
+#define ZINT_ERROR_INVALID_CHECK 7
+#define ZINT_ERROR_INVALID_OPTION 8
+#define ZINT_ERROR_ENCODING_PROBLEM 9
+#define ZINT_ERROR_FILE_ACCESS 10
+#define ZINT_ERROR_MEMORY 11
+
+// Raster file types
+#define OUT_BUFFER 0
+#define OUT_SVG_FILE 10
+#define OUT_EPS_FILE 20
+#define OUT_EMF_FILE 30
+#define OUT_PNG_FILE 100
+#define OUT_BMP_FILE 120
+#define OUT_GIF_FILE 140
+#define OUT_PCX_FILE 160
+#define OUT_JPG_FILE 180
+#define OUT_TIF_FILE 200
+
+// Debug flags
+#define ZINT_DEBUG_PRINT 1
+#define ZINT_DEBUG_TEST 2
#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
+#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
+#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 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_Render(struct zint_symbol *symbol, float width, float height);
+ ZINT_EXTERN int ZBarcode_Encode(struct zint_symbol *symbol, const unsigned char *source, int in_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_Buffer(struct zint_symbol *symbol, int rotate_angle);
+ ZINT_EXTERN int ZBarcode_Buffer_Vector(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_and_Buffer_Vector(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_Encode_File_and_Buffer_Vector(struct zint_symbol *symbol, char *filename, int rotate_angle);
-ZINT_EXTERN int ZBarcode_ValidID(int symbol_id);
+ ZINT_EXTERN int ZBarcode_ValidID(int symbol_id);
+ ZINT_EXTERN int ZBarcode_Version();
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ZINT_H */
+
diff --git a/packaging/zint.spec b/packaging/zint.spec
index 7ff387b..73f0b58 100644
--- a/packaging/zint.spec
+++ b/packaging/zint.spec
@@ -1,6 +1,6 @@
Name: zint
-Version: 2.4.3
-Release: 14
+Version: 2.7.1
+Release: 1
Summary: Barcode generator library
License: BSD-3-Clause
URL: http://www.zint.org.uk
@@ -22,7 +22,7 @@ Features of the library:
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.
+- Output in the following file formats: PNG, GIF, EPS, WMF, BMP, TIF, SVG.
- Verification stage for SBN, ISBN and ISBN-13 data.