Removed old Data Matrix standards

Removed Data Matrix ECC 000 to 140 because (a) they don't work properly and (b) nobody uses them anyway!
Also removed some ghosts of Codablock-F - there are some more to find.
This commit is contained in:
Robin Stuart 2010-06-16 09:00:31 +01:00
parent 35e3c76785
commit 81b4902c95
12 changed files with 1064 additions and 3339 deletions

View File

@ -7,7 +7,7 @@ find_package(PNG)
set(zint_COMMON_SRCS common.c library.c render.c ps.c large.c reedsol.c gs1.c svg.c png.c)
set(zint_ONEDIM_SRCS code.c code128.c 2of5.c upcean.c telepen.c medical.c plessey.c rss.c)
set(zint_POSTAL_SRCS postal.c auspost.c imail.c)
set(zint_TWODIM_SRCS code16k.c dmatrix.c dm200.c pdf417.c qr.c maxicode.c composite.c aztec.c code49.c code1.c gridmtx.c)
set(zint_TWODIM_SRCS code16k.c dmatrix.c pdf417.c qr.c maxicode.c composite.c aztec.c code49.c code1.c gridmtx.c)
set(zint_SRCS ${zint_COMMON_SRCS} ${zint_ONEDIM_SRCS} ${zint_POSTAL_SRCS} ${zint_TWODIM_SRCS} )
if(PNG_FOUND)

View File

@ -1,881 +0,0 @@
/* dm200.c Handles Data Matrix ECC 200 symbols */
/*
libzint - the open source barcode library
Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
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>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#ifdef _MSC_VER
#include <malloc.h>
#endif
#include "reedsol.h"
#include "common.h"
#include "dm200.h"
// Annex M placement alorithm low level
static void ecc200placementbit(int *array, int NR, int NC, int r, int c, int p, char b)
{
if (r < 0) {
r += NR;
c += 4 - ((NR + 4) % 8);
}
if (c < 0) {
c += NC;
r += 4 - ((NC + 4) % 8);
}
array[r * NC + c] = (p << 3) + b;
}
static void ecc200placementblock(int *array, int NR, int NC, int r,
int c, int p)
{
ecc200placementbit(array, NR, NC, r - 2, c - 2, p, 7);
ecc200placementbit(array, NR, NC, r - 2, c - 1, p, 6);
ecc200placementbit(array, NR, NC, r - 1, c - 2, p, 5);
ecc200placementbit(array, NR, NC, r - 1, c - 1, p, 4);
ecc200placementbit(array, NR, NC, r - 1, c - 0, p, 3);
ecc200placementbit(array, NR, NC, r - 0, c - 2, p, 2);
ecc200placementbit(array, NR, NC, r - 0, c - 1, p, 1);
ecc200placementbit(array, NR, NC, r - 0, c - 0, p, 0);
}
static void ecc200placementcornerA(int *array, int NR, int NC, int p)
{
ecc200placementbit(array, NR, NC, NR - 1, 0, p, 7);
ecc200placementbit(array, NR, NC, NR - 1, 1, p, 6);
ecc200placementbit(array, NR, NC, NR - 1, 2, p, 5);
ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4);
ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3);
ecc200placementbit(array, NR, NC, 1, NC - 1, p, 2);
ecc200placementbit(array, NR, NC, 2, NC - 1, p, 1);
ecc200placementbit(array, NR, NC, 3, NC - 1, p, 0);
}
static void ecc200placementcornerB(int *array, int NR, int NC, int p)
{
ecc200placementbit(array, NR, NC, NR - 3, 0, p, 7);
ecc200placementbit(array, NR, NC, NR - 2, 0, p, 6);
ecc200placementbit(array, NR, NC, NR - 1, 0, p, 5);
ecc200placementbit(array, NR, NC, 0, NC - 4, p, 4);
ecc200placementbit(array, NR, NC, 0, NC - 3, p, 3);
ecc200placementbit(array, NR, NC, 0, NC - 2, p, 2);
ecc200placementbit(array, NR, NC, 0, NC - 1, p, 1);
ecc200placementbit(array, NR, NC, 1, NC - 1, p, 0);
}
static void ecc200placementcornerC(int *array, int NR, int NC, int p)
{
ecc200placementbit(array, NR, NC, NR - 3, 0, p, 7);
ecc200placementbit(array, NR, NC, NR - 2, 0, p, 6);
ecc200placementbit(array, NR, NC, NR - 1, 0, p, 5);
ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4);
ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3);
ecc200placementbit(array, NR, NC, 1, NC - 1, p, 2);
ecc200placementbit(array, NR, NC, 2, NC - 1, p, 1);
ecc200placementbit(array, NR, NC, 3, NC - 1, p, 0);
}
static void ecc200placementcornerD(int *array, int NR, int NC, int p)
{
ecc200placementbit(array, NR, NC, NR - 1, 0, p, 7);
ecc200placementbit(array, NR, NC, NR - 1, NC - 1, p, 6);
ecc200placementbit(array, NR, NC, 0, NC - 3, p, 5);
ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4);
ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3);
ecc200placementbit(array, NR, NC, 1, NC - 3, p, 2);
ecc200placementbit(array, NR, NC, 1, NC - 2, p, 1);
ecc200placementbit(array, NR, NC, 1, NC - 1, p, 0);
}
// Annex M placement alorithm main function
static void ecc200placement(int *array, int NR, int NC)
{
int r, c, p;
// invalidate
for (r = 0; r < NR; r++)
for (c = 0; c < NC; c++)
array[r * NC + c] = 0;
// start
p = 1;
r = 4;
c = 0;
do {
// check corner
if (r == NR && !c)
ecc200placementcornerA(array, NR, NC, p++);
if (r == NR - 2 && !c && NC % 4)
ecc200placementcornerB(array, NR, NC, p++);
if (r == NR - 2 && !c && (NC % 8) == 4)
ecc200placementcornerC(array, NR, NC, p++);
if (r == NR + 4 && c == 2 && !(NC % 8))
ecc200placementcornerD(array, NR, NC, p++);
// up/right
do {
if (r < NR && c >= 0 && !array[r * NC + c])
ecc200placementblock(array, NR, NC, r, c, p++);
r -= 2;
c += 2;
}
while (r >= 0 && c < NC);
r++;
c += 3;
// down/left
do {
if (r >= 0 && c < NC && !array[r * NC + c])
ecc200placementblock(array, NR, NC, r, c, p++);
r += 2;
c -= 2;
}
while (r < NR && c >= 0);
r += 3;
c++;
}
while (r < NR || c < NC);
// unfilled corner
if (!array[NR * NC - 1])
array[NR * NC - 1] = array[NR * NC - NC - 2] = 1;
}
// calculate and append ecc code, and if necessary interleave
static void ecc200(unsigned char *binary, int bytes, int datablock, int rsblock)
{
int blocks = (bytes + 2) / datablock, b;
rs_init_gf(0x12d);
rs_init_code(rsblock, 1);
for (b = 0; b < blocks; b++) {
unsigned char buf[256], ecc[256];
int n, p = 0;
for (n = b; n < bytes; n += blocks)
buf[p++] = binary[n];
rs_encode(p, buf, ecc);
p = rsblock - 1; // comes back reversed
for (n = b; n < rsblock * blocks; n += blocks)
binary[bytes + n] = ecc[p--];
}
rs_free();
}
int isx12(unsigned char source)
{
if(source == 13) { return 1; }
if(source == 42) { return 1; }
if(source == 62) { return 1; }
if(source == 32) { return 1; }
if((source >= '0') && (source <= '9')) { return 1; }
if((source >= 'A') && (source <= 'Z')) { return 1; }
return 0;
}
void dminsert(char binary_string[], int posn, char newbit)
{ /* Insert a character into the middle of a string at position posn */
int i, end;
end = strlen(binary_string);
for(i = end; i > posn; i--) {
binary_string[i] = binary_string[i - 1];
}
binary_string[posn] = newbit;
}
void insert_value(unsigned char binary_stream[], int posn, int streamlen, char newbit)
{
int i;
for(i = streamlen; i > posn; i--) {
binary_stream[i] = binary_stream[i - 1];
}
binary_stream[posn] = newbit;
}
int look_ahead_test(unsigned char source[], int sourcelen, int position, int current_mode, int gs1)
{
/* A custom version of the 'look ahead test' from Annex P */
/* This version is deliberately very reluctant to end a data stream with EDIFACT encoding */
float ascii_count, c40_count, text_count, x12_count, edf_count, b256_count, best_count;
int sp, done, best_scheme;
char reduced_char;
/* step (j) */
if(current_mode == DM_ASCII) {
ascii_count = 0.0;
c40_count = 1.0;
text_count = 1.0;
x12_count = 1.0;
edf_count = 1.0;
b256_count = 1.25;
} else {
ascii_count = 1.0;
c40_count = 2.0;
text_count = 2.0;
x12_count = 2.0;
edf_count = 2.0;
b256_count = 2.25;
}
switch(current_mode) {
case DM_C40: c40_count = 0.0; break;
case DM_TEXT: text_count = 0.0; break;
case DM_X12: x12_count = 0.0; break;
case DM_EDIFACT: edf_count = 0.0; break;
case DM_BASE256: b256_count = 0.0; break;
}
for(sp = position; (sp < sourcelen) && (sp <= (position + 8)); sp++) {
if(source[sp] <= 127) { reduced_char = source[sp]; } else { reduced_char = source[sp] - 127; }
if((source[sp] >= '0') && (source[sp] <= '9')) { ascii_count += 0.5; } else { ascii_count += 1.0; }
if(source[sp] > 127) { ascii_count += 1.0; }
done = 0;
if(reduced_char == ' ') { c40_count += (2.0 / 3.0); done = 1; }
if((reduced_char >= '0') && (reduced_char <= '9')) { c40_count += (2.0 / 3.0); done = 1; }
if((reduced_char >= 'A') && (reduced_char <= 'Z')) { c40_count += (2.0 / 3.0); done = 1; }
if(source[sp] > 127) { c40_count += (4.0 / 3.0); }
if(done == 0) { c40_count += (4.0 / 3.0); }
done = 0;
if(reduced_char == ' ') { text_count += (2.0 / 3.0); done = 1; }
if((reduced_char >= '0') && (reduced_char <= '9')) { text_count += (2.0 / 3.0); done = 1; }
if((reduced_char >= 'a') && (reduced_char <= 'z')) { text_count += (2.0 / 3.0); done = 1; }
if(source[sp] > 127) { text_count += (4.0 / 3.0); }
if(done == 0) { text_count += (4.0 / 3.0); }
if(isx12(source[sp])) { x12_count += (2.0 / 3.0); } else { x12_count += 4.0; }
/* step (p) */
done = 0;
if((source[sp] >= ' ') && (source[sp] <= '^')) { edf_count += (3.0 / 4.0); } else { edf_count += 6.0; }
if(gs1 && (source[sp] == '[')) { edf_count += 6.0; }
if(sp >= (sourcelen - 5)) { edf_count += 6.0; } /* MMmmm fudge! */
/* step (q) */
if(gs1 && (source[sp] == '[')) { b256_count += 4.0; } else { b256_count += 1.0; }
/* printf("%c lat a%.2f c%.2f t%.2f x%.2f e%.2f b%.2f\n", source[sp], ascii_count, c40_count, text_count, x12_count, edf_count, b256_count); */
}
best_count = ascii_count;
best_scheme = DM_ASCII;
if(b256_count <= best_count) {
best_count = b256_count;
best_scheme = DM_BASE256;
}
if(edf_count <= best_count) {
best_count = edf_count;
best_scheme = DM_EDIFACT;
}
if(text_count <= best_count) {
best_count = text_count;
best_scheme = DM_TEXT;
}
if(x12_count <= best_count) {
best_count = x12_count;
best_scheme = DM_X12;
}
if(c40_count <= best_count) {
best_count = c40_count;
best_scheme = DM_C40;
}
return best_scheme;
}
int dm200encode(struct zint_symbol *symbol, unsigned char source[], unsigned char target[], int *last_mode, int length)
{
/* Encodes data using ASCII, C40, Text, X12, EDIFACT or Base 256 modes as appropriate */
/* Supports encoding FNC1 in supporting systems */
int sp, tp, i, gs1;
int current_mode, next_mode;
int inputlen = length;
int c40_buffer[6], c40_p;
int text_buffer[6], text_p;
int x12_buffer[6], x12_p;
int edifact_buffer[8], edifact_p;
int debug = 0;
#ifndef _MSC_VER
char binary[2 * inputlen];
#else
char* binary = (char*)_alloca(2 * inputlen);
#endif
sp = 0;
tp = 0;
memset(c40_buffer, 0, 6);
c40_p = 0;
memset(text_buffer, 0, 6);
text_p = 0;
memset(x12_buffer, 0, 6);
x12_p = 0;
memset(edifact_buffer, 0, 8);
edifact_p = 0;
strcpy(binary, "");
/* step (a) */
current_mode = DM_ASCII;
next_mode = DM_ASCII;
if(symbol->input_mode == GS1_MODE) { gs1 = 1; } else { gs1 = 0; }
if(gs1) {
target[tp] = 232; tp++;
concat(binary, " ");
if(debug) printf("FN1 ");
} /* FNC1 */
if(symbol->output_options & READER_INIT) {
if(gs1) {
strcpy(symbol->errtxt, "Cannot encode in GS1 mode and Reader Initialisation at the same time");
return ERROR_INVALID_OPTION;
} else {
target[tp] = 234; tp++; /* Reader Programming */
concat(binary, " ");
if(debug) printf("RP ");
}
}
while (sp < inputlen) {
current_mode = next_mode;
/* step (b) - ASCII encodation */
if(current_mode == DM_ASCII) {
next_mode = DM_ASCII;
if(istwodigits(source, sp) && ((sp + 1) != inputlen)) {
target[tp] = (10 * ctoi(source[sp])) + ctoi(source[sp + 1]) + 130;
if(debug) printf("N%d ", target[tp] - 130);
tp++; concat(binary, " ");
sp += 2;
} else {
next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
if(next_mode != DM_ASCII) {
switch(next_mode) {
case DM_C40: target[tp] = 230; tp++; concat(binary, " ");
if(debug) printf("C40 "); break;
case DM_TEXT: target[tp] = 239; tp++; concat(binary, " ");
if(debug) printf("TEX "); break;
case DM_X12: target[tp] = 238; tp++; concat(binary, " ");
if(debug) printf("X12 "); break;
case DM_EDIFACT: target[tp] = 240; tp++; concat(binary, " ");
if(debug) printf("EDI "); break;
case DM_BASE256: target[tp] = 231; tp++; concat(binary, " ");
if(debug) printf("BAS "); break;
}
} else {
if(source[sp] > 127) {
target[tp] = 235; /* FNC4 */
if(debug) printf("FN4 ");
tp++;
target[tp] = (source[sp] - 128) + 1;
if(debug) printf("A%02X ", target[tp] - 1);
tp++; concat(binary, " ");
} else {
if(gs1 && (source[sp] == '[')) {
target[tp] = 232; /* FNC1 */
if(debug) printf("FN1 ");
} else {
target[tp] = source[sp] + 1;
if(debug) printf("A%02X ", target[tp] - 1);
}
tp++;
concat(binary, " ");
}
sp++;
}
}
}
/* step (c) C40 encodation */
if(current_mode == DM_C40) {
int shift_set, value;
next_mode = DM_C40;
if(c40_p == 0) {
next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
}
if(next_mode != DM_C40) {
target[tp] = 254; tp++; concat(binary, " ");/* Unlatch */
next_mode = DM_ASCII;
if (debug) printf("ASC ");
} else {
if(source[sp] > 127) {
c40_buffer[c40_p] = 1; c40_p++;
c40_buffer[c40_p] = 30; c40_p++; /* Upper Shift */
shift_set = c40_shift[source[sp] - 128];
value = c40_value[source[sp] - 128];
} else {
shift_set = c40_shift[source[sp]];
value = c40_value[source[sp]];
}
if(gs1 && (source[sp] == '[')) {
shift_set = 2;
value = 27; /* FNC1 */
}
if(shift_set != 0) {
c40_buffer[c40_p] = shift_set - 1; c40_p++;
}
c40_buffer[c40_p] = value; c40_p++;
if(c40_p >= 3) {
int iv;
iv = (1600 * c40_buffer[0]) + (40 * c40_buffer[1]) + (c40_buffer[2]) + 1;
target[tp] = iv / 256; tp++;
target[tp] = iv % 256; tp++;
concat(binary, " ");
if (debug) printf("[%d %d %d] ", c40_buffer[0], c40_buffer[1], c40_buffer[2]);
c40_buffer[0] = c40_buffer[3];
c40_buffer[1] = c40_buffer[4];
c40_buffer[2] = c40_buffer[5];
c40_buffer[3] = 0;
c40_buffer[4] = 0;
c40_buffer[5] = 0;
c40_p -= 3;
}
sp++;
}
}
/* step (d) Text encodation */
if(current_mode == DM_TEXT) {
int shift_set, value;
next_mode = DM_TEXT;
if(text_p == 0) {
next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
}
if(next_mode != DM_TEXT) {
target[tp] = 254; tp++; concat(binary, " ");/* Unlatch */
next_mode = DM_ASCII;
if (debug) printf("ASC ");
} else {
if(source[sp] > 127) {
text_buffer[text_p] = 1; text_p++;
text_buffer[text_p] = 30; text_p++; /* Upper Shift */
shift_set = text_shift[source[sp] - 128];
value = text_value[source[sp] - 128];
} else {
shift_set = text_shift[source[sp]];
value = text_value[source[sp]];
}
if(gs1 && (source[sp] == '[')) {
shift_set = 2;
value = 27; /* FNC1 */
}
if(shift_set != 0) {
text_buffer[text_p] = shift_set - 1; text_p++;
}
text_buffer[text_p] = value; text_p++;
if(text_p >= 3) {
int iv;
iv = (1600 * text_buffer[0]) + (40 * text_buffer[1]) + (text_buffer[2]) + 1;
target[tp] = iv / 256; tp++;
target[tp] = iv % 256; tp++;
concat(binary, " ");
if (debug) printf("[%d %d %d] ", text_buffer[0], text_buffer[1], text_buffer[2]);
text_buffer[0] = text_buffer[3];
text_buffer[1] = text_buffer[4];
text_buffer[2] = text_buffer[5];
text_buffer[3] = 0;
text_buffer[4] = 0;
text_buffer[5] = 0;
text_p -= 3;
}
sp++;
}
}
/* step (e) X12 encodation */
if(current_mode == DM_X12) {
int value = 0;
next_mode = DM_X12;
if(text_p == 0) {
next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
}
if(next_mode != DM_X12) {
target[tp] = 254; tp++; concat(binary, " ");/* Unlatch */
next_mode = DM_ASCII;
if (debug) printf("ASC ");
} else {
if(source[sp] == 13) { value = 0; }
if(source[sp] == '*') { value = 1; }
if(source[sp] == '>') { value = 2; }
if(source[sp] == ' ') { value = 3; }
if((source[sp] >= '0') && (source[sp] <= '9')) { value = (source[sp] - '0') + 4; }
if((source[sp] >= 'A') && (source[sp] <= 'Z')) { value = (source[sp] - 'A') + 14; }
x12_buffer[x12_p] = value; x12_p++;
if(x12_p >= 3) {
int iv;
iv = (1600 * x12_buffer[0]) + (40 * x12_buffer[1]) + (x12_buffer[2]) + 1;
target[tp] = iv / 256; tp++;
target[tp] = iv % 256; tp++;
concat(binary, " ");
if (debug) printf("[%d %d %d] ", x12_buffer[0], x12_buffer[1], x12_buffer[2]);
x12_buffer[0] = x12_buffer[3];
x12_buffer[1] = x12_buffer[4];
x12_buffer[2] = x12_buffer[5];
x12_buffer[3] = 0;
x12_buffer[4] = 0;
x12_buffer[5] = 0;
x12_p -= 3;
}
sp++;
}
}
/* step (f) EDIFACT encodation */
if(current_mode == DM_EDIFACT) {
int value = 0;
next_mode = DM_EDIFACT;
if(edifact_p == 3) {
next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
}
if(next_mode != DM_EDIFACT) {
edifact_buffer[edifact_p] = 31; edifact_p++;
next_mode = DM_ASCII;
} else {
if((source[sp] >= '@') && (source[sp] <= '^')) { value = source[sp] - '@'; }
if((source[sp] >= ' ') && (source[sp] <= '?')) { value = source[sp]; }
edifact_buffer[edifact_p] = value; edifact_p++;
sp++;
}
if(edifact_p >= 4) {
target[tp] = (edifact_buffer[0] << 2) + ((edifact_buffer[1] & 0x30) >> 4); tp++;
target[tp] = ((edifact_buffer[1] & 0x0f) << 4) + ((edifact_buffer[2] & 0x3c) >> 2); tp++;
target[tp] = ((edifact_buffer[2] & 0x03) << 6) + edifact_buffer[3]; tp++;
concat(binary, " ");
if (debug) printf("[%d %d %d %d] ", edifact_buffer[0], edifact_buffer[1], edifact_buffer[2], edifact_buffer[3]);
edifact_buffer[0] = edifact_buffer[4];
edifact_buffer[1] = edifact_buffer[5];
edifact_buffer[2] = edifact_buffer[6];
edifact_buffer[3] = edifact_buffer[7];
edifact_buffer[4] = 0;
edifact_buffer[5] = 0;
edifact_buffer[6] = 0;
edifact_buffer[7] = 0;
edifact_p -= 4;
}
}
/* step (g) Base 256 encodation */
if(current_mode == DM_BASE256) {
next_mode = look_ahead_test(source, inputlen, sp, current_mode, gs1);
if(next_mode == DM_BASE256) {
target[tp] = source[sp];
if(debug) printf("B%02X ", target[tp]);
tp++;
sp++;
concat(binary, "b");
} else {
next_mode = DM_ASCII;
if(debug) printf("ASC ");
}
}
if(tp > 1558) {
return 0;
}
} /* while */
/* Empty buffers */
if(c40_p == 2) {
target[tp] = 254; tp++; /* unlatch */
target[tp] = source[inputlen - 2] + 1; tp++;
target[tp] = source[inputlen - 1] + 1; tp++;
concat(binary, " ");
if(debug) printf("ASC A%02X A%02X ", target[tp - 2] - 1, target[tp - 1] - 1);
current_mode = DM_ASCII;
}
if(c40_p == 1) {
target[tp] = 254; tp++; /* unlatch */
target[tp] = source[inputlen - 1] + 1; tp++;
concat(binary, " ");
if(debug) printf("ASC A%02X ", target[tp - 1] - 1);
current_mode = DM_ASCII;
}
if(text_p == 2) {
target[tp] = 254; tp++; /* unlatch */
target[tp] = source[inputlen - 2] + 1; tp++;
target[tp] = source[inputlen - 1] + 1; tp++;
concat(binary, " ");
if(debug) printf("ASC A%02X A%02X ", target[tp - 2] - 1, target[tp - 1] - 1);
current_mode = DM_ASCII;
}
if(text_p == 1) {
target[tp] = 254; tp++; /* unlatch */
target[tp] = source[inputlen - 1] + 1; tp++;
concat(binary, " ");
if(debug) printf("ASC A%02X ", target[tp - 1] - 1);
current_mode = DM_ASCII;
}
if(x12_p == 2) {
target[tp] = 254; tp++; /* unlatch */
target[tp] = source[inputlen - 2] + 1; tp++;
target[tp] = source[inputlen - 1] + 1; tp++;
concat(binary, " ");
if(debug) printf("ASC A%02X A%02X ", target[tp - 2] - 1, target[tp - 1] - 1);
current_mode = DM_ASCII;
}
if(x12_p == 1) {
target[tp] = 254; tp++; /* unlatch */
target[tp] = source[inputlen - 1] + 1; tp++;
concat(binary, " ");
if(debug) printf("ASC A%02X ", target[tp - 1] - 1);
current_mode = DM_ASCII;
}
/* Add length and randomising algorithm to b256 */
i = 0;
while (i < tp) {
if(binary[i] == 'b') {
if((i == 0) || ((i != 0) && (binary[i - 1] != 'b'))) {
/* start of binary data */
int binary_count; /* length of b256 data */
for(binary_count = 0; binary[binary_count + i] == 'b'; binary_count++);
if(binary_count <= 249) {
dminsert(binary, i, 'b');
insert_value(target, i, tp, binary_count); tp++;
} else {
dminsert(binary, i, 'b');
dminsert(binary, i + 1, 'b');
insert_value(target, i, tp, (binary_count / 250) + 249); tp++;
insert_value(target, i + 1, tp, binary_count % 250); tp++;
}
}
}
i++;
}
for(i = 0; i < tp; i++) {
if(binary[i] == 'b') {
int prn, temp;
prn = ((149 * (i + 1)) % 255) + 1;
temp = target[i] + prn;
if (temp <= 255) { target[i] = temp; } else { target[i] = temp - 256; }
}
}
if(debug) {
printf("\n\n");
for(i = 0; i < tp; i++){
printf("%02X ", target[i]);
}
printf("\n");
}
*(last_mode) = current_mode;
return tp;
}
void add_tail(unsigned char target[], int tp, int tail_length, int last_mode)
{
/* adds unlatch and pad bits */
int i, prn, temp;
switch(last_mode) {
case DM_C40:
case DM_TEXT:
case DM_X12:
target[tp] = 254; tp++; /* Unlatch */
tail_length--;
}
for(i = tail_length; i > 0; i--) {
if(i == tail_length) {
target[tp] = 129; tp++; /* Pad */
} else {
prn = ((149 * (tp + 1)) % 253) + 1;
temp = 129 + prn;
if(temp <= 254) {
target[tp] = temp; tp++;
} else {
target[tp] = temp - 254; tp++;
}
}
}
}
int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], int length)
{
int inputlen, i;
unsigned char binary[2000];
int binlen;
int symbolsize, optionsize, calcsize;
int taillength, error_number = 0;
int H, W, FH, FW, datablock, bytes, rsblock;
int last_mode;
unsigned char *grid = 0;
inputlen = length;
binlen = dm200encode(symbol, source, binary, &last_mode, length);
if(binlen == 0) {
strcpy(symbol->errtxt, "Data too long to fit in symbol");
return ERROR_TOO_LONG;
}
if((symbol->option_2 >= 1) && (symbol->option_2 <= 30)) {
optionsize = intsymbol[symbol->option_2 - 1];
} else {
optionsize = -1;
}
calcsize = 29;
for(i = 29; i > -1; i--) {
if(matrixbytes[i] > binlen) {
calcsize = i;
}
}
if(symbol->option_3 == DM_SQUARE) {
/* Force to use square symbol */
switch(calcsize) {
case 2:
case 4:
case 6:
case 9:
case 11:
case 14:
calcsize++;
}
}
symbolsize = optionsize;
if(calcsize > optionsize) {
symbolsize = calcsize;
if(optionsize != -1) {
/* flag an error */
error_number = WARN_INVALID_OPTION;
strcpy(symbol->errtxt, "Data does not fit in selected symbol size");
}
}
H = matrixH[symbolsize];
W = matrixW[symbolsize];
FH = matrixFH[symbolsize];
FW = matrixFW[symbolsize];
bytes = matrixbytes[symbolsize];
datablock = matrixdatablock[symbolsize];
rsblock = matrixrsblock[symbolsize];
taillength = bytes - binlen;
if(taillength != 0) {
add_tail(binary, binlen, taillength, last_mode);
}
// ecc code
ecc200(binary, bytes, datablock, rsblock);
{ // placement
int x, y, NC, NR, *places;
NC = W - 2 * (W / FW);
NR = H - 2 * (H / FH);
places = (int*)malloc(NC * NR * sizeof(int));
ecc200placement(places, NR, NC);
grid = (unsigned char*)malloc(W * H);
memset(grid, 0, W * H);
for (y = 0; y < H; y += FH) {
for (x = 0; x < W; x++)
grid[y * W + x] = 1;
for (x = 0; x < W; x += 2)
grid[(y + FH - 1) * W + x] = 1;
}
for (x = 0; x < W; x += FW) {
for (y = 0; y < H; y++)
grid[y * W + x] = 1;
for (y = 0; y < H; y += 2)
grid[y * W + x + FW - 1] = 1;
}
for (y = 0; y < NR; y++) {
for (x = 0; x < NC; x++) {
int v = places[(NR - y - 1) * NC + x];
//fprintf (stderr, "%4d", v);
if (v == 1 || (v > 7 && (binary[(v >> 3) - 1] & (1 << (v & 7)))))
grid[(1 + y + 2 * (y / (FH - 2))) * W + 1 + x + 2 * (x / (FW - 2))] = 1;
}
//fprintf (stderr, "\n");
}
for(y = H - 1; y >= 0; y--) {
int x;
for(x = 0; x < W; x++) {
if(grid[W * y + x]) {
set_module(symbol, (H - y) - 1, x);
}
}
symbol->row_height[(H - y) - 1] = 1;
}
free(grid);
free(places);
}
symbol->rows = H;
symbol->width = W;
return error_number;
}

View File

@ -1,101 +0,0 @@
/* dm200.h - Handles Data Matrix ECC 200 */
/*
libzint - the open source barcode library
Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "common.h"
#ifndef __IEC16022ECC200_H
#define __IEC16022ECC200_H
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
extern int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], int length);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#define MAXBARCODE 3116
#define DM_ASCII 1
#define DM_C40 2
#define DM_TEXT 3
#define DM_X12 4
#define DM_EDIFACT 5
#define DM_BASE256 6
static int c40_shift[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
static int c40_value[] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,4,5,6,7,8,9,10,11,12,13,
15,16,17,18,19,20,21,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
22,23,24,25,26,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 };
static int text_shift[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3 };
static int text_value[] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,4,5,6,7,8,9,10,11,12,13,
15,16,17,18,19,20,21,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,
22,23,24,25,26,0,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,27,28,29,30,31 };
static int intsymbol[] = {
0,1,3,5,7,8,10,12,13,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,2,4,6,9,11,14 };
static int matrixH[] = {
10, 12, 8, 14, 8, 16, 12, 18, 20, 12, 22, 16, 24, 26, 16, 32, 36, 40, 44, 48,
52, 64, 72, 80, 88, 96, 104, 120, 132, 144 };
static int matrixW[] = {
10, 12, 18, 14, 32, 16, 26, 18, 20, 36, 22, 36, 24, 26, 48, 32, 36, 40, 44,
48, 52, 64, 72, 80, 88, 96, 104, 120, 132, 144 };
static int matrixFH[] = {
10, 12, 8, 14, 8, 16, 12, 18, 20, 12, 22, 16, 24, 26, 16, 16, 18, 20, 22, 24,
26, 16, 18, 20, 22, 24, 26, 20, 22, 24 };
static int matrixFW[] = {
10, 12, 18, 14, 16, 16, 26, 18, 20, 18, 22, 18, 24, 26, 24, 16, 18, 20, 22,
24, 26, 16, 18, 20, 22, 24, 26, 20, 22, 24 };
static int matrixbytes[] = {
3, 5, 5, 8, 10, 12, 16, 18, 22, 22, 30, 32, 36, 44, 49, 62, 86, 114, 144,
174, 204, 280, 368, 456, 576, 696, 816, 1050, 1304, 1558 };
static int matrixdatablock[] = {
3, 5, 5, 8, 10, 12, 16, 18, 22, 22, 30, 32, 36, 44, 49, 62, 86, 114, 144,
174, 102, 140, 92, 114, 144, 174, 136, 175, 163, 156 };
static int matrixrsblock[] = {
5, 7, 7, 10, 11, 12, 14, 14, 18, 18, 20, 24, 24, 28, 28, 36, 42, 48, 56, 68,
42, 56, 36, 48, 56, 68, 56, 68, 62, 62 };
#endif /* __IEC16022ECC200_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
/* dmatrix.h - Data Matrix ECC 000 - 150 tables */
/* dmatrix.h - Handles Data Matrix ECC 200 */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <robin@zint.org.uk>
Copyright (C) 2009 Robin Stuart <robin@zint.org.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -19,653 +19,83 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* Data taken from ISO/IEC 16022:2006 Annex H "ECC 000 - 140 data module placement grids" */
#include "common.h"
int tableh1[] = { /* 7 x 7 data */
2,45,10,38,24,21,1,
12,40,26,5,33,19,47,
22,31,29,15,43,8,36,
34,20,48,13,41,27,6,
44,9,37,23,17,30,16,
39,25,4,32,18,46,11,
0,28,14,42,7,35,3
};
#ifndef __IEC16022ECC200_H
#define __IEC16022ECC200_H
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
int tableh2[] = { /* 9 x 9 data */
2,19,55,10,46,28,64,73,1,
62,17,53,35,71,8,80,44,26,
49,31,67,4,76,40,22,58,13,
69,6,78,42,24,60,15,51,33,
74,38,20,56,11,47,29,65,37,
25,61,16,52,34,70,7,79,43,
12,48,30,66,63,75,39,21,57,
32,68,5,77,41,23,59,14,50,
0,72,36,18,54,9,45,27,3
};
extern int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], int length);
int tableh3[] = { /* 11 x 11 data */
2,26,114,70,15,103,59,37,81,4,1,
117,73,18,106,62,40,84,7,95,51,29,
12,100,56,34,78,92,89,45,23,111,67,
65,43,87,10,98,54,32,120,76,21,109,
82,5,93,49,27,115,71,16,104,60,38,
96,52,30,118,74,19,107,63,41,85,8,
24,112,68,13,101,57,35,79,48,90,46,
75,20,108,64,42,86,9,97,53,31,119,
102,58,36,80,77,91,47,25,113,69,14,
39,83,6,94,50,28,116,72,17,105,61,
0,88,44,22,110,66,11,99,55,33,3
};
#ifdef __cplusplus
}
#endif /* __cplusplus */
int tableh4[] = { /* 13 x 13 data */
2,159,29,133,81,16,120,68,42,146,94,91,1,
37,141,89,24,128,76,50,154,102,11,115,63,167,
83,18,122,70,44,148,96,5,109,57,161,31,135,
125,73,47,151,99,8,112,60,164,34,138,86,21,
40,144,92,107,105,53,157,27,131,79,14,118,66,
103,12,116,64,168,38,142,90,25,129,77,51,155,
110,58,162,32,136,84,19,123,71,45,149,97,6,
165,35,139,87,22,126,74,48,152,100,9,113,61,
132,80,15,119,67,41,145,93,55,106,54,158,28,
23,127,75,49,153,101,10,114,62,166,36,140,88,
69,43,147,95,4,108,56,160,30,134,82,17,121,
150,98,7,111,59,163,33,137,85,20,124,72,46,
0,104,52,156,26,130,78,13,117,65,39,143,3
};
#define MAXBARCODE 3116
int tableh5[] = { /* 15 x 15 data */
2,187,37,157,97,217,22,142,82,202,52,172,112,7,1,
41,161,101,221,26,146,86,206,56,176,116,11,131,71,191,
93,213,18,138,78,198,48,168,108,105,123,63,183,33,153,
28,148,88,208,58,178,118,13,133,73,193,43,163,103,223,
80,200,50,170,110,5,125,65,185,35,155,95,215,20,140,
54,174,114,9,129,69,189,39,159,99,219,24,144,84,204,
106,127,121,61,181,31,151,91,211,16,136,76,196,46,166,
134,74,194,44,164,104,224,29,149,89,209,59,179,119,14,
186,36,156,96,216,21,141,81,201,51,171,111,6,126,66,
160,100,220,25,145,85,205,55,175,115,10,130,70,190,40,
212,17,137,77,197,47,167,107,67,122,62,182,32,152,92,
147,87,207,57,177,117,12,132,72,192,42,162,102,222,27,
199,49,169,109,4,124,64,184,34,154,94,214,19,139,79,
173,113,8,128,68,188,38,158,98,218,23,143,83,203,53,
0,120,60,180,30,150,90,210,15,135,75,195,45,165,3
};
#define DM_ASCII 1
#define DM_C40 2
#define DM_TEXT 3
#define DM_X12 4
#define DM_EDIFACT 5
#define DM_BASE256 6
int tableh6[] = { /* 17 x 17 data */
2,69,205,35,171,103,239,18,154,86,222,52,188,120,256,273,1,
220,50,186,118,254,33,169,101,237,67,203,135,271,16,288,152,84,
178,110,246,25,161,93,229,59,195,127,263,8,280,144,76,212,42,
250,29,165,97,233,63,199,131,267,12,284,148,80,216,46,182,114,
157,89,225,55,191,123,259,4,276,140,72,208,38,174,106,242,21,
235,65,201,133,269,14,286,150,82,218,48,184,116,252,31,167,99,
193,125,261,6,278,142,74,210,40,176,108,244,23,159,91,227,57,
265,10,282,146,78,214,44,180,112,248,27,163,95,231,61,197,129,
274,138,70,206,36,172,104,240,19,155,87,223,53,189,121,257,137,
83,219,49,185,117,253,32,168,100,236,66,202,134,270,15,287,151,
41,177,109,245,24,160,92,228,58,194,126,262,7,279,143,75,211,
113,249,28,164,96,232,62,198,130,266,11,283,147,79,215,45,181,
20,156,88,224,54,190,122,258,255,275,139,71,207,37,173,105,241,
98,234,64,200,132,268,13,285,149,81,217,47,183,115,251,30,166,
56,192,124,260,5,277,141,73,209,39,175,107,243,22,158,90,226,
128,264,9,281,145,77,213,43,179,111,247,26,162,94,230,60,196,
0,272,136,68,204,34,170,102,238,17,153,85,221,51,187,119,3
};
static int c40_shift[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
int tableh7[] = { /* 19 x 19 data */
2,82,234,44,348,196,120,272,25,329,177,101,253,63,215,139,291,6,1,
239,49,353,201,125,277,30,334,182,106,258,68,220,144,296,11,315,163,87,
343,191,115,267,20,324,172,96,248,58,210,134,286,310,305,153,77,229,39,
132,284,37,341,189,113,265,75,227,151,303,18,322,170,94,246,56,360,208,
28,332,180,104,256,66,218,142,294,9,313,161,85,237,47,351,199,123,275,
185,109,261,71,223,147,299,14,318,166,90,242,52,356,204,128,280,33,337,
251,61,213,137,289,4,308,156,80,232,42,346,194,118,270,23,327,175,99,
225,149,301,16,320,168,92,244,54,358,206,130,282,35,339,187,111,263,73,
292,7,311,159,83,235,45,349,197,121,273,26,330,178,102,254,64,216,140,
316,164,88,240,50,354,202,126,278,31,335,183,107,259,69,221,145,297,12,
78,230,40,344,192,116,268,21,325,173,97,249,59,211,135,287,158,306,154,
55,359,207,131,283,36,340,188,112,264,74,226,150,302,17,321,169,93,245,
198,122,274,27,331,179,103,255,65,217,141,293,8,312,160,84,236,46,350,
279,32,336,184,108,260,70,222,146,298,13,317,165,89,241,51,355,203,127,
326,174,98,250,60,212,136,288,285,307,155,79,231,41,345,193,117,269,22,
110,262,72,224,148,300,15,319,167,91,243,53,357,205,129,281,34,338,186,
62,214,138,290,5,309,157,81,233,43,347,195,119,271,24,328,176,100,252,
143,295,10,314,162,86,238,48,352,200,124,276,29,333,181,105,257,67,219,
0,304,152,76,228,38,342,190,114,266,19,323,171,95,247,57,209,133,3
};
static int c40_value[] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,4,5,6,7,8,9,10,11,12,13,
15,16,17,18,19,20,21,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
22,23,24,25,26,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 };
int tableh8[] = { /* 21 x 21 data */
2,88,424,256,46,382,214,130,298,25,361,193,109,277,67,403,235,151,319,4,1,
437,269,59,395,227,143,311,38,374,206,122,290,80,416,248,164,332,17,353,185,101,
49,385,217,133,301,28,364,196,112,280,70,406,238,154,322,7,343,175,91,427,259,
222,138,306,33,369,201,117,285,75,411,243,159,327,12,348,180,96,432,264,54,390,
295,22,358,190,106,274,64,400,232,148,316,340,337,169,85,421,253,43,379,211,127,
377,209,125,293,83,419,251,167,335,20,356,188,104,440,272,62,398,230,146,314,41,
115,283,73,409,241,157,325,10,346,178,94,430,262,52,388,220,136,304,31,367,199,
78,414,246,162,330,15,351,183,99,435,267,57,393,225,141,309,36,372,204,120,288,
236,152,320,5,341,173,89,425,257,47,383,215,131,299,26,362,194,110,278,68,404,
333,18,354,186,102,438,270,60,396,228,144,312,39,375,207,123,291,81,417,249,165,
344,176,92,428,260,50,386,218,134,302,29,365,197,113,281,71,407,239,155,323,8,
97,433,265,55,391,223,139,307,34,370,202,118,286,76,412,244,160,328,13,349,181,
254,44,380,212,128,296,23,359,191,107,275,65,401,233,149,317,172,338,170,86,422,
397,229,145,313,40,376,208,124,292,82,418,250,166,334,19,355,187,103,439,271,61,
135,303,30,366,198,114,282,72,408,240,156,324,9,345,177,93,429,261,51,387,219,
35,371,203,119,287,77,413,245,161,329,14,350,182,98,434,266,56,392,224,140,308,
192,108,276,66,402,234,150,318,315,339,171,87,423,255,45,381,213,129,297,24,360,
289,79,415,247,163,331,16,352,184,100,436,268,58,394,226,142,310,37,373,205,121,
405,237,153,321,6,342,174,90,426,258,48,384,216,132,300,27,363,195,111,279,69,
158,326,11,347,179,95,431,263,53,389,221,137,305,32,368,200,116,284,74,410,242,
0,336,168,84,420,252,42,378,210,126,294,21,357,189,105,273,63,399,231,147,3
};
static int text_shift[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3 };
int tableh9[] = { /* 23 x 23 data */
2,102,470,286,56,424,240,148,516,332,33,401,217,125,493,309,79,447,263,171,355,10,1,
476,292,62,430,246,154,522,338,39,407,223,131,499,315,85,453,269,177,361,16,384,200,108,
50,418,234,142,510,326,27,395,211,119,487,303,73,441,257,165,349,4,372,188,96,464,280,
249,157,525,341,42,410,226,134,502,318,88,456,272,180,364,19,387,203,111,479,295,65,433,
513,329,30,398,214,122,490,306,76,444,260,168,352,7,375,191,99,467,283,53,421,237,145,
36,404,220,128,496,312,82,450,266,174,358,13,381,197,105,473,289,59,427,243,151,519,335,
208,116,484,300,70,438,254,162,346,378,369,185,93,461,277,47,415,231,139,507,323,24,392,
505,321,91,459,275,183,367,22,390,206,114,482,298,68,436,252,160,528,344,45,413,229,137,
80,448,264,172,356,11,379,195,103,471,287,57,425,241,149,517,333,34,402,218,126,494,310,
270,178,362,17,385,201,109,477,293,63,431,247,155,523,339,40,408,224,132,500,316,86,454,
350,5,373,189,97,465,281,51,419,235,143,511,327,28,396,212,120,488,304,74,442,258,166,
388,204,112,480,296,66,434,250,158,526,342,43,411,227,135,503,319,89,457,273,181,365,20,
100,468,284,54,422,238,146,514,330,31,399,215,123,491,307,77,445,261,169,353,8,376,192,
290,60,428,244,152,520,336,37,405,221,129,497,313,83,451,267,175,359,14,382,198,106,474,
416,232,140,508,324,25,393,209,117,485,301,71,439,255,163,347,194,370,186,94,462,278,48,
159,527,343,44,412,228,136,504,320,90,458,274,182,366,21,389,205,113,481,297,67,435,251,
331,32,400,216,124,492,308,78,446,262,170,354,9,377,193,101,469,285,55,423,239,147,515,
406,222,130,498,314,84,452,268,176,360,15,383,199,107,475,291,61,429,245,153,521,337,38,
118,486,302,72,440,256,164,348,345,371,187,95,463,279,49,417,233,141,509,325,26,394,210,
317,87,455,271,179,363,18,386,202,110,478,294,64,432,248,156,524,340,41,409,225,133,501,
443,259,167,351,6,374,190,98,466,282,52,420,236,144,512,328,29,397,213,121,489,305,75,
173,357,12,380,196,104,472,288,58,426,242,150,518,334,35,403,219,127,495,311,81,449,265,
0,368,184,92,460,276,46,414,230,138,506,322,23,391,207,115,483,299,69,437,253,161,3
};
static int text_value[] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,4,5,6,7,8,9,10,11,12,13,
15,16,17,18,19,20,21,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,
22,23,24,25,26,0,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,27,28,29,30,31 };
int tableh10[] = { /* 25 x 25 data */
2,603,103,503,303,53,453,253,153,553,353,28,428,228,128,528,328,78,478,278,178,578,378,375,1,
123,523,323,73,473,273,173,573,373,48,448,248,148,548,348,98,498,298,198,598,398,23,423,223,623,
311,61,461,261,161,561,361,36,436,236,136,536,336,86,486,286,186,586,386,11,411,211,611,111,511,
467,267,167,567,367,42,442,242,142,542,342,92,492,292,192,592,392,17,417,217,617,117,517,317,67,
155,555,355,30,430,230,130,530,330,80,480,280,180,580,380,5,405,205,605,105,505,305,55,455,255,
370,45,445,245,145,545,345,95,495,295,195,595,395,20,420,220,620,120,520,320,70,470,270,170,570,
433,233,133,533,333,83,483,283,183,583,383,8,408,208,608,108,508,308,58,458,258,158,558,358,33,
139,539,339,89,489,289,189,589,389,14,414,214,614,114,514,314,64,464,264,164,564,364,39,439,239,
326,76,476,276,176,576,376,403,401,201,601,101,501,301,51,451,251,151,551,351,26,426,226,126,526,
499,299,199,599,399,24,424,224,624,124,524,324,74,474,274,174,574,374,49,449,249,149,549,349,99,
187,587,387,12,412,212,612,112,512,312,62,462,262,162,562,362,37,437,237,137,537,337,87,487,287,
393,18,418,218,618,118,518,318,68,468,268,168,568,368,43,443,243,143,543,343,93,493,293,193,593,
406,206,606,106,506,306,56,456,256,156,556,356,31,431,231,131,531,331,81,481,281,181,581,381,6,
621,121,521,321,71,471,271,171,571,371,46,446,246,146,546,346,96,496,296,196,596,396,21,421,221,
509,309,59,459,259,159,559,359,34,434,234,134,534,334,84,484,284,184,584,384,9,409,209,609,109,
65,465,265,165,565,365,40,440,240,140,540,340,90,490,290,190,590,390,15,415,215,615,115,515,315,
252,152,552,352,27,427,227,127,527,327,77,477,277,177,577,377,203,402,202,602,102,502,302,52,452,
572,372,47,447,247,147,547,347,97,497,297,197,597,397,22,422,222,622,122,522,322,72,472,272,172,
35,435,235,135,535,335,85,485,285,185,585,385,10,410,210,610,110,510,310,60,460,260,160,560,360,
241,141,541,341,91,491,291,191,591,391,16,416,216,616,116,516,316,66,466,266,166,566,366,41,441,
529,329,79,479,279,179,579,379,4,404,204,604,104,504,304,54,454,254,154,554,354,29,429,229,129,
94,494,294,194,594,394,19,419,219,619,119,519,319,69,469,269,169,569,369,44,444,244,144,544,344,
282,182,582,382,7,407,207,607,107,507,307,57,457,257,157,557,357,32,432,232,132,532,332,82,482,
588,388,13,413,213,613,113,513,313,63,463,263,163,563,363,38,438,238,138,538,338,88,488,288,188,
0,400,200,600,100,500,300,50,450,250,150,550,350,25,425,225,125,525,325,75,475,275,175,575,3
};
static int intsymbol[] = {
0,1,3,5,7,8,10,12,13,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,2,4,6,9,11,14 };
int tableh11[] = { /* 27 x 27 data */
2,658,118,550,334,64,496,280,712,172,604,388,37,469,253,685,145,577,361,91,523,307,199,631,415,10,1,
125,557,341,71,503,287,719,179,611,395,44,476,260,692,152,584,368,98,530,314,206,638,422,17,449,233,665,
327,57,489,273,705,165,597,381,30,462,246,678,138,570,354,84,516,300,192,624,408,405,435,219,651,111,543,
511,295,727,187,619,403,52,484,268,700,160,592,376,106,538,322,214,646,430,25,457,241,673,133,565,349,79,
714,174,606,390,39,471,255,687,147,579,363,93,525,309,201,633,417,12,444,228,660,120,552,336,66,498,282,
613,397,46,478,262,694,154,586,370,100,532,316,208,640,424,19,451,235,667,127,559,343,73,505,289,721,181,
32,464,248,680,140,572,356,86,518,302,194,626,410,5,437,221,653,113,545,329,59,491,275,707,167,599,383,
265,697,157,589,373,103,535,319,211,643,427,22,454,238,670,130,562,346,76,508,292,724,184,616,400,49,481,
143,575,359,89,521,305,197,629,413,8,440,224,656,116,548,332,62,494,278,710,170,602,386,35,467,251,683,
366,96,528,312,204,636,420,15,447,231,663,123,555,339,69,501,285,717,177,609,393,42,474,258,690,150,582,
514,298,190,622,406,442,433,217,649,109,541,325,55,487,271,703,163,595,379,28,460,244,676,136,568,352,82,
215,647,431,26,458,242,674,134,566,350,80,512,296,728,188,620,404,53,485,269,701,161,593,377,107,539,323,
418,13,445,229,661,121,553,337,67,499,283,715,175,607,391,40,472,256,688,148,580,364,94,526,310,202,634,
452,236,668,128,560,344,74,506,290,722,182,614,398,47,479,263,695,155,587,371,101,533,317,209,641,425,20,
654,114,546,330,60,492,276,708,168,600,384,33,465,249,681,141,573,357,87,519,303,195,627,411,6,438,222,
563,347,77,509,293,725,185,617,401,50,482,266,698,158,590,374,104,536,320,212,644,428,23,455,239,671,131,
63,495,279,711,171,603,387,36,468,252,684,144,576,360,90,522,306,198,630,414,9,441,225,657,117,549,333,
286,718,178,610,394,43,475,259,691,151,583,367,97,529,313,205,637,421,16,448,232,664,124,556,340,70,502,
164,596,380,29,461,245,677,137,569,353,83,515,299,191,623,407,226,434,218,650,110,542,326,56,488,272,704,
402,51,483,267,699,159,591,375,105,537,321,213,645,429,24,456,240,672,132,564,348,78,510,294,726,186,618,
470,254,686,146,578,362,92,524,308,200,632,416,11,443,227,659,119,551,335,65,497,281,713,173,605,389,38,
693,153,585,369,99,531,315,207,639,423,18,450,234,666,126,558,342,72,504,288,720,180,612,396,45,477,261,
571,355,85,517,301,193,625,409,4,436,220,652,112,544,328,58,490,274,706,166,598,382,31,463,247,679,139,
102,534,318,210,642,426,21,453,237,669,129,561,345,75,507,291,723,183,615,399,48,480,264,696,156,588,372,
304,196,628,412,7,439,223,655,115,547,331,61,493,277,709,169,601,385,34,466,250,682,142,574,358,88,520,
635,419,14,446,230,662,122,554,338,68,500,284,716,176,608,392,41,473,257,689,149,581,365,95,527,311,203,
0,432,216,648,108,540,324,54,486,270,702,162,594,378,27,459,243,675,135,567,351,81,513,297,189,621,3
};
static int matrixH[] = {
10, 12, 8, 14, 8, 16, 12, 18, 20, 12, 22, 16, 24, 26, 16, 32, 36, 40, 44, 48,
52, 64, 72, 80, 88, 96, 104, 120, 132, 144 };
int tableh12[] = { /* 29 x 29 data */
2,703,123,587,355,819,65,529,297,761,181,645,413,36,500,268,732,152,616,384,94,558,326,790,210,674,442,7,1,
141,605,373,837,83,547,315,779,199,663,431,54,518,286,750,170,634,402,112,576,344,808,228,692,460,25,489,257,721,
359,823,69,533,301,765,185,649,417,40,504,272,736,156,620,388,98,562,330,794,214,678,446,11,475,243,707,127,591,
76,540,308,772,192,656,424,47,511,279,743,163,627,395,105,569,337,801,221,685,453,18,482,250,714,134,598,366,830,
293,757,177,641,409,32,496,264,728,148,612,380,90,554,322,786,206,670,438,435,467,235,699,119,583,351,815,61,525,
201,665,433,56,520,288,752,172,636,404,114,578,346,810,230,694,462,27,491,259,723,143,607,375,839,85,549,317,781,
419,42,506,274,738,158,622,390,100,564,332,796,216,680,448,13,477,245,709,129,593,361,825,71,535,303,767,187,651,
513,281,745,165,629,397,107,571,339,803,223,687,455,20,484,252,716,136,600,368,832,78,542,310,774,194,658,426,49,
730,150,614,382,92,556,324,788,208,672,440,5,469,237,701,121,585,353,817,63,527,295,759,179,643,411,34,498,266,
632,400,110,574,342,806,226,690,458,23,487,255,719,139,603,371,835,81,545,313,777,197,661,429,52,516,284,748,168,
96,560,328,792,212,676,444,9,473,241,705,125,589,357,821,67,531,299,763,183,647,415,38,502,270,734,154,618,386,
335,799,219,683,451,16,480,248,712,132,596,364,828,74,538,306,770,190,654,422,45,509,277,741,161,625,393,103,567,
204,668,436,471,465,233,697,117,581,349,813,59,523,291,755,175,639,407,30,494,262,726,146,610,378,88,552,320,784,
463,28,492,260,724,144,608,376,840,86,550,318,782,202,666,434,57,521,289,753,173,637,405,115,579,347,811,231,695,
478,246,710,130,594,362,826,72,536,304,768,188,652,420,43,507,275,739,159,623,391,101,565,333,797,217,681,449,14,
717,137,601,369,833,79,543,311,775,195,659,427,50,514,282,746,166,630,398,108,572,340,804,224,688,456,21,485,253,
586,354,818,64,528,296,760,180,644,412,35,499,267,731,151,615,383,93,557,325,789,209,673,441,6,470,238,702,122,
836,82,546,314,778,198,662,430,53,517,285,749,169,633,401,111,575,343,807,227,691,459,24,488,256,720,140,604,372,
532,300,764,184,648,416,39,503,271,735,155,619,387,97,561,329,793,213,677,445,10,474,242,706,126,590,358,822,68,
771,191,655,423,46,510,278,742,162,626,394,104,568,336,800,220,684,452,17,481,249,713,133,597,365,829,75,539,307,
640,408,31,495,263,727,147,611,379,89,553,321,785,205,669,437,239,466,234,698,118,582,350,814,60,524,292,756,176,
55,519,287,751,171,635,403,113,577,345,809,229,693,461,26,490,258,722,142,606,374,838,84,548,316,780,200,664,432,
273,737,157,621,389,99,563,331,795,215,679,447,12,476,244,708,128,592,360,824,70,534,302,766,186,650,418,41,505,
164,628,396,106,570,338,802,222,686,454,19,483,251,715,135,599,367,831,77,541,309,773,193,657,425,48,512,280,744,
381,91,555,323,787,207,671,439,4,468,236,700,120,584,352,816,62,526,294,758,178,642,410,33,497,265,729,149,613,
573,341,805,225,689,457,22,486,254,718,138,602,370,834,80,544,312,776,196,660,428,51,515,283,747,167,631,399,109,
791,211,675,443,8,472,240,704,124,588,356,820,66,530,298,762,182,646,414,37,501,269,733,153,617,385,95,559,327,
682,450,15,479,247,711,131,595,363,827,73,537,305,769,189,653,421,44,508,276,740,160,624,392,102,566,334,798,218,
0,464,232,696,116,580,348,812,58,522,290,754,174,638,406,29,493,261,725,145,609,377,87,551,319,783,203,667,3
};
static int matrixW[] = {
10, 12, 18, 14, 32, 16, 26, 18, 20, 36, 22, 36, 24, 26, 48, 32, 36, 40, 44,
48, 52, 64, 72, 80, 88, 96, 104, 120, 132, 144 };
int tableh13[] = { /* 31 x 31 data */
2,759,139,635,387,883,77,573,325,821,201,697,449,945,46,542,294,790,170,666,418,914,108,604,356,852,232,728,480,15,1,
147,643,395,891,85,581,333,829,209,705,457,953,54,550,302,798,178,674,426,922,116,612,364,860,240,736,488,23,519,271,767,
379,875,69,565,317,813,193,689,441,937,38,534,286,782,162,658,410,906,100,596,348,844,224,720,472,7,503,255,751,131,627,
89,585,337,833,213,709,461,957,58,554,306,802,182,678,430,926,120,616,368,864,244,740,492,27,523,275,771,151,647,399,895,
321,817,197,693,445,941,42,538,290,786,166,662,414,910,104,600,352,848,228,724,476,11,507,259,755,135,631,383,879,73,569,
205,701,453,949,50,546,298,794,174,670,422,918,112,608,360,856,236,732,484,19,515,267,763,143,639,391,887,81,577,329,825,
437,933,34,530,282,778,158,654,406,902,96,592,344,840,220,716,468,465,499,251,747,127,623,375,871,65,561,313,809,189,685,
60,556,308,804,184,680,432,928,122,618,370,866,246,742,494,29,525,277,773,153,649,401,897,91,587,339,835,215,711,463,959,
292,788,168,664,416,912,106,602,354,850,230,726,478,13,509,261,757,137,633,385,881,75,571,323,819,199,695,447,943,44,540,
176,672,424,920,114,610,362,858,238,734,486,21,517,269,765,145,641,393,889,83,579,331,827,207,703,455,951,52,548,300,796,
408,904,98,594,346,842,222,718,470,5,501,253,749,129,625,377,873,67,563,315,811,191,687,439,935,36,532,284,780,160,656,
118,614,366,862,242,738,490,25,521,273,769,149,645,397,893,87,583,335,831,211,707,459,955,56,552,304,800,180,676,428,924,
350,846,226,722,474,9,505,257,753,133,629,381,877,71,567,319,815,195,691,443,939,40,536,288,784,164,660,412,908,102,598,
234,730,482,17,513,265,761,141,637,389,885,79,575,327,823,203,699,451,947,48,544,296,792,172,668,420,916,110,606,358,854,
466,511,497,249,745,125,621,373,869,63,559,311,807,187,683,435,931,32,528,280,776,156,652,404,900,94,590,342,838,218,714,
526,278,774,154,650,402,898,92,588,340,836,216,712,464,960,61,557,309,805,185,681,433,929,123,619,371,867,247,743,495,30,
758,138,634,386,882,76,572,324,820,200,696,448,944,45,541,293,789,169,665,417,913,107,603,355,851,231,727,479,14,510,262,
642,394,890,84,580,332,828,208,704,456,952,53,549,301,797,177,673,425,921,115,611,363,859,239,735,487,22,518,270,766,146,
874,68,564,316,812,192,688,440,936,37,533,285,781,161,657,409,905,99,595,347,843,223,719,471,6,502,254,750,130,626,378,
584,336,832,212,708,460,956,57,553,305,801,181,677,429,925,119,615,367,863,243,739,491,26,522,274,770,150,646,398,894,88,
816,196,692,444,940,41,537,289,785,165,661,413,909,103,599,351,847,227,723,475,10,506,258,754,134,630,382,878,72,568,320,
700,452,948,49,545,297,793,173,669,421,917,111,607,359,855,235,731,483,18,514,266,762,142,638,390,886,80,576,328,824,204,
932,33,529,281,777,157,653,405,901,95,591,343,839,219,715,467,263,498,250,746,126,622,374,870,64,560,312,808,188,684,436,
555,307,803,183,679,431,927,121,617,369,865,245,741,493,28,524,276,772,152,648,400,896,90,586,338,834,214,710,462,958,59,
787,167,663,415,911,105,601,353,849,229,725,477,12,508,260,756,136,632,384,880,74,570,322,818,198,694,446,942,43,539,291,
671,423,919,113,609,361,857,237,733,485,20,516,268,764,144,640,392,888,82,578,330,826,206,702,454,950,51,547,299,795,175,
903,97,593,345,841,221,717,469,4,500,252,748,128,624,376,872,66,562,314,810,190,686,438,934,35,531,283,779,159,655,407,
613,365,861,241,737,489,24,520,272,768,148,644,396,892,86,582,334,830,210,706,458,954,55,551,303,799,179,675,427,923,117,
845,225,721,473,8,504,256,752,132,628,380,876,70,566,318,814,194,690,442,938,39,535,287,783,163,659,411,907,101,597,349,
729,481,16,512,264,760,140,636,388,884,78,574,326,822,202,698,450,946,47,543,295,791,171,667,419,915,109,605,357,853,233,
0,496,248,744,124,620,372,868,62,558,310,806,186,682,434,930,31,527,279,775,155,651,403,899,93,589,341,837,217,713,3
};
static int matrixFH[] = {
10, 12, 8, 14, 8, 16, 12, 18, 20, 12, 22, 16, 24, 26, 16, 16, 18, 20, 22, 24,
26, 16, 18, 20, 22, 24, 26, 20, 22, 24 };
int tableh14[] = { /* 33 x 33 data */
2,265,793,133,661,397,925,67,595,331,859,199,727,463,991,34,562,298,826,166,694,430,958,100,628,364,892,232,760,496,1024,1057,1,
824,164,692,428,956,98,626,362,890,230,758,494,1022,65,593,329,857,197,725,461,989,131,659,395,923,263,791,527,1055,32,1088,560,296,
676,412,940,82,610,346,874,214,742,478,1006,49,577,313,841,181,709,445,973,115,643,379,907,247,775,511,1039,16,1072,544,280,808,148,
948,90,618,354,882,222,750,486,1014,57,585,321,849,189,717,453,981,123,651,387,915,255,783,519,1047,24,1080,552,288,816,156,684,420,
602,338,866,206,734,470,998,41,569,305,833,173,701,437,965,107,635,371,899,239,767,503,1031,8,1064,536,272,800,140,668,404,932,74,
886,226,754,490,1018,61,589,325,853,193,721,457,985,127,655,391,919,259,787,523,1051,28,1084,556,292,820,160,688,424,952,94,622,358,
738,474,1002,45,573,309,837,177,705,441,969,111,639,375,903,243,771,507,1035,12,1068,540,276,804,144,672,408,936,78,606,342,870,210,
1010,53,581,317,845,185,713,449,977,119,647,383,911,251,779,515,1043,20,1076,548,284,812,152,680,416,944,86,614,350,878,218,746,482,
565,301,829,169,697,433,961,103,631,367,895,235,763,499,1027,4,1060,532,268,796,136,664,400,928,70,598,334,862,202,730,466,994,37,
855,195,723,459,987,129,657,393,921,261,789,525,1053,30,1086,558,294,822,162,690,426,954,96,624,360,888,228,756,492,1020,63,591,327,
707,443,971,113,641,377,905,245,773,509,1037,14,1070,542,278,806,146,674,410,938,80,608,344,872,212,740,476,1004,47,575,311,839,179,
979,121,649,385,913,253,781,517,1045,22,1078,550,286,814,154,682,418,946,88,616,352,880,220,748,484,1012,55,583,319,847,187,715,451,
633,369,897,237,765,501,1029,6,1062,534,270,798,138,666,402,930,72,600,336,864,204,732,468,996,39,567,303,831,171,699,435,963,105,
917,257,785,521,1049,26,1082,554,290,818,158,686,422,950,92,620,356,884,224,752,488,1016,59,587,323,851,191,719,455,983,125,653,389,
769,505,1033,10,1066,538,274,802,142,670,406,934,76,604,340,868,208,736,472,1000,43,571,307,835,175,703,439,967,109,637,373,901,241,
1041,18,1074,546,282,810,150,678,414,942,84,612,348,876,216,744,480,1008,51,579,315,843,183,711,447,975,117,645,381,909,249,777,513,
1058,530,266,794,134,662,398,926,68,596,332,860,200,728,464,992,35,563,299,827,167,695,431,959,101,629,365,893,233,761,497,1025,529,
295,823,163,691,427,955,97,625,361,889,229,757,493,1021,64,592,328,856,196,724,460,988,130,658,394,922,262,790,526,1054,31,1087,559,
147,675,411,939,81,609,345,873,213,741,477,1005,48,576,312,840,180,708,444,972,114,642,378,906,246,774,510,1038,15,1071,543,279,807,
419,947,89,617,353,881,221,749,485,1013,56,584,320,848,188,716,452,980,122,650,386,914,254,782,518,1046,23,1079,551,287,815,155,683,
73,601,337,865,205,733,469,997,40,568,304,832,172,700,436,964,106,634,370,898,238,766,502,1030,7,1063,535,271,799,139,667,403,931,
357,885,225,753,489,1017,60,588,324,852,192,720,456,984,126,654,390,918,258,786,522,1050,27,1083,555,291,819,159,687,423,951,93,621,
209,737,473,1001,44,572,308,836,176,704,440,968,110,638,374,902,242,770,506,1034,11,1067,539,275,803,143,671,407,935,77,605,341,869,
481,1009,52,580,316,844,184,712,448,976,118,646,382,910,250,778,514,1042,19,1075,547,283,811,151,679,415,943,85,613,349,877,217,745,
36,564,300,828,168,696,432,960,102,630,366,894,234,762,498,1026,1023,1059,531,267,795,135,663,399,927,69,597,333,861,201,729,465,993,
326,854,194,722,458,986,128,656,392,920,260,788,524,1052,29,1085,557,293,821,161,689,425,953,95,623,359,887,227,755,491,1019,62,590,
178,706,442,970,112,640,376,904,244,772,508,1036,13,1069,541,277,805,145,673,409,937,79,607,343,871,211,739,475,1003,46,574,310,838,
450,978,120,648,384,912,252,780,516,1044,21,1077,549,285,813,153,681,417,945,87,615,351,879,219,747,483,1011,54,582,318,846,186,714,
104,632,368,896,236,764,500,1028,5,1061,533,269,797,137,665,401,929,71,599,335,863,203,731,467,995,38,566,302,830,170,698,434,962,
388,916,256,784,520,1048,25,1081,553,289,817,157,685,421,949,91,619,355,883,223,751,487,1015,58,586,322,850,190,718,454,982,124,652,
240,768,504,1032,9,1065,537,273,801,141,669,405,933,75,603,339,867,207,735,471,999,42,570,306,834,174,702,438,966,108,636,372,900,
512,1040,17,1073,545,281,809,149,677,413,941,83,611,347,875,215,743,479,1007,50,578,314,842,182,710,446,974,116,644,380,908,248,776,
0,1056,528,264,792,132,660,396,924,66,594,330,858,198,726,462,990,33,561,297,825,165,693,429,957,99,627,363,891,231,759,495,3
};
static int matrixFW[] = {
10, 12, 18, 14, 16, 16, 26, 18, 20, 18, 22, 18, 24, 26, 24, 16, 18, 20, 22,
24, 26, 16, 18, 20, 22, 24, 26, 20, 22, 24 };
int tableh15[] = { /* 35 x 35 data */
2,290,850,150,710,430,990,80,1200,640,360,920,220,780,500,1060,45,1165,605,325,885,185,745,465,1025,115,675,395,955,255,815,535,1095,10,1,
859,159,719,439,999,89,1209,649,369,929,229,789,509,1069,54,1174,614,334,894,194,754,474,1034,124,684,404,964,264,824,544,1104,19,1139,579,299,
701,421,981,71,1191,631,351,911,211,771,491,1051,36,1156,596,316,876,176,736,456,1016,106,666,386,946,246,806,526,1086,1130,1121,561,281,841,141,
1014,104,1224,664,384,944,244,804,524,1084,69,1189,629,349,909,209,769,489,1049,139,699,419,979,279,839,559,1119,34,1154,594,314,874,174,734,454,
1207,647,367,927,227,787,507,1067,52,1172,612,332,892,192,752,472,1032,122,682,402,962,262,822,542,1102,17,1137,577,297,857,157,717,437,997,87,
376,936,236,796,516,1076,61,1181,621,341,901,201,761,481,1041,131,691,411,971,271,831,551,1111,26,1146,586,306,866,166,726,446,1006,96,1216,656,
218,778,498,1058,43,1163,603,323,883,183,743,463,1023,113,673,393,953,253,813,533,1093,8,1128,568,288,848,148,708,428,988,78,1198,638,358,918,
520,1080,65,1185,625,345,905,205,765,485,1045,135,695,415,975,275,835,555,1115,30,1150,590,310,870,170,730,450,1010,100,1220,660,380,940,240,800,
48,1168,608,328,888,188,748,468,1028,118,678,398,958,258,818,538,1098,13,1133,573,293,853,153,713,433,993,83,1203,643,363,923,223,783,503,1063,
617,337,897,197,757,477,1037,127,687,407,967,267,827,547,1107,22,1142,582,302,862,162,722,442,1002,92,1212,652,372,932,232,792,512,1072,57,1177,
879,179,739,459,1019,109,669,389,949,249,809,529,1089,4,1124,564,284,844,144,704,424,984,74,1194,634,354,914,214,774,494,1054,39,1159,599,319,
767,487,1047,137,697,417,977,277,837,557,1117,32,1152,592,312,872,172,732,452,1012,102,1222,662,382,942,242,802,522,1082,67,1187,627,347,907,207,
1030,120,680,400,960,260,820,540,1100,15,1135,575,295,855,155,715,435,995,85,1205,645,365,925,225,785,505,1065,50,1170,610,330,890,190,750,470,
689,409,969,269,829,549,1109,24,1144,584,304,864,164,724,444,1004,94,1214,654,374,934,234,794,514,1074,59,1179,619,339,899,199,759,479,1039,129,
951,251,811,531,1091,6,1126,566,286,846,146,706,426,986,76,1196,636,356,916,216,776,496,1056,41,1161,601,321,881,181,741,461,1021,111,671,391,
833,553,1113,28,1148,588,308,868,168,728,448,1008,98,1218,658,378,938,238,798,518,1078,63,1183,623,343,903,203,763,483,1043,133,693,413,973,273,
1096,11,1131,571,291,851,151,711,431,991,81,1201,641,361,921,221,781,501,1061,46,1166,606,326,886,186,746,466,1026,116,676,396,956,256,816,536,
1140,580,300,860,160,720,440,1000,90,1210,650,370,930,230,790,510,1070,55,1175,615,335,895,195,755,475,1035,125,685,405,965,265,825,545,1105,20,
282,842,142,702,422,982,72,1192,632,352,912,212,772,492,1052,37,1157,597,317,877,177,737,457,1017,107,667,387,947,247,807,527,1087,570,1122,562,
173,733,453,1013,103,1223,663,383,943,243,803,523,1083,68,1188,628,348,908,208,768,488,1048,138,698,418,978,278,838,558,1118,33,1153,593,313,873,
436,996,86,1206,646,366,926,226,786,506,1066,51,1171,611,331,891,191,751,471,1031,121,681,401,961,261,821,541,1101,16,1136,576,296,856,156,716,
95,1215,655,375,935,235,795,515,1075,60,1180,620,340,900,200,760,480,1040,130,690,410,970,270,830,550,1110,25,1145,585,305,865,165,725,445,1005,
637,357,917,217,777,497,1057,42,1162,602,322,882,182,742,462,1022,112,672,392,952,252,812,532,1092,7,1127,567,287,847,147,707,427,987,77,1197,
939,239,799,519,1079,64,1184,624,344,904,204,764,484,1044,134,694,414,974,274,834,554,1114,29,1149,589,309,869,169,729,449,1009,99,1219,659,379,
782,502,1062,47,1167,607,327,887,187,747,467,1027,117,677,397,957,257,817,537,1097,12,1132,572,292,852,152,712,432,992,82,1202,642,362,922,222,
1071,56,1176,616,336,896,196,756,476,1036,126,686,406,966,266,826,546,1106,21,1141,581,301,861,161,721,441,1001,91,1211,651,371,931,231,791,511,
1158,598,318,878,178,738,458,1018,108,668,388,948,248,808,528,1088,1085,1123,563,283,843,143,703,423,983,73,1193,633,353,913,213,773,493,1053,38,
346,906,206,766,486,1046,136,696,416,976,276,836,556,1116,31,1151,591,311,871,171,731,451,1011,101,1221,661,381,941,241,801,521,1081,66,1186,626,
189,749,469,1029,119,679,399,959,259,819,539,1099,14,1134,574,294,854,154,714,434,994,84,1204,644,364,924,224,784,504,1064,49,1169,609,329,889,
478,1038,128,688,408,968,268,828,548,1108,23,1143,583,303,863,163,723,443,1003,93,1213,653,373,933,233,793,513,1073,58,1178,618,338,898,198,758,
110,670,390,950,250,810,530,1090,5,1125,565,285,845,145,705,425,985,75,1195,635,355,915,215,775,495,1055,40,1160,600,320,880,180,740,460,1020,
412,972,272,832,552,1112,27,1147,587,307,867,167,727,447,1007,97,1217,657,377,937,237,797,517,1077,62,1182,622,342,902,202,762,482,1042,132,692,
254,814,534,1094,9,1129,569,289,849,149,709,429,989,79,1199,639,359,919,219,779,499,1059,44,1164,604,324,884,184,744,464,1024,114,674,394,954,
543,1103,18,1138,578,298,858,158,718,438,998,88,1208,648,368,928,228,788,508,1068,53,1173,613,333,893,193,753,473,1033,123,683,403,963,263,823,
0,1120,560,280,840,140,700,420,980,70,1190,630,350,910,210,770,490,1050,35,1155,595,315,875,175,735,455,1015,105,665,385,945,245,805,525,3
};
static int matrixbytes[] = {
3, 5, 5, 8, 10, 12, 16, 18, 22, 22, 30, 32, 36, 44, 49, 62, 86, 114, 144,
174, 204, 280, 368, 456, 576, 696, 816, 1050, 1304, 1558 };
int tableh16[] = { /* 37 x 37 data */
2,302,894,154,1338,746,450,1042,80,1264,672,376,968,228,820,524,1116,43,1227,635,339,931,191,783,487,1079,117,1301,709,413,1005,265,857,561,1153,6,1,
917,177,1361,769,473,1065,103,1287,695,399,991,251,843,547,1139,66,1250,658,362,954,214,806,510,1102,140,1324,732,436,1028,288,880,584,1176,29,1213,621,325,
1343,751,455,1047,85,1269,677,381,973,233,825,529,1121,48,1232,640,344,936,196,788,492,1084,122,1306,714,418,1010,270,862,566,1158,11,1195,603,307,899,159,
464,1056,94,1278,686,390,982,242,834,538,1130,57,1241,649,353,945,205,797,501,1093,131,1315,723,427,1019,279,871,575,1167,20,1204,612,316,908,168,1352,760,
75,1259,667,371,963,223,815,519,1111,38,1222,630,334,926,186,778,482,1074,112,1296,704,408,1000,260,852,556,1148,1190,1185,593,297,889,149,1333,741,445,1037,
702,406,998,258,850,554,1146,73,1257,665,369,961,221,813,517,1109,147,1331,739,443,1035,295,887,591,1183,36,1220,628,332,924,184,1368,776,480,1072,110,1294,
980,240,832,536,1128,55,1239,647,351,943,203,795,499,1091,129,1313,721,425,1017,277,869,573,1165,18,1202,610,314,906,166,1350,758,462,1054,92,1276,684,388,
841,545,1137,64,1248,656,360,952,212,804,508,1100,138,1322,730,434,1026,286,878,582,1174,27,1211,619,323,915,175,1359,767,471,1063,101,1285,693,397,989,249,
1119,46,1230,638,342,934,194,786,490,1082,120,1304,712,416,1008,268,860,564,1156,9,1193,601,305,897,157,1341,749,453,1045,83,1267,675,379,971,231,823,527,
1253,661,365,957,217,809,513,1105,143,1327,735,439,1031,291,883,587,1179,32,1216,624,328,920,180,1364,772,476,1068,106,1290,698,402,994,254,846,550,1142,69,
347,939,199,791,495,1087,125,1309,717,421,1013,273,865,569,1161,14,1198,606,310,902,162,1346,754,458,1050,88,1272,680,384,976,236,828,532,1124,51,1235,643,
208,800,504,1096,134,1318,726,430,1022,282,874,578,1170,23,1207,615,319,911,171,1355,763,467,1059,97,1281,689,393,985,245,837,541,1133,60,1244,652,356,948,
485,1077,115,1299,707,411,1003,263,855,559,1151,4,1188,596,300,892,152,1336,744,448,1040,78,1262,670,374,966,226,818,522,1114,41,1225,633,337,929,189,781,
145,1329,737,441,1033,293,885,589,1181,34,1218,626,330,922,182,1366,774,478,1070,108,1292,700,404,996,256,848,552,1144,71,1255,663,367,959,219,811,515,1107,
719,423,1015,275,867,571,1163,16,1200,608,312,904,164,1348,756,460,1052,90,1274,682,386,978,238,830,534,1126,53,1237,645,349,941,201,793,497,1089,127,1311,
1024,284,876,580,1172,25,1209,617,321,913,173,1357,765,469,1061,99,1283,691,395,987,247,839,543,1135,62,1246,654,358,950,210,802,506,1098,136,1320,728,432,
858,562,1154,7,1191,599,303,895,155,1339,747,451,1043,81,1265,673,377,969,229,821,525,1117,44,1228,636,340,932,192,784,488,1080,118,1302,710,414,1006,266,
1177,30,1214,622,326,918,178,1362,770,474,1066,104,1288,696,400,992,252,844,548,1140,67,1251,659,363,955,215,807,511,1103,141,1325,733,437,1029,289,881,585,
1196,604,308,900,160,1344,752,456,1048,86,1270,678,382,974,234,826,530,1122,49,1233,641,345,937,197,789,493,1085,123,1307,715,419,1011,271,863,567,1159,12,
317,909,169,1353,761,465,1057,95,1279,687,391,983,243,835,539,1131,58,1242,650,354,946,206,798,502,1094,132,1316,724,428,1020,280,872,576,1168,21,1205,613,
150,1334,742,446,1038,76,1260,668,372,964,224,816,520,1112,39,1223,631,335,927,187,779,483,1075,113,1297,705,409,1001,261,853,557,1149,598,1186,594,298,890,
775,479,1071,109,1293,701,405,997,257,849,553,1145,72,1256,664,368,960,220,812,516,1108,146,1330,738,442,1034,294,886,590,1182,35,1219,627,331,923,183,1367,
1053,91,1275,683,387,979,239,831,535,1127,54,1238,646,350,942,202,794,498,1090,128,1312,720,424,1016,276,868,572,1164,17,1201,609,313,905,165,1349,757,461,
1284,692,396,988,248,840,544,1136,63,1247,655,359,951,211,803,507,1099,137,1321,729,433,1025,285,877,581,1173,26,1210,618,322,914,174,1358,766,470,1062,100,
378,970,230,822,526,1118,45,1229,637,341,933,193,785,489,1081,119,1303,711,415,1007,267,859,563,1155,8,1192,600,304,896,156,1340,748,452,1044,82,1266,674,
253,845,549,1141,68,1252,660,364,956,216,808,512,1104,142,1326,734,438,1030,290,882,586,1178,31,1215,623,327,919,179,1363,771,475,1067,105,1289,697,401,993,
531,1123,50,1234,642,346,938,198,790,494,1086,124,1308,716,420,1012,272,864,568,1160,13,1197,605,309,901,161,1345,753,457,1049,87,1271,679,383,975,235,827,
59,1243,651,355,947,207,799,503,1095,133,1317,725,429,1021,281,873,577,1169,22,1206,614,318,910,170,1354,762,466,1058,96,1280,688,392,984,244,836,540,1132,
632,336,928,188,780,484,1076,114,1298,706,410,1002,262,854,558,1150,1147,1187,595,299,891,151,1335,743,447,1039,77,1261,669,373,965,225,817,521,1113,40,1224,
958,218,810,514,1106,144,1328,736,440,1032,292,884,588,1180,33,1217,625,329,921,181,1365,773,477,1069,107,1291,699,403,995,255,847,551,1143,70,1254,662,366,
792,496,1088,126,1310,718,422,1014,274,866,570,1162,15,1199,607,311,903,163,1347,755,459,1051,89,1273,681,385,977,237,829,533,1125,52,1236,644,348,940,200,
1097,135,1319,727,431,1023,283,875,579,1171,24,1208,616,320,912,172,1356,764,468,1060,98,1282,690,394,986,246,838,542,1134,61,1245,653,357,949,209,801,505,
1300,708,412,1004,264,856,560,1152,5,1189,597,301,893,153,1337,745,449,1041,79,1263,671,375,967,227,819,523,1115,42,1226,634,338,930,190,782,486,1078,116,
435,1027,287,879,583,1175,28,1212,620,324,916,176,1360,768,472,1064,102,1286,694,398,990,250,842,546,1138,65,1249,657,361,953,213,805,509,1101,139,1323,731,
269,861,565,1157,10,1194,602,306,898,158,1342,750,454,1046,84,1268,676,380,972,232,824,528,1120,47,1231,639,343,935,195,787,491,1083,121,1305,713,417,1009,
574,1166,19,1203,611,315,907,167,1351,759,463,1055,93,1277,685,389,981,241,833,537,1129,56,1240,648,352,944,204,796,500,1092,130,1314,722,426,1018,278,870,
0,1184,592,296,888,148,1332,740,444,1036,74,1258,666,370,962,222,814,518,1110,37,1221,629,333,925,185,777,481,1073,111,1295,703,407,999,259,851,555,3
};
static int matrixdatablock[] = {
3, 5, 5, 8, 10, 12, 16, 18, 22, 22, 30, 32, 36, 44, 49, 62, 86, 114, 144,
174, 102, 140, 92, 114, 144, 174, 136, 175, 163, 156 };
int tableh17[] = { /* 39 x 39 data */
2,328,952,172,1420,796,484,1108,94,1342,718,406,1030,250,1498,874,562,1186,55,1303,679,367,991,211,1459,835,523,1147,133,1381,757,445,1069,289,913,601,1225,16,1,
962,182,1430,806,494,1118,104,1352,728,416,1040,260,1508,884,572,1196,65,1313,689,377,1001,221,1469,845,533,1157,143,1391,767,455,1079,299,923,611,1235,26,1274,650,338,
1410,786,474,1098,84,1332,708,396,1020,240,1488,864,552,1176,45,1293,669,357,981,201,1449,825,513,1137,123,1371,747,435,1059,279,903,591,1215,6,1254,630,318,942,162,
499,1123,109,1357,733,421,1045,265,1513,889,577,1201,70,1318,694,382,1006,226,1474,850,538,1162,148,1396,772,460,1084,304,928,616,1240,31,1279,655,343,967,187,1435,811,
89,1337,713,401,1025,245,1493,869,557,1181,50,1298,674,362,986,206,1454,830,518,1142,128,1376,752,440,1064,284,908,596,1220,11,1259,635,323,947,167,1415,791,479,1103,
723,411,1035,255,1503,879,567,1191,60,1308,684,372,996,216,1464,840,528,1152,138,1386,762,450,1074,294,918,606,1230,21,1269,645,333,957,177,1425,801,489,1113,99,1347,
1015,235,1483,859,547,1171,40,1288,664,352,976,196,1444,820,508,1132,118,1366,742,430,1054,274,898,586,1210,1264,1249,625,313,937,157,1405,781,469,1093,79,1327,703,391,
1520,896,584,1208,77,1325,701,389,1013,233,1481,857,545,1169,155,1403,779,467,1091,311,935,623,1247,38,1286,662,350,974,194,1442,818,506,1130,116,1364,740,428,1052,272,
565,1189,58,1306,682,370,994,214,1462,838,526,1150,136,1384,760,448,1072,292,916,604,1228,19,1267,643,331,955,175,1423,799,487,1111,97,1345,721,409,1033,253,1501,877,
68,1316,692,380,1004,224,1472,848,536,1160,146,1394,770,458,1082,302,926,614,1238,29,1277,653,341,965,185,1433,809,497,1121,107,1355,731,419,1043,263,1511,887,575,1199,
672,360,984,204,1452,828,516,1140,126,1374,750,438,1062,282,906,594,1218,9,1257,633,321,945,165,1413,789,477,1101,87,1335,711,399,1023,243,1491,867,555,1179,48,1296,
1009,229,1477,853,541,1165,151,1399,775,463,1087,307,931,619,1243,34,1282,658,346,970,190,1438,814,502,1126,112,1360,736,424,1048,268,1516,892,580,1204,73,1321,697,385,
1457,833,521,1145,131,1379,755,443,1067,287,911,599,1223,14,1262,638,326,950,170,1418,794,482,1106,92,1340,716,404,1028,248,1496,872,560,1184,53,1301,677,365,989,209,
531,1155,141,1389,765,453,1077,297,921,609,1233,24,1272,648,336,960,180,1428,804,492,1116,102,1350,726,414,1038,258,1506,882,570,1194,63,1311,687,375,999,219,1467,843,
121,1369,745,433,1057,277,901,589,1213,4,1252,628,316,940,160,1408,784,472,1096,82,1330,706,394,1018,238,1486,862,550,1174,43,1291,667,355,979,199,1447,823,511,1135,
777,465,1089,309,933,621,1245,36,1284,660,348,972,192,1440,816,504,1128,114,1362,738,426,1050,270,1518,894,582,1206,75,1323,699,387,1011,231,1479,855,543,1167,153,1401,
1070,290,914,602,1226,17,1265,641,329,953,173,1421,797,485,1109,95,1343,719,407,1031,251,1499,875,563,1187,56,1304,680,368,992,212,1460,836,524,1148,134,1382,758,446,
924,612,1236,27,1275,651,339,963,183,1431,807,495,1119,105,1353,729,417,1041,261,1509,885,573,1197,66,1314,690,378,1002,222,1470,846,534,1158,144,1392,768,456,1080,300,
1216,7,1255,631,319,943,163,1411,787,475,1099,85,1333,709,397,1021,241,1489,865,553,1177,46,1294,670,358,982,202,1450,826,514,1138,124,1372,748,436,1060,280,904,592,
1280,656,344,968,188,1436,812,500,1124,110,1358,734,422,1046,266,1514,890,578,1202,71,1319,695,383,1007,227,1475,851,539,1163,149,1397,773,461,1085,305,929,617,1241,32,
324,948,168,1416,792,480,1104,90,1338,714,402,1026,246,1494,870,558,1182,51,1299,675,363,987,207,1455,831,519,1143,129,1377,753,441,1065,285,909,597,1221,12,1260,636,
178,1426,802,490,1114,100,1348,724,412,1036,256,1504,880,568,1192,61,1309,685,373,997,217,1465,841,529,1153,139,1387,763,451,1075,295,919,607,1231,22,1270,646,334,958,
782,470,1094,80,1328,704,392,1016,236,1484,860,548,1172,41,1289,665,353,977,197,1445,821,509,1133,119,1367,743,431,1055,275,899,587,1211,640,1250,626,314,938,158,1406,
1129,115,1363,739,427,1051,271,1519,895,583,1207,76,1324,700,388,1012,232,1480,856,544,1168,154,1402,778,466,1090,310,934,622,1246,37,1285,661,349,973,193,1441,817,505,
1344,720,408,1032,252,1500,876,564,1188,57,1305,681,369,993,213,1461,837,525,1149,135,1383,759,447,1071,291,915,603,1227,18,1266,642,330,954,174,1422,798,486,1110,96,
418,1042,262,1510,886,574,1198,67,1315,691,379,1003,223,1471,847,535,1159,145,1393,769,457,1081,301,925,613,1237,28,1276,652,340,964,184,1432,808,496,1120,106,1354,730,
242,1490,866,554,1178,47,1295,671,359,983,203,1451,827,515,1139,125,1373,749,437,1061,281,905,593,1217,8,1256,632,320,944,164,1412,788,476,1100,86,1334,710,398,1022,
891,579,1203,72,1320,696,384,1008,228,1476,852,540,1164,150,1398,774,462,1086,306,930,618,1242,33,1281,657,345,969,189,1437,813,501,1125,111,1359,735,423,1047,267,1515,
1183,52,1300,676,364,988,208,1456,832,520,1144,130,1378,754,442,1066,286,910,598,1222,13,1261,637,325,949,169,1417,793,481,1105,91,1339,715,403,1027,247,1495,871,559,
1310,686,374,998,218,1466,842,530,1154,140,1388,764,452,1076,296,920,608,1232,23,1271,647,335,959,179,1427,803,491,1115,101,1349,725,413,1037,257,1505,881,569,1193,62,
354,978,198,1446,822,510,1134,120,1368,744,432,1056,276,900,588,1212,1209,1251,627,315,939,159,1407,783,471,1095,81,1329,705,393,1017,237,1485,861,549,1173,42,1290,666,
230,1478,854,542,1166,152,1400,776,464,1088,308,932,620,1244,35,1283,659,347,971,191,1439,815,503,1127,113,1361,737,425,1049,269,1517,893,581,1205,74,1322,698,386,1010,
834,522,1146,132,1380,756,444,1068,288,912,600,1224,15,1263,639,327,951,171,1419,795,483,1107,93,1341,717,405,1029,249,1497,873,561,1185,54,1302,678,366,990,210,1458,
1156,142,1390,766,454,1078,298,922,610,1234,25,1273,649,337,961,181,1429,805,493,1117,103,1351,727,415,1039,259,1507,883,571,1195,64,1312,688,376,1000,220,1468,844,532,
1370,746,434,1058,278,902,590,1214,5,1253,629,317,941,161,1409,785,473,1097,83,1331,707,395,1019,239,1487,863,551,1175,44,1292,668,356,980,200,1448,824,512,1136,122,
459,1083,303,927,615,1239,30,1278,654,342,966,186,1434,810,498,1122,108,1356,732,420,1044,264,1512,888,576,1200,69,1317,693,381,1005,225,1473,849,537,1161,147,1395,771,
283,907,595,1219,10,1258,634,322,946,166,1414,790,478,1102,88,1336,712,400,1024,244,1492,868,556,1180,49,1297,673,361,985,205,1453,829,517,1141,127,1375,751,439,1063,
605,1229,20,1268,644,332,956,176,1424,800,488,1112,98,1346,722,410,1034,254,1502,878,566,1190,59,1307,683,371,995,215,1463,839,527,1151,137,1385,761,449,1073,293,917,
0,1248,624,312,936,156,1404,780,468,1092,78,1326,702,390,1014,234,1482,858,546,1170,39,1287,663,351,975,195,1443,819,507,1131,117,1365,741,429,1053,273,897,585,3
};
static int matrixrsblock[] = {
5, 7, 7, 10, 11, 12, 14, 14, 18, 18, 20, 24, 24, 28, 28, 36, 42, 48, 56, 68,
42, 56, 36, 48, 56, 68, 56, 68, 62, 62 };
int tableh18[] = { /* 41 x 41 data */
2,332,1644,988,168,1480,824,496,1152,86,1398,742,414,1070,250,1562,906,578,1234,45,1357,701,373,1029,209,1521,865,537,1193,127,1439,783,455,1111,291,1603,947,619,1275,4,1,
1677,1021,201,1513,857,529,1185,119,1431,775,447,1103,283,1595,939,611,1267,78,1390,734,406,1062,242,1554,898,570,1226,160,1472,816,488,1144,324,1636,980,652,1308,37,1349,693,365,
181,1493,837,509,1165,99,1411,755,427,1083,263,1575,919,591,1247,58,1370,714,386,1042,222,1534,878,550,1206,140,1452,796,468,1124,304,1616,960,632,1288,17,1329,673,345,1657,1001,
847,519,1175,109,1421,765,437,1093,273,1585,929,601,1257,68,1380,724,396,1052,232,1544,888,560,1216,150,1462,806,478,1134,314,1626,970,642,1298,27,1339,683,355,1667,1011,191,1503,
1155,89,1401,745,417,1073,253,1565,909,581,1237,48,1360,704,376,1032,212,1524,868,540,1196,130,1442,786,458,1114,294,1606,950,622,1278,7,1319,663,335,1647,991,171,1483,827,499,
1426,770,442,1098,278,1590,934,606,1262,73,1385,729,401,1057,237,1549,893,565,1221,155,1467,811,483,1139,319,1631,975,647,1303,32,1344,688,360,1672,1016,196,1508,852,524,1180,114,
422,1078,258,1570,914,586,1242,53,1365,709,381,1037,217,1529,873,545,1201,135,1447,791,463,1119,299,1611,955,627,1283,12,1324,668,340,1652,996,176,1488,832,504,1160,94,1406,750,
268,1580,924,596,1252,63,1375,719,391,1047,227,1539,883,555,1211,145,1457,801,473,1129,309,1621,965,637,1293,22,1334,678,350,1662,1006,186,1498,842,514,1170,104,1416,760,432,1088,
903,575,1231,42,1354,698,370,1026,206,1518,862,534,1190,124,1436,780,452,1108,288,1600,944,616,1272,1316,1313,657,329,1641,985,165,1477,821,493,1149,83,1395,739,411,1067,247,1559,
1270,81,1393,737,409,1065,245,1557,901,573,1229,163,1475,819,491,1147,327,1639,983,655,1311,40,1352,696,368,1680,1024,204,1516,860,532,1188,122,1434,778,450,1106,286,1598,942,614,
1373,717,389,1045,225,1537,881,553,1209,143,1455,799,471,1127,307,1619,963,635,1291,20,1332,676,348,1660,1004,184,1496,840,512,1168,102,1414,758,430,1086,266,1578,922,594,1250,61,
399,1055,235,1547,891,563,1219,153,1465,809,481,1137,317,1629,973,645,1301,30,1342,686,358,1670,1014,194,1506,850,522,1178,112,1424,768,440,1096,276,1588,932,604,1260,71,1383,727,
215,1527,871,543,1199,133,1445,789,461,1117,297,1609,953,625,1281,10,1322,666,338,1650,994,174,1486,830,502,1158,92,1404,748,420,1076,256,1568,912,584,1240,51,1363,707,379,1035,
896,568,1224,158,1470,814,486,1142,322,1634,978,650,1306,35,1347,691,363,1675,1019,199,1511,855,527,1183,117,1429,773,445,1101,281,1593,937,609,1265,76,1388,732,404,1060,240,1552,
1204,138,1450,794,466,1122,302,1614,958,630,1286,15,1327,671,343,1655,999,179,1491,835,507,1163,97,1409,753,425,1081,261,1573,917,589,1245,56,1368,712,384,1040,220,1532,876,548,
1460,804,476,1132,312,1624,968,640,1296,25,1337,681,353,1665,1009,189,1501,845,517,1173,107,1419,763,435,1091,271,1583,927,599,1255,66,1378,722,394,1050,230,1542,886,558,1214,148,
456,1112,292,1604,948,620,1276,5,1317,661,333,1645,989,169,1481,825,497,1153,87,1399,743,415,1071,251,1563,907,579,1235,46,1358,702,374,1030,210,1522,866,538,1194,128,1440,784,
325,1637,981,653,1309,38,1350,694,366,1678,1022,202,1514,858,530,1186,120,1432,776,448,1104,284,1596,940,612,1268,79,1391,735,407,1063,243,1555,899,571,1227,161,1473,817,489,1145,
961,633,1289,18,1330,674,346,1658,1002,182,1494,838,510,1166,100,1412,756,428,1084,264,1576,920,592,1248,59,1371,715,387,1043,223,1535,879,551,1207,141,1453,797,469,1125,305,1617,
1299,28,1340,684,356,1668,1012,192,1504,848,520,1176,110,1422,766,438,1094,274,1586,930,602,1258,69,1381,725,397,1053,233,1545,889,561,1217,151,1463,807,479,1135,315,1627,971,643,
1320,664,336,1648,992,172,1484,828,500,1156,90,1402,746,418,1074,254,1566,910,582,1238,49,1361,705,377,1033,213,1525,869,541,1197,131,1443,787,459,1115,295,1607,951,623,1279,8,
361,1673,1017,197,1509,853,525,1181,115,1427,771,443,1099,279,1591,935,607,1263,74,1386,730,402,1058,238,1550,894,566,1222,156,1468,812,484,1140,320,1632,976,648,1304,33,1345,689,
997,177,1489,833,505,1161,95,1407,751,423,1079,259,1571,915,587,1243,54,1366,710,382,1038,218,1530,874,546,1202,136,1448,792,464,1120,300,1612,956,628,1284,13,1325,669,341,1653,
1499,843,515,1171,105,1417,761,433,1089,269,1581,925,597,1253,64,1376,720,392,1048,228,1540,884,556,1212,146,1458,802,474,1130,310,1622,966,638,1294,23,1335,679,351,1663,1007,187,
494,1150,84,1396,740,412,1068,248,1560,904,576,1232,43,1355,699,371,1027,207,1519,863,535,1191,125,1437,781,453,1109,289,1601,945,617,1273,660,1314,658,330,1642,986,166,1478,822,
121,1433,777,449,1105,285,1597,941,613,1269,80,1392,736,408,1064,244,1556,900,572,1228,162,1474,818,490,1146,326,1638,982,654,1310,39,1351,695,367,1679,1023,203,1515,859,531,1187,
757,429,1085,265,1577,921,593,1249,60,1372,716,388,1044,224,1536,880,552,1208,142,1454,798,470,1126,306,1618,962,634,1290,19,1331,675,347,1659,1003,183,1495,839,511,1167,101,1413,
1095,275,1587,931,603,1259,70,1382,726,398,1054,234,1546,890,562,1218,152,1464,808,480,1136,316,1628,972,644,1300,29,1341,685,357,1669,1013,193,1505,849,521,1177,111,1423,767,439,
1567,911,583,1239,50,1362,706,378,1034,214,1526,870,542,1198,132,1444,788,460,1116,296,1608,952,624,1280,9,1321,665,337,1649,993,173,1485,829,501,1157,91,1403,747,419,1075,255,
608,1264,75,1387,731,403,1059,239,1551,895,567,1223,157,1469,813,485,1141,321,1633,977,649,1305,34,1346,690,362,1674,1018,198,1510,854,526,1182,116,1428,772,444,1100,280,1592,936,
55,1367,711,383,1039,219,1531,875,547,1203,137,1449,793,465,1121,301,1613,957,629,1285,14,1326,670,342,1654,998,178,1490,834,506,1162,96,1408,752,424,1080,260,1572,916,588,1244,
721,393,1049,229,1541,885,557,1213,147,1459,803,475,1131,311,1623,967,639,1295,24,1336,680,352,1664,1008,188,1500,844,516,1172,106,1418,762,434,1090,270,1582,926,598,1254,65,1377,
1028,208,1520,864,536,1192,126,1438,782,454,1110,290,1602,946,618,1274,1271,1315,659,331,1643,987,167,1479,823,495,1151,85,1397,741,413,1069,249,1561,905,577,1233,44,1356,700,372,
1553,897,569,1225,159,1471,815,487,1143,323,1635,979,651,1307,36,1348,692,364,1676,1020,200,1512,856,528,1184,118,1430,774,446,1102,282,1594,938,610,1266,77,1389,733,405,1061,241,
549,1205,139,1451,795,467,1123,303,1615,959,631,1287,16,1328,672,344,1656,1000,180,1492,836,508,1164,98,1410,754,426,1082,262,1574,918,590,1246,57,1369,713,385,1041,221,1533,877,
149,1461,805,477,1133,313,1625,969,641,1297,26,1338,682,354,1666,1010,190,1502,846,518,1174,108,1420,764,436,1092,272,1584,928,600,1256,67,1379,723,395,1051,231,1543,887,559,1215,
785,457,1113,293,1605,949,621,1277,6,1318,662,334,1646,990,170,1482,826,498,1154,88,1400,744,416,1072,252,1564,908,580,1236,47,1359,703,375,1031,211,1523,867,539,1195,129,1441,
1138,318,1630,974,646,1302,31,1343,687,359,1671,1015,195,1507,851,523,1179,113,1425,769,441,1097,277,1589,933,605,1261,72,1384,728,400,1056,236,1548,892,564,1220,154,1466,810,482,
1610,954,626,1282,11,1323,667,339,1651,995,175,1487,831,503,1159,93,1405,749,421,1077,257,1569,913,585,1241,52,1364,708,380,1036,216,1528,872,544,1200,134,1446,790,462,1118,298,
636,1292,21,1333,677,349,1661,1005,185,1497,841,513,1169,103,1415,759,431,1087,267,1579,923,595,1251,62,1374,718,390,1046,226,1538,882,554,1210,144,1456,800,472,1128,308,1620,964,
0,1312,656,328,1640,984,164,1476,820,492,1148,82,1394,738,410,1066,246,1558,902,574,1230,41,1353,697,369,1025,205,1517,861,533,1189,123,1435,779,451,1107,287,1599,943,615,3
};
int tableh19[] = { /* 43 x 43 data */
2,359,1735,1047,187,1563,875,531,1219,101,1477,789,445,1821,1133,273,1649,961,617,1305,58,1434,746,402,1778,1090,230,1606,918,574,1262,144,1520,832,488,1176,316,1692,1004,660,1348,15,1,
1746,1058,198,1574,886,542,1230,112,1488,800,456,1832,1144,284,1660,972,628,1316,69,1445,757,413,1789,1101,241,1617,929,585,1273,155,1531,843,499,1187,327,1703,1015,671,1359,26,1402,714,370,
176,1552,864,520,1208,90,1466,778,434,1810,1122,262,1638,950,606,1294,47,1423,735,391,1767,1079,219,1595,907,563,1251,133,1509,821,477,1165,305,1681,993,649,1337,4,1380,692,348,1724,1036,
899,555,1243,125,1501,813,469,1845,1157,297,1673,985,641,1329,82,1458,770,426,1802,1114,254,1630,942,598,1286,168,1544,856,512,1200,340,1716,1028,684,1372,39,1415,727,383,1759,1071,211,1587,
1222,104,1480,792,448,1824,1136,276,1652,964,620,1308,61,1437,749,405,1781,1093,233,1609,921,577,1265,147,1523,835,491,1179,319,1695,1007,663,1351,18,1394,706,362,1738,1050,190,1566,878,534,
1491,803,459,1835,1147,287,1663,975,631,1319,72,1448,760,416,1792,1104,244,1620,932,588,1276,158,1534,846,502,1190,330,1706,1018,674,1362,29,1405,717,373,1749,1061,201,1577,889,545,1233,115,
437,1813,1125,265,1641,953,609,1297,50,1426,738,394,1770,1082,222,1598,910,566,1254,136,1512,824,480,1168,308,1684,996,652,1340,7,1383,695,351,1727,1039,179,1555,867,523,1211,93,1469,781,
1152,292,1668,980,636,1324,77,1453,765,421,1797,1109,249,1625,937,593,1281,163,1539,851,507,1195,335,1711,1023,679,1367,34,1410,722,378,1754,1066,206,1582,894,550,1238,120,1496,808,464,1840,
1646,958,614,1302,55,1431,743,399,1775,1087,227,1603,915,571,1259,141,1517,829,485,1173,313,1689,1001,657,1345,12,1388,700,356,1732,1044,184,1560,872,528,1216,98,1474,786,442,1818,1130,270,
625,1313,66,1442,754,410,1786,1098,238,1614,926,582,1270,152,1528,840,496,1184,324,1700,1012,668,1356,23,1399,711,367,1743,1055,195,1571,883,539,1227,109,1485,797,453,1829,1141,281,1657,969,
44,1420,732,388,1764,1076,216,1592,904,560,1248,130,1506,818,474,1162,302,1678,990,646,1334,1391,1377,689,345,1721,1033,173,1549,861,517,1205,87,1463,775,431,1807,1119,259,1635,947,603,1291,
773,429,1805,1117,257,1633,945,601,1289,171,1547,859,515,1203,343,1719,1031,687,1375,42,1418,730,386,1762,1074,214,1590,902,558,1246,128,1504,816,472,1848,1160,300,1676,988,644,1332,85,1461,
1784,1096,236,1612,924,580,1268,150,1526,838,494,1182,322,1698,1010,666,1354,21,1397,709,365,1741,1053,193,1569,881,537,1225,107,1483,795,451,1827,1139,279,1655,967,623,1311,64,1440,752,408,
247,1623,935,591,1279,161,1537,849,505,1193,333,1709,1021,677,1365,32,1408,720,376,1752,1064,204,1580,892,548,1236,118,1494,806,462,1838,1150,290,1666,978,634,1322,75,1451,763,419,1795,1107,
913,569,1257,139,1515,827,483,1171,311,1687,999,655,1343,10,1386,698,354,1730,1042,182,1558,870,526,1214,96,1472,784,440,1816,1128,268,1644,956,612,1300,53,1429,741,397,1773,1085,225,1601,
1284,166,1542,854,510,1198,338,1714,1026,682,1370,37,1413,725,381,1757,1069,209,1585,897,553,1241,123,1499,811,467,1843,1155,295,1671,983,639,1327,80,1456,768,424,1800,1112,252,1628,940,596,
1521,833,489,1177,317,1693,1005,661,1349,16,1392,704,360,1736,1048,188,1564,876,532,1220,102,1478,790,446,1822,1134,274,1650,962,618,1306,59,1435,747,403,1779,1091,231,1607,919,575,1263,145,
500,1188,328,1704,1016,672,1360,27,1403,715,371,1747,1059,199,1575,887,543,1231,113,1489,801,457,1833,1145,285,1661,973,629,1317,70,1446,758,414,1790,1102,242,1618,930,586,1274,156,1532,844,
306,1682,994,650,1338,5,1381,693,349,1725,1037,177,1553,865,521,1209,91,1467,779,435,1811,1123,263,1639,951,607,1295,48,1424,736,392,1768,1080,220,1596,908,564,1252,134,1510,822,478,1166,
1029,685,1373,40,1416,728,384,1760,1072,212,1588,900,556,1244,126,1502,814,470,1846,1158,298,1674,986,642,1330,83,1459,771,427,1803,1115,255,1631,943,599,1287,169,1545,857,513,1201,341,1717,
1352,19,1395,707,363,1739,1051,191,1567,879,535,1223,105,1481,793,449,1825,1137,277,1653,965,621,1309,62,1438,750,406,1782,1094,234,1610,922,578,1266,148,1524,836,492,1180,320,1696,1008,664,
1406,718,374,1750,1062,202,1578,890,546,1234,116,1492,804,460,1836,1148,288,1664,976,632,1320,73,1449,761,417,1793,1105,245,1621,933,589,1277,159,1535,847,503,1191,331,1707,1019,675,1363,30,
352,1728,1040,180,1556,868,524,1212,94,1470,782,438,1814,1126,266,1642,954,610,1298,51,1427,739,395,1771,1083,223,1599,911,567,1255,137,1513,825,481,1169,309,1685,997,653,1341,8,1384,696,
1067,207,1583,895,551,1239,121,1497,809,465,1841,1153,293,1669,981,637,1325,78,1454,766,422,1798,1110,250,1626,938,594,1282,164,1540,852,508,1196,336,1712,1024,680,1368,35,1411,723,379,1755,
1561,873,529,1217,99,1475,787,443,1819,1131,271,1647,959,615,1303,56,1432,744,400,1776,1088,228,1604,916,572,1260,142,1518,830,486,1174,314,1690,1002,658,1346,13,1389,701,357,1733,1045,185,
540,1228,110,1486,798,454,1830,1142,282,1658,970,626,1314,67,1443,755,411,1787,1099,239,1615,927,583,1271,153,1529,841,497,1185,325,1701,1013,669,1357,24,1400,712,368,1744,1056,196,1572,884,
88,1464,776,432,1808,1120,260,1636,948,604,1292,45,1421,733,389,1765,1077,217,1593,905,561,1249,131,1507,819,475,1163,303,1679,991,647,1335,703,1378,690,346,1722,1034,174,1550,862,518,1206,
815,471,1847,1159,299,1675,987,643,1331,84,1460,772,428,1804,1116,256,1632,944,600,1288,170,1546,858,514,1202,342,1718,1030,686,1374,41,1417,729,385,1761,1073,213,1589,901,557,1245,127,1503,
1826,1138,278,1654,966,622,1310,63,1439,751,407,1783,1095,235,1611,923,579,1267,149,1525,837,493,1181,321,1697,1009,665,1353,20,1396,708,364,1740,1052,192,1568,880,536,1224,106,1482,794,450,
289,1665,977,633,1321,74,1450,762,418,1794,1106,246,1622,934,590,1278,160,1536,848,504,1192,332,1708,1020,676,1364,31,1407,719,375,1751,1063,203,1579,891,547,1235,117,1493,805,461,1837,1149,
955,611,1299,52,1428,740,396,1772,1084,224,1600,912,568,1256,138,1514,826,482,1170,310,1686,998,654,1342,9,1385,697,353,1729,1041,181,1557,869,525,1213,95,1471,783,439,1815,1127,267,1643,
1326,79,1455,767,423,1799,1111,251,1627,939,595,1283,165,1541,853,509,1197,337,1713,1025,681,1369,36,1412,724,380,1756,1068,208,1584,896,552,1240,122,1498,810,466,1842,1154,294,1670,982,638,
1433,745,401,1777,1089,229,1605,917,573,1261,143,1519,831,487,1175,315,1691,1003,659,1347,14,1390,702,358,1734,1046,186,1562,874,530,1218,100,1476,788,444,1820,1132,272,1648,960,616,1304,57,
412,1788,1100,240,1616,928,584,1272,154,1530,842,498,1186,326,1702,1014,670,1358,25,1401,713,369,1745,1057,197,1573,885,541,1229,111,1487,799,455,1831,1143,283,1659,971,627,1315,68,1444,756,
1078,218,1594,906,562,1250,132,1508,820,476,1164,304,1680,992,648,1336,1333,1379,691,347,1723,1035,175,1551,863,519,1207,89,1465,777,433,1809,1121,261,1637,949,605,1293,46,1422,734,390,1766,
1629,941,597,1285,167,1543,855,511,1199,339,1715,1027,683,1371,38,1414,726,382,1758,1070,210,1586,898,554,1242,124,1500,812,468,1844,1156,296,1672,984,640,1328,81,1457,769,425,1801,1113,253,
576,1264,146,1522,834,490,1178,318,1694,1006,662,1350,17,1393,705,361,1737,1049,189,1565,877,533,1221,103,1479,791,447,1823,1135,275,1651,963,619,1307,60,1436,748,404,1780,1092,232,1608,920,
157,1533,845,501,1189,329,1705,1017,673,1361,28,1404,716,372,1748,1060,200,1576,888,544,1232,114,1490,802,458,1834,1146,286,1662,974,630,1318,71,1447,759,415,1791,1103,243,1619,931,587,1275,
823,479,1167,307,1683,995,651,1339,6,1382,694,350,1726,1038,178,1554,866,522,1210,92,1468,780,436,1812,1124,264,1640,952,608,1296,49,1425,737,393,1769,1081,221,1597,909,565,1253,135,1511,
1194,334,1710,1022,678,1366,33,1409,721,377,1753,1065,205,1581,893,549,1237,119,1495,807,463,1839,1151,291,1667,979,635,1323,76,1452,764,420,1796,1108,248,1624,936,592,1280,162,1538,850,506,
1688,1000,656,1344,11,1387,699,355,1731,1043,183,1559,871,527,1215,97,1473,785,441,1817,1129,269,1645,957,613,1301,54,1430,742,398,1774,1086,226,1602,914,570,1258,140,1516,828,484,1172,312,
667,1355,22,1398,710,366,1742,1054,194,1570,882,538,1226,108,1484,796,452,1828,1140,280,1656,968,624,1312,65,1441,753,409,1785,1097,237,1613,925,581,1269,151,1527,839,495,1183,323,1699,1011,
0,1376,688,344,1720,1032,172,1548,860,516,1204,86,1462,774,430,1806,1118,258,1634,946,602,1290,43,1419,731,387,1763,1075,215,1591,903,559,1247,129,1505,817,473,1161,301,1677,989,645,3
};
int tableh20[] = { /* 45 x 45 data */
2,370,1810,1090,190,1630,910,550,1990,1270,100,1540,820,460,1900,1180,280,1720,1000,640,1360,55,1495,775,415,1855,1135,235,1675,955,595,1315,145,1585,865,505,1945,1225,325,1765,1045,685,1405,10,1,
1838,1118,218,1658,938,578,2018,1298,128,1568,848,488,1928,1208,308,1748,1028,668,1388,83,1523,803,443,1883,1163,263,1703,983,623,1343,173,1613,893,533,1973,1253,353,1793,1073,713,1433,38,1478,758,398,
196,1636,916,556,1996,1276,106,1546,826,466,1906,1186,286,1726,1006,646,1366,61,1501,781,421,1861,1141,241,1681,961,601,1321,151,1591,871,511,1951,1231,331,1771,1051,691,1411,16,1456,736,376,1816,1096,
927,567,2007,1287,117,1557,837,477,1917,1197,297,1737,1017,657,1377,72,1512,792,432,1872,1152,252,1692,972,612,1332,162,1602,882,522,1962,1242,342,1782,1062,702,1422,27,1467,747,387,1827,1107,207,1647,
1984,1264,94,1534,814,454,1894,1174,274,1714,994,634,1354,49,1489,769,409,1849,1129,229,1669,949,589,1309,139,1579,859,499,1939,1219,319,1759,1039,679,1399,4,1444,724,364,1804,1084,184,1624,904,544,
131,1571,851,491,1931,1211,311,1751,1031,671,1391,86,1526,806,446,1886,1166,266,1706,986,626,1346,176,1616,896,536,1976,1256,356,1796,1076,716,1436,41,1481,761,401,1841,1121,221,1661,941,581,2021,1301,
829,469,1909,1189,289,1729,1009,649,1369,64,1504,784,424,1864,1144,244,1684,964,604,1324,154,1594,874,514,1954,1234,334,1774,1054,694,1414,19,1459,739,379,1819,1099,199,1639,919,559,1999,1279,109,1549,
1920,1200,300,1740,1020,660,1380,75,1515,795,435,1875,1155,255,1695,975,615,1335,165,1605,885,525,1965,1245,345,1785,1065,705,1425,30,1470,750,390,1830,1110,210,1650,930,570,2010,1290,120,1560,840,480,
277,1717,997,637,1357,52,1492,772,412,1852,1132,232,1672,952,592,1312,142,1582,862,502,1942,1222,322,1762,1042,682,1402,7,1447,727,367,1807,1087,187,1627,907,547,1987,1267,97,1537,817,457,1897,1177,
1025,665,1385,80,1520,800,440,1880,1160,260,1700,980,620,1340,170,1610,890,530,1970,1250,350,1790,1070,710,1430,35,1475,755,395,1835,1115,215,1655,935,575,2015,1295,125,1565,845,485,1925,1205,305,1745,
1363,58,1498,778,418,1858,1138,238,1678,958,598,1318,148,1588,868,508,1948,1228,328,1768,1048,688,1408,13,1453,733,373,1813,1093,193,1633,913,553,1993,1273,103,1543,823,463,1903,1183,283,1723,1003,643,
1509,789,429,1869,1149,249,1689,969,609,1329,159,1599,879,519,1959,1239,339,1779,1059,699,1419,24,1464,744,384,1824,1104,204,1644,924,564,2004,1284,114,1554,834,474,1914,1194,294,1734,1014,654,1374,69,
406,1846,1126,226,1666,946,586,1306,136,1576,856,496,1936,1216,316,1756,1036,676,1396,1450,1441,721,361,1801,1081,181,1621,901,541,1981,1261,91,1531,811,451,1891,1171,271,1711,991,631,1351,46,1486,766,
1169,269,1709,989,629,1349,179,1619,899,539,1979,1259,359,1799,1079,719,1439,44,1484,764,404,1844,1124,224,1664,944,584,2024,1304,134,1574,854,494,1934,1214,314,1754,1034,674,1394,89,1529,809,449,1889,
1687,967,607,1327,157,1597,877,517,1957,1237,337,1777,1057,697,1417,22,1462,742,382,1822,1102,202,1642,922,562,2002,1282,112,1552,832,472,1912,1192,292,1732,1012,652,1372,67,1507,787,427,1867,1147,247,
618,1338,168,1608,888,528,1968,1248,348,1788,1068,708,1428,33,1473,753,393,1833,1113,213,1653,933,573,2013,1293,123,1563,843,483,1923,1203,303,1743,1023,663,1383,78,1518,798,438,1878,1158,258,1698,978,
146,1586,866,506,1946,1226,326,1766,1046,686,1406,11,1451,731,371,1811,1091,191,1631,911,551,1991,1271,101,1541,821,461,1901,1181,281,1721,1001,641,1361,56,1496,776,416,1856,1136,236,1676,956,596,1316,
894,534,1974,1254,354,1794,1074,714,1434,39,1479,759,399,1839,1119,219,1659,939,579,2019,1299,129,1569,849,489,1929,1209,309,1749,1029,669,1389,84,1524,804,444,1884,1164,264,1704,984,624,1344,174,1614,
1952,1232,332,1772,1052,692,1412,17,1457,737,377,1817,1097,197,1637,917,557,1997,1277,107,1547,827,467,1907,1187,287,1727,1007,647,1367,62,1502,782,422,1862,1142,242,1682,962,602,1322,152,1592,872,512,
343,1783,1063,703,1423,28,1468,748,388,1828,1108,208,1648,928,568,2008,1288,118,1558,838,478,1918,1198,298,1738,1018,658,1378,73,1513,793,433,1873,1153,253,1693,973,613,1333,163,1603,883,523,1963,1243,
1040,680,1400,5,1445,725,365,1805,1085,185,1625,905,545,1985,1265,95,1535,815,455,1895,1175,275,1715,995,635,1355,50,1490,770,410,1850,1130,230,1670,950,590,1310,140,1580,860,500,1940,1220,320,1760,
1437,42,1482,762,402,1842,1122,222,1662,942,582,2022,1302,132,1572,852,492,1932,1212,312,1752,1032,672,1392,87,1527,807,447,1887,1167,267,1707,987,627,1347,177,1617,897,537,1977,1257,357,1797,1077,717,
1460,740,380,1820,1100,200,1640,920,560,2000,1280,110,1550,830,470,1910,1190,290,1730,1010,650,1370,65,1505,785,425,1865,1145,245,1685,965,605,1325,155,1595,875,515,1955,1235,335,1775,1055,695,1415,20,
391,1831,1111,211,1651,931,571,2011,1291,121,1561,841,481,1921,1201,301,1741,1021,661,1381,76,1516,796,436,1876,1156,256,1696,976,616,1336,166,1606,886,526,1966,1246,346,1786,1066,706,1426,31,1471,751,
1088,188,1628,908,548,1988,1268,98,1538,818,458,1898,1178,278,1718,998,638,1358,53,1493,773,413,1853,1133,233,1673,953,593,1313,143,1583,863,503,1943,1223,323,1763,1043,683,1403,8,1448,728,368,1808,
1656,936,576,2016,1296,126,1566,846,486,1926,1206,306,1746,1026,666,1386,81,1521,801,441,1881,1161,261,1701,981,621,1341,171,1611,891,531,1971,1251,351,1791,1071,711,1431,36,1476,756,396,1836,1116,216,
554,1994,1274,104,1544,824,464,1904,1184,284,1724,1004,644,1364,59,1499,779,419,1859,1139,239,1679,959,599,1319,149,1589,869,509,1949,1229,329,1769,1049,689,1409,14,1454,734,374,1814,1094,194,1634,914,
1285,115,1555,835,475,1915,1195,295,1735,1015,655,1375,70,1510,790,430,1870,1150,250,1690,970,610,1330,160,1600,880,520,1960,1240,340,1780,1060,700,1420,25,1465,745,385,1825,1105,205,1645,925,565,2005,
1532,812,452,1892,1172,272,1712,992,632,1352,47,1487,767,407,1847,1127,227,1667,947,587,1307,137,1577,857,497,1937,1217,317,1757,1037,677,1397,730,1442,722,362,1802,1082,182,1622,902,542,1982,1262,92,
493,1933,1213,313,1753,1033,673,1393,88,1528,808,448,1888,1168,268,1708,988,628,1348,178,1618,898,538,1978,1258,358,1798,1078,718,1438,43,1483,763,403,1843,1123,223,1663,943,583,2023,1303,133,1573,853,
1191,291,1731,1011,651,1371,66,1506,786,426,1866,1146,246,1686,966,606,1326,156,1596,876,516,1956,1236,336,1776,1056,696,1416,21,1461,741,381,1821,1101,201,1641,921,561,2001,1281,111,1551,831,471,1911,
1742,1022,662,1382,77,1517,797,437,1877,1157,257,1697,977,617,1337,167,1607,887,527,1967,1247,347,1787,1067,707,1427,32,1472,752,392,1832,1112,212,1652,932,572,2012,1292,122,1562,842,482,1922,1202,302,
639,1359,54,1494,774,414,1854,1134,234,1674,954,594,1314,144,1584,864,504,1944,1224,324,1764,1044,684,1404,9,1449,729,369,1809,1089,189,1629,909,549,1989,1269,99,1539,819,459,1899,1179,279,1719,999,
82,1522,802,442,1882,1162,262,1702,982,622,1342,172,1612,892,532,1972,1252,352,1792,1072,712,1432,37,1477,757,397,1837,1117,217,1657,937,577,2017,1297,127,1567,847,487,1927,1207,307,1747,1027,667,1387,
780,420,1860,1140,240,1680,960,600,1320,150,1590,870,510,1950,1230,330,1770,1050,690,1410,15,1455,735,375,1815,1095,195,1635,915,555,1995,1275,105,1545,825,465,1905,1185,285,1725,1005,645,1365,60,1500,
1871,1151,251,1691,971,611,1331,161,1601,881,521,1961,1241,341,1781,1061,701,1421,26,1466,746,386,1826,1106,206,1646,926,566,2006,1286,116,1556,836,476,1916,1196,296,1736,1016,656,1376,71,1511,791,431,
228,1668,948,588,1308,138,1578,858,498,1938,1218,318,1758,1038,678,1398,1395,1443,723,363,1803,1083,183,1623,903,543,1983,1263,93,1533,813,453,1893,1173,273,1713,993,633,1353,48,1488,768,408,1848,1128,
985,625,1345,175,1615,895,535,1975,1255,355,1795,1075,715,1435,40,1480,760,400,1840,1120,220,1660,940,580,2020,1300,130,1570,850,490,1930,1210,310,1750,1030,670,1390,85,1525,805,445,1885,1165,265,1705,
1323,153,1593,873,513,1953,1233,333,1773,1053,693,1413,18,1458,738,378,1818,1098,198,1638,918,558,1998,1278,108,1548,828,468,1908,1188,288,1728,1008,648,1368,63,1503,783,423,1863,1143,243,1683,963,603,
1604,884,524,1964,1244,344,1784,1064,704,1424,29,1469,749,389,1829,1109,209,1649,929,569,2009,1289,119,1559,839,479,1919,1199,299,1739,1019,659,1379,74,1514,794,434,1874,1154,254,1694,974,614,1334,164,
501,1941,1221,321,1761,1041,681,1401,6,1446,726,366,1806,1086,186,1626,906,546,1986,1266,96,1536,816,456,1896,1176,276,1716,996,636,1356,51,1491,771,411,1851,1131,231,1671,951,591,1311,141,1581,861,
1249,349,1789,1069,709,1429,34,1474,754,394,1834,1114,214,1654,934,574,2014,1294,124,1564,844,484,1924,1204,304,1744,1024,664,1384,79,1519,799,439,1879,1159,259,1699,979,619,1339,169,1609,889,529,1969,
1767,1047,687,1407,12,1452,732,372,1812,1092,192,1632,912,552,1992,1272,102,1542,822,462,1902,1182,282,1722,1002,642,1362,57,1497,777,417,1857,1137,237,1677,957,597,1317,147,1587,867,507,1947,1227,327,
698,1418,23,1463,743,383,1823,1103,203,1643,923,563,2003,1283,113,1553,833,473,1913,1193,293,1733,1013,653,1373,68,1508,788,428,1868,1148,248,1688,968,608,1328,158,1598,878,518,1958,1238,338,1778,1058,
0,1440,720,360,1800,1080,180,1620,900,540,1980,1260,90,1530,810,450,1890,1170,270,1710,990,630,1350,45,1485,765,405,1845,1125,225,1665,945,585,1305,135,1575,855,495,1935,1215,315,1755,1035,675,3
};
int tableh21[] = { /* 47 x 47 data */
2,398,1902,1150,210,1714,962,586,2090,1338,116,1620,868,492,1996,1244,304,1808,1056,680,2184,1432,69,1573,821,445,1949,1197,257,1761,1009,633,2137,1385,163,1667,915,539,2043,1291,351,1855,1103,727,1479,22,1,
1914,1162,222,1726,974,598,2102,1350,128,1632,880,504,2008,1256,316,1820,1068,692,2196,1444,81,1585,833,457,1961,1209,269,1773,1021,645,2149,1397,175,1679,927,551,2055,1303,363,1867,1115,739,1491,34,1538,786,410,
198,1702,950,574,2078,1326,104,1608,856,480,1984,1232,292,1796,1044,668,2172,1420,57,1561,809,433,1937,1185,245,1749,997,621,2125,1373,151,1655,903,527,2031,1279,339,1843,1091,715,1467,10,1514,762,386,1890,1138,
980,604,2108,1356,134,1638,886,510,2014,1262,322,1826,1074,698,2202,1450,87,1591,839,463,1967,1215,275,1779,1027,651,2155,1403,181,1685,933,557,2061,1309,369,1873,1121,745,1497,40,1544,792,416,1920,1168,228,1732,
2084,1332,110,1614,862,486,1990,1238,298,1802,1050,674,2178,1426,63,1567,815,439,1943,1191,251,1755,1003,627,2131,1379,157,1661,909,533,2037,1285,345,1849,1097,721,1473,16,1520,768,392,1896,1144,204,1708,956,580,
122,1626,874,498,2002,1250,310,1814,1062,686,2190,1438,75,1579,827,451,1955,1203,263,1767,1015,639,2143,1391,169,1673,921,545,2049,1297,357,1861,1109,733,1485,28,1532,780,404,1908,1156,216,1720,968,592,2096,1344,
850,474,1978,1226,286,1790,1038,662,2166,1414,51,1555,803,427,1931,1179,239,1743,991,615,2119,1367,145,1649,897,521,2025,1273,333,1837,1085,709,1461,4,1508,756,380,1884,1132,192,1696,944,568,2072,1320,98,1602,
2017,1265,325,1829,1077,701,2205,1453,90,1594,842,466,1970,1218,278,1782,1030,654,2158,1406,184,1688,936,560,2064,1312,372,1876,1124,748,1500,43,1547,795,419,1923,1171,231,1735,983,607,2111,1359,137,1641,889,513,
301,1805,1053,677,2181,1429,66,1570,818,442,1946,1194,254,1758,1006,630,2134,1382,160,1664,912,536,2040,1288,348,1852,1100,724,1476,19,1523,771,395,1899,1147,207,1711,959,583,2087,1335,113,1617,865,489,1993,1241,
1065,689,2193,1441,78,1582,830,454,1958,1206,266,1770,1018,642,2146,1394,172,1676,924,548,2052,1300,360,1864,1112,736,1488,31,1535,783,407,1911,1159,219,1723,971,595,2099,1347,125,1629,877,501,2005,1253,313,1817,
2169,1417,54,1558,806,430,1934,1182,242,1746,994,618,2122,1370,148,1652,900,524,2028,1276,336,1840,1088,712,1464,7,1511,759,383,1887,1135,195,1699,947,571,2075,1323,101,1605,853,477,1981,1229,289,1793,1041,665,
84,1588,836,460,1964,1212,272,1776,1024,648,2152,1400,178,1682,930,554,2058,1306,366,1870,1118,742,1494,37,1541,789,413,1917,1165,225,1729,977,601,2105,1353,131,1635,883,507,2011,1259,319,1823,1071,695,2199,1447,
812,436,1940,1188,248,1752,1000,624,2128,1376,154,1658,906,530,2034,1282,342,1846,1094,718,1470,13,1517,765,389,1893,1141,201,1705,953,577,2081,1329,107,1611,859,483,1987,1235,295,1799,1047,671,2175,1423,60,1564,
1952,1200,260,1764,1012,636,2140,1388,166,1670,918,542,2046,1294,354,1858,1106,730,1482,25,1529,777,401,1905,1153,213,1717,965,589,2093,1341,119,1623,871,495,1999,1247,307,1811,1059,683,2187,1435,72,1576,824,448,
236,1740,988,612,2116,1364,142,1646,894,518,2022,1270,330,1834,1082,706,1458,1526,1505,753,377,1881,1129,189,1693,941,565,2069,1317,95,1599,847,471,1975,1223,283,1787,1035,659,2163,1411,48,1552,800,424,1928,1176,
1033,657,2161,1409,187,1691,939,563,2067,1315,375,1879,1127,751,1503,46,1550,798,422,1926,1174,234,1738,986,610,2114,1362,140,1644,892,516,2020,1268,328,1832,1080,704,2208,1456,93,1597,845,469,1973,1221,281,1785,
2138,1386,164,1668,916,540,2044,1292,352,1856,1104,728,1480,23,1527,775,399,1903,1151,211,1715,963,587,2091,1339,117,1621,869,493,1997,1245,305,1809,1057,681,2185,1433,70,1574,822,446,1950,1198,258,1762,1010,634,
176,1680,928,552,2056,1304,364,1868,1116,740,1492,35,1539,787,411,1915,1163,223,1727,975,599,2103,1351,129,1633,881,505,2009,1257,317,1821,1069,693,2197,1445,82,1586,834,458,1962,1210,270,1774,1022,646,2150,1398,
904,528,2032,1280,340,1844,1092,716,1468,11,1515,763,387,1891,1139,199,1703,951,575,2079,1327,105,1609,857,481,1985,1233,293,1797,1045,669,2173,1421,58,1562,810,434,1938,1186,246,1750,998,622,2126,1374,152,1656,
2062,1310,370,1874,1122,746,1498,41,1545,793,417,1921,1169,229,1733,981,605,2109,1357,135,1639,887,511,2015,1263,323,1827,1075,699,2203,1451,88,1592,840,464,1968,1216,276,1780,1028,652,2156,1404,182,1686,934,558,
346,1850,1098,722,1474,17,1521,769,393,1897,1145,205,1709,957,581,2085,1333,111,1615,863,487,1991,1239,299,1803,1051,675,2179,1427,64,1568,816,440,1944,1192,252,1756,1004,628,2132,1380,158,1662,910,534,2038,1286,
1110,734,1486,29,1533,781,405,1909,1157,217,1721,969,593,2097,1345,123,1627,875,499,2003,1251,311,1815,1063,687,2191,1439,76,1580,828,452,1956,1204,264,1768,1016,640,2144,1392,170,1674,922,546,2050,1298,358,1862,
1462,5,1509,757,381,1885,1133,193,1697,945,569,2073,1321,99,1603,851,475,1979,1227,287,1791,1039,663,2167,1415,52,1556,804,428,1932,1180,240,1744,992,616,2120,1368,146,1650,898,522,2026,1274,334,1838,1086,710,
1548,796,420,1924,1172,232,1736,984,608,2112,1360,138,1642,890,514,2018,1266,326,1830,1078,702,2206,1454,91,1595,843,467,1971,1219,279,1783,1031,655,2159,1407,185,1689,937,561,2065,1313,373,1877,1125,749,1501,44,
396,1900,1148,208,1712,960,584,2088,1336,114,1618,866,490,1994,1242,302,1806,1054,678,2182,1430,67,1571,819,443,1947,1195,255,1759,1007,631,2135,1383,161,1665,913,537,2041,1289,349,1853,1101,725,1477,20,1524,772,
1160,220,1724,972,596,2100,1348,126,1630,878,502,2006,1254,314,1818,1066,690,2194,1442,79,1583,831,455,1959,1207,267,1771,1019,643,2147,1395,173,1677,925,549,2053,1301,361,1865,1113,737,1489,32,1536,784,408,1912,
1700,948,572,2076,1324,102,1606,854,478,1982,1230,290,1794,1042,666,2170,1418,55,1559,807,431,1935,1183,243,1747,995,619,2123,1371,149,1653,901,525,2029,1277,337,1841,1089,713,1465,8,1512,760,384,1888,1136,196,
602,2106,1354,132,1636,884,508,2012,1260,320,1824,1072,696,2200,1448,85,1589,837,461,1965,1213,273,1777,1025,649,2153,1401,179,1683,931,555,2059,1307,367,1871,1119,743,1495,38,1542,790,414,1918,1166,226,1730,978,
1330,108,1612,860,484,1988,1236,296,1800,1048,672,2176,1424,61,1565,813,437,1941,1189,249,1753,1001,625,2129,1377,155,1659,907,531,2035,1283,343,1847,1095,719,1471,14,1518,766,390,1894,1142,202,1706,954,578,2082,
1624,872,496,2000,1248,308,1812,1060,684,2188,1436,73,1577,825,449,1953,1201,261,1765,1013,637,2141,1389,167,1671,919,543,2047,1295,355,1859,1107,731,1483,26,1530,778,402,1906,1154,214,1718,966,590,2094,1342,120,
472,1976,1224,284,1788,1036,660,2164,1412,49,1553,801,425,1929,1177,237,1741,989,613,2117,1365,143,1647,895,519,2023,1271,331,1835,1083,707,1459,774,1506,754,378,1882,1130,190,1694,942,566,2070,1318,96,1600,848,
1267,327,1831,1079,703,2207,1455,92,1596,844,468,1972,1220,280,1784,1032,656,2160,1408,186,1690,938,562,2066,1314,374,1878,1126,750,1502,45,1549,797,421,1925,1173,233,1737,985,609,2113,1361,139,1643,891,515,2019,
1807,1055,679,2183,1431,68,1572,820,444,1948,1196,256,1760,1008,632,2136,1384,162,1666,914,538,2042,1290,350,1854,1102,726,1478,21,1525,773,397,1901,1149,209,1713,961,585,2089,1337,115,1619,867,491,1995,1243,303,
691,2195,1443,80,1584,832,456,1960,1208,268,1772,1020,644,2148,1396,174,1678,926,550,2054,1302,362,1866,1114,738,1490,33,1537,785,409,1913,1161,221,1725,973,597,2101,1349,127,1631,879,503,2007,1255,315,1819,1067,
1419,56,1560,808,432,1936,1184,244,1748,996,620,2124,1372,150,1654,902,526,2030,1278,338,1842,1090,714,1466,9,1513,761,385,1889,1137,197,1701,949,573,2077,1325,103,1607,855,479,1983,1231,291,1795,1043,667,2171,
1590,838,462,1966,1214,274,1778,1026,650,2154,1402,180,1684,932,556,2060,1308,368,1872,1120,744,1496,39,1543,791,415,1919,1167,227,1731,979,603,2107,1355,133,1637,885,509,2013,1261,321,1825,1073,697,2201,1449,86,
438,1942,1190,250,1754,1002,626,2130,1378,156,1660,908,532,2036,1284,344,1848,1096,720,1472,15,1519,767,391,1895,1143,203,1707,955,579,2083,1331,109,1613,861,485,1989,1237,297,1801,1049,673,2177,1425,62,1566,814,
1202,262,1766,1014,638,2142,1390,168,1672,920,544,2048,1296,356,1860,1108,732,1484,27,1531,779,403,1907,1155,215,1719,967,591,2095,1343,121,1625,873,497,2001,1249,309,1813,1061,685,2189,1437,74,1578,826,450,1954,
1742,990,614,2118,1366,144,1648,896,520,2024,1272,332,1836,1084,708,1460,1457,1507,755,379,1883,1131,191,1695,943,567,2071,1319,97,1601,849,473,1977,1225,285,1789,1037,661,2165,1413,50,1554,802,426,1930,1178,238,
653,2157,1405,183,1687,935,559,2063,1311,371,1875,1123,747,1499,42,1546,794,418,1922,1170,230,1734,982,606,2110,1358,136,1640,888,512,2016,1264,324,1828,1076,700,2204,1452,89,1593,841,465,1969,1217,277,1781,1029,
1381,159,1663,911,535,2039,1287,347,1851,1099,723,1475,18,1522,770,394,1898,1146,206,1710,958,582,2086,1334,112,1616,864,488,1992,1240,300,1804,1052,676,2180,1428,65,1569,817,441,1945,1193,253,1757,1005,629,2133,
1675,923,547,2051,1299,359,1863,1111,735,1487,30,1534,782,406,1910,1158,218,1722,970,594,2098,1346,124,1628,876,500,2004,1252,312,1816,1064,688,2192,1440,77,1581,829,453,1957,1205,265,1769,1017,641,2145,1393,171,
523,2027,1275,335,1839,1087,711,1463,6,1510,758,382,1886,1134,194,1698,946,570,2074,1322,100,1604,852,476,1980,1228,288,1792,1040,664,2168,1416,53,1557,805,429,1933,1181,241,1745,993,617,2121,1369,147,1651,899,
1305,365,1869,1117,741,1493,36,1540,788,412,1916,1164,224,1728,976,600,2104,1352,130,1634,882,506,2010,1258,318,1822,1070,694,2198,1446,83,1587,835,459,1963,1211,271,1775,1023,647,2151,1399,177,1681,929,553,2057,
1845,1093,717,1469,12,1516,764,388,1892,1140,200,1704,952,576,2080,1328,106,1610,858,482,1986,1234,294,1798,1046,670,2174,1422,59,1563,811,435,1939,1187,247,1751,999,623,2127,1375,153,1657,905,529,2033,1281,341,
729,1481,24,1528,776,400,1904,1152,212,1716,964,588,2092,1340,118,1622,870,494,1998,1246,306,1810,1058,682,2186,1434,71,1575,823,447,1951,1199,259,1763,1011,635,2139,1387,165,1669,917,541,2045,1293,353,1857,1105,
0,1504,752,376,1880,1128,188,1692,940,564,2068,1316,94,1598,846,470,1974,1222,282,1786,1034,658,2162,1410,47,1551,799,423,1927,1175,235,1739,987,611,2115,1363,141,1645,893,517,2021,1269,329,1833,1081,705,3
};
int MatrixMaxCapacities[21] = { 49, 81, 121, 169, 225, 289, 361, 441, 529, 625, 729, 841, 961, 1089, 1225, 1369, 1521, 1681, 1849, 2025, 2209 };
int MasterRandomStream[] = { /* From Annex L */
0x05,0xff,0xc7,0x31,0x88,0xa8,0x83,0x9c,0x64,0x87,0x9f,0x64,0xb3,0xe0,0x4d,0x9c,0x80,0x29,0x3a,0x90,
0xb3,0x8b,0x9e,0x90,0x45,0xbf,0xf5,0x68,0x4b,0x08,0xcf,0x44,0xb8,0xd4,0x4c,0x5b,0xa0,0xab,0x72,0x52,
0x1c,0xe4,0xd2,0x74,0xa4,0xda,0x8a,0x08,0xfa,0xa7,0xc7,0xdd,0x00,0x30,0xa9,0xe6,0x64,0xab,0xd5,0x8b,
0xed,0x9c,0x79,0xf8,0x08,0xd1,0x8b,0xc6,0x22,0x64,0x0b,0x33,0x43,0xd0,0x80,0xd4,0x44,0x95,0x2e,0x6f,
0x5e,0x13,0x8d,0x47,0x62,0x06,0xeb,0x80,0x82,0xc9,0x41,0xd5,0x73,0x8a,0x30,0x23,0x24,0xe3,0x7f,0xb2,
0xa8,0x0b,0xed,0x38,0x42,0x4c,0xd7,0xb0,0xce,0x98,0xbd,0xe1,0xd5,0xe4,0xc3,0x1d,0x15,0x4a,0xcf,0xd1,
0x1f,0x39,0x26,0x18,0x93,0xfc,0x19,0xb2,0x2d,0xab,0xf2,0x6e,0xa1,0x9f,0xaf,0xd0,0x8a,0x2b,0xa0,0x56,
0xb0,0x41,0x6d,0x43,0xa4,0x63,0xf3,0xaa,0x7d,0xaf,0x35,0x57,0xc2,0x94,0x4a,0x65,0x0b,0x41,0xde,0xb8,
0xe2,0x30,0x12,0x27,0x9b,0x66,0x2b,0x34,0x5b,0xb8,0x99,0xe8,0x28,0x71,0xd0,0x95,0x6b,0x07,0x4d,0x3c,
0x7a,0xb3,0xe5,0x29,0xb3,0xba,0x8c,0xcc,0x2d,0xe0,0xc9,0xc0,0x22,0xec,0x4c,0xde,0xf8,0x58,0x07,0xfc,
0x19,0xf2,0x64,0xe2,0xc3,0xe2,0xd8,0xb9,0xfd,0x67,0xa0,0xbc,0xf5,0x2e,0xc9,0x49,0x75,0x62,0x82,0x27,
0x10,0xf4,0x19,0x6f,0x49,0xf7,0xb3,0x84,0x14,0xea,0xeb,0xe1,0x2a,0x31,0xab,0x47,0x7d,0x08,0x29,0xac,
0xbb,0x72,0xfa,0xfa,0x62,0xb8,0xc8,0xd3,0x86,0x89,0x95,0xfd,0xdf,0xcc,0x9c,0xad,0xf1,0xd4,0x6c,0x64,
0x23,0x24,0x2a,0x56,0x1f,0x36,0xeb,0xb7,0xd6,0xff,0xda,0x57,0xf4,0x50,0x79,0x08,0x00
};
#endif /* __IEC16022ECC200_H */

View File

@ -568,9 +568,6 @@ void QZint::render(QPainter & painter, const QRectF & paintRect, AspectRatioMode
if(((m_zintSymbol->symbology == BARCODE_CODE16K) || (m_zintSymbol->symbology == BARCODE_CODE49)) && (row != 0)) {
painter.fillRect(0,y - 1,m_zintSymbol->width,2,QBrush(m_fgColor));
}
if(((m_zintSymbol->symbology == BARCODE_CODABLOCKF) || (m_zintSymbol->symbology == BARCODE_HIBC_BLOCKF)) && (row != 0)) {
painter.fillRect(11,y - 1,m_zintSymbol->width - 24,2,QBrush(m_fgColor));
}
y+=m_zintSymbol->row_height[row];
}
}

View File

@ -159,9 +159,6 @@ int escape_char_process(struct zint_symbol *my_symbol, unsigned char input_strin
} while (i < length);
escaped_string[j] = '\0';
printf("Input: %s\n", input_string);
printf("Output:%s\n", escaped_string);
error_number = ZBarcode_Encode(my_symbol, escaped_string, j);
return error_number;

View File

@ -1,62 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>grpCodablock</class>
<widget class="QWidget" name="grpCodablock">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>372</width>
<height>175</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QRadioButton" name="radCodaStand">
<property name="text">
<string>S&amp;tandard Mode</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="radCodaHIBC">
<property name="text">
<string>&amp;HIBC Codablock-F</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QRadioButton" name="radCodaGS1">
<property name="text">
<string>&amp;GS-1 Data Mode</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -15,47 +15,196 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QRadioButton" name="radDM200Stand">
<property name="text">
<string>Encoding &amp;Mode:</string>
<string>S&amp;tandard</string>
</property>
<property name="buddy">
<cstring>cmbDMMode</cstring>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="cmbDMMode">
<item row="1" column="1">
<widget class="QRadioButton" name="radDM200HIBC">
<property name="text">
<string>&amp;HIBC Data Matrix</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="radDM200GS1">
<property name="text">
<string>&amp;GS-1 Data Mode</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblDM200Size">
<property name="text">
<string>Si&amp;ze:</string>
</property>
<property name="buddy">
<cstring>cmbDM200Size</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="cmbDM200Size">
<item>
<property name="text">
<string>ECC 200 (Recommended)</string>
<string>Automatic</string>
</property>
</item>
<item>
<property name="text">
<string>ECC 000</string>
<string>10 x 10</string>
</property>
</item>
<item>
<property name="text">
<string>ECC 050</string>
<string>12 x 12</string>
</property>
</item>
<item>
<property name="text">
<string>ECC 080</string>
<string>14 x 14</string>
</property>
</item>
<item>
<property name="text">
<string>ECC 100</string>
<string>16 x 16</string>
</property>
</item>
<item>
<property name="text">
<string>ECC 140</string>
<string>18 x 18</string>
</property>
</item>
<item>
<property name="text">
<string>20 x 20</string>
</property>
</item>
<item>
<property name="text">
<string>22 x 22</string>
</property>
</item>
<item>
<property name="text">
<string>24 x 24</string>
</property>
</item>
<item>
<property name="text">
<string>26 x 26</string>
</property>
</item>
<item>
<property name="text">
<string>32 x 32</string>
</property>
</item>
<item>
<property name="text">
<string>36 x 36</string>
</property>
</item>
<item>
<property name="text">
<string>40 x 40</string>
</property>
</item>
<item>
<property name="text">
<string>44 x 44</string>
</property>
</item>
<item>
<property name="text">
<string>48 x 48</string>
</property>
</item>
<item>
<property name="text">
<string>52 x 52</string>
</property>
</item>
<item>
<property name="text">
<string>64 x 64</string>
</property>
</item>
<item>
<property name="text">
<string>72 x 72</string>
</property>
</item>
<item>
<property name="text">
<string>80 x 80</string>
</property>
</item>
<item>
<property name="text">
<string>88 x 88</string>
</property>
</item>
<item>
<property name="text">
<string>96 x 96</string>
</property>
</item>
<item>
<property name="text">
<string>104 x 104</string>
</property>
</item>
<item>
<property name="text">
<string>120 x 120</string>
</property>
</item>
<item>
<property name="text">
<string>132 x 132</string>
</property>
</item>
<item>
<property name="text">
<string>144 x 144</string>
</property>
</item>
<item>
<property name="text">
<string>8 x 18</string>
</property>
</item>
<item>
<property name="text">
<string>8 x 32</string>
</property>
</item>
<item>
<property name="text">
<string>12 x 26</string>
</property>
</item>
<item>
<property name="text">
<string>12 x 36</string>
</property>
</item>
<item>
<property name="text">
<string>16 x 36</string>
</property>
</item>
<item>
<property name="text">
<string>16 x 48</string>
</property>
</item>
</widget>
@ -63,355 +212,13 @@
</layout>
</item>
<item>
<widget class="QGroupBox" name="grpDMNon200">
<property name="title">
<string>Non ECC 200 Options</string>
<widget class="QCheckBox" name="chkDMRectangle">
<property name="text">
<string>Suppress Rectangular Symbols in Automatic Mode</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="lblDMNon200Size">
<property name="text">
<string>Si&amp;ze:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>cmbDMNon200Size</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="cmbDMNon200Size">
<item>
<property name="text">
<string>Automatic</string>
</property>
</item>
<item>
<property name="text">
<string>9 x 9</string>
</property>
</item>
<item>
<property name="text">
<string>11 x 11</string>
</property>
</item>
<item>
<property name="text">
<string>13 x 13</string>
</property>
</item>
<item>
<property name="text">
<string>15 x 15</string>
</property>
</item>
<item>
<property name="text">
<string>17 x 17</string>
</property>
</item>
<item>
<property name="text">
<string>19 x 19</string>
</property>
</item>
<item>
<property name="text">
<string>21 x 21</string>
</property>
</item>
<item>
<property name="text">
<string>23 x 23</string>
</property>
</item>
<item>
<property name="text">
<string>25 x 25</string>
</property>
</item>
<item>
<property name="text">
<string>27 x 27</string>
</property>
</item>
<item>
<property name="text">
<string>29 x 29</string>
</property>
</item>
<item>
<property name="text">
<string>31 x 31</string>
</property>
</item>
<item>
<property name="text">
<string>33 x 33</string>
</property>
</item>
<item>
<property name="text">
<string>35 x 35</string>
</property>
</item>
<item>
<property name="text">
<string>37 x 37</string>
</property>
</item>
<item>
<property name="text">
<string>39 x 39</string>
</property>
</item>
<item>
<property name="text">
<string>41 x 41</string>
</property>
</item>
<item>
<property name="text">
<string>43 x 43</string>
</property>
</item>
<item>
<property name="text">
<string>45 x 45</string>
</property>
</item>
<item>
<property name="text">
<string>47 x 47</string>
</property>
</item>
<item>
<property name="text">
<string>49 x 49</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="grpDM200">
<property name="title">
<string>ECC 200 Options</string>
<property name="checked">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="virticalInner">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QRadioButton" name="radDM200Stand">
<property name="text">
<string>S&amp;tandard</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QRadioButton" name="radDM200HIBC">
<property name="text">
<string>&amp;HIBC Data Matrix</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="radDM200GS1">
<property name="text">
<string>&amp;GS-1 Data Mode</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblDM200Size">
<property name="text">
<string>Si&amp;ze:</string>
</property>
<property name="buddy">
<cstring>cmbDM200Size</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="cmbDM200Size">
<item>
<property name="text">
<string>Automatic</string>
</property>
</item>
<item>
<property name="text">
<string>10 x 10</string>
</property>
</item>
<item>
<property name="text">
<string>12 x 12</string>
</property>
</item>
<item>
<property name="text">
<string>14 x 14</string>
</property>
</item>
<item>
<property name="text">
<string>16 x 16</string>
</property>
</item>
<item>
<property name="text">
<string>18 x 18</string>
</property>
</item>
<item>
<property name="text">
<string>20 x 20</string>
</property>
</item>
<item>
<property name="text">
<string>22 x 22</string>
</property>
</item>
<item>
<property name="text">
<string>24 x 24</string>
</property>
</item>
<item>
<property name="text">
<string>26 x 26</string>
</property>
</item>
<item>
<property name="text">
<string>32 x 32</string>
</property>
</item>
<item>
<property name="text">
<string>36 x 36</string>
</property>
</item>
<item>
<property name="text">
<string>40 x 40</string>
</property>
</item>
<item>
<property name="text">
<string>44 x 44</string>
</property>
</item>
<item>
<property name="text">
<string>48 x 48</string>
</property>
</item>
<item>
<property name="text">
<string>52 x 52</string>
</property>
</item>
<item>
<property name="text">
<string>64 x 64</string>
</property>
</item>
<item>
<property name="text">
<string>72 x 72</string>
</property>
</item>
<item>
<property name="text">
<string>80 x 80</string>
</property>
</item>
<item>
<property name="text">
<string>88 x 88</string>
</property>
</item>
<item>
<property name="text">
<string>96 x 96</string>
</property>
</item>
<item>
<property name="text">
<string>104 x 104</string>
</property>
</item>
<item>
<property name="text">
<string>120 x 120</string>
</property>
</item>
<item>
<property name="text">
<string>132 x 132</string>
</property>
</item>
<item>
<property name="text">
<string>144 x 144</string>
</property>
</item>
<item>
<property name="text">
<string>8 x 18</string>
</property>
</item>
<item>
<property name="text">
<string>8 x 32</string>
</property>
</item>
<item>
<property name="text">
<string>12 x 26</string>
</property>
</item>
<item>
<property name="text">
<string>12 x 36</string>
</property>
</item>
<item>
<property name="text">
<string>16 x 36</string>
</property>
</item>
<item>
<property name="text">
<string>16 x 48</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="chkDMRectangle">
<property name="text">
<string>Suppress Rectangular Symbols in Automatic Mode</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>

View File

@ -349,15 +349,11 @@ void MainWindow::change_options()
m_optionWidget=uiload.load(&file);
file.close();
tabMain->insertTab(1,m_optionWidget,tr("Data Matrix"));
connect(m_optionWidget->findChild<QObject*>("cmbDMMode"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("cmbDMMode"), SIGNAL(currentIndexChanged( int )), SLOT(datamatrix_options()));
connect(m_optionWidget->findChild<QObject*>("radDM200Stand"), SIGNAL(clicked( bool )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("radDM200GS1"), SIGNAL(clicked( bool )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("radDM200HIBC"), SIGNAL(clicked( bool )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("cmbDM200Size"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("cmbDMNon200Size"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview()));
connect(m_optionWidget->findChild<QObject*>("chkDMRectangle"), SIGNAL(stateChanged( int )), SLOT(update_preview()));
datamatrix_options();
}
if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_QRCODE)
@ -516,23 +512,6 @@ void MainWindow::composite_ean_check()
chkComposite->setChecked(false);
}
void MainWindow::datamatrix_options()
{
if (metaObject()->enumerator(0).value(bstyle->currentIndex())!=BARCODE_DATAMATRIX)
return;
if(m_optionWidget->findChild<QComboBox*>("cmbDMMode")->currentIndex() == 0)
{
m_optionWidget->findChild<QGroupBox*>("grpDMNon200")->hide();
m_optionWidget->findChild<QGroupBox*>("grpDM200")->show();
}
else
{
m_optionWidget->findChild<QGroupBox*>("grpDM200")->hide();
m_optionWidget->findChild<QGroupBox*>("grpDMNon200")->show();
}
}
void MainWindow::maxi_primary()
{
if (metaObject()->enumerator(0).value(bstyle->currentIndex())!=BARCODE_MAXICODE)
@ -718,39 +697,21 @@ void MainWindow::update_preview()
m_bc.bc.setInputMode(GS1_MODE);
break;
case BARCODE_CODABLOCKF:
if(m_optionWidget->findChild<QRadioButton*>("radCodaGS1")->isChecked())
case BARCODE_DATAMATRIX:
m_bc.bc.setSecurityLevel(1);
if(m_optionWidget->findChild<QRadioButton*>("radDM200HIBC")->isChecked())
m_bc.bc.setSymbol(BARCODE_HIBC_DM);
else
m_bc.bc.setSymbol(BARCODE_DATAMATRIX);
if(m_optionWidget->findChild<QRadioButton*>("radDM200GS1")->isChecked())
m_bc.bc.setInputMode(GS1_MODE);
if(m_optionWidget->findChild<QRadioButton*>("radCodaHIBC")->isChecked())
m_bc.bc.setSymbol(BARCODE_HIBC_BLOCKF);
m_bc.bc.setWidth(m_optionWidget->findChild<QComboBox*>("cmbDM200Size")->currentIndex());
if(m_optionWidget->findChild<QCheckBox*>("chkDMRectangle")->isChecked())
m_bc.bc.setOption3(DM_SQUARE);
else
m_bc.bc.setSymbol(BARCODE_CODABLOCKF);
break;
case BARCODE_DATAMATRIX:
m_bc.bc.setSecurityLevel(m_optionWidget->findChild<QComboBox*>("cmbDMMode")->currentIndex() + 1);
if(m_optionWidget->findChild<QComboBox*>("cmbDMMode")->currentIndex() == 0)
{ /* ECC 200 */
if(m_optionWidget->findChild<QRadioButton*>("radDM200HIBC")->isChecked())
m_bc.bc.setSymbol(BARCODE_HIBC_DM);
else
m_bc.bc.setSymbol(BARCODE_DATAMATRIX);
if(m_optionWidget->findChild<QRadioButton*>("radDM200GS1")->isChecked())
m_bc.bc.setInputMode(GS1_MODE);
m_bc.bc.setWidth(m_optionWidget->findChild<QComboBox*>("cmbDM200Size")->currentIndex());
if(m_optionWidget->findChild<QCheckBox*>("chkDMRectangle")->isChecked())
m_bc.bc.setOption3(DM_SQUARE);
else
m_bc.bc.setOption3(0);
}
else
{ /* Not ECC 200 */
m_bc.bc.setSymbol(BARCODE_DATAMATRIX);
m_bc.bc.setWidth(m_optionWidget->findChild<QComboBox*>("cmbDMNon200Size")->currentIndex());
}
m_bc.bc.setOption3(0);
break;
case BARCODE_QRCODE:

View File

@ -113,7 +113,6 @@ public slots:
void on_bgcolor_clicked();
void composite_enable();
void composite_ean_check();
void datamatrix_options();
void maxi_primary();
void change_print_scale();

View File

@ -14,7 +14,6 @@
<file>grpMaxicode.ui</file>
<file>grpPDF417.ui</file>
<file>grpC16k.ui</file>
<file>grpCodablock.ui</file>
<file>grpMQR.ui</file>
<file>grpQR.ui</file>
<file>grpCodeOne.ui</file>