diff --git a/DroidFish/jni/Android.mk b/DroidFish/jni/Android.mk
index 62b2b0d..cb62fcc 100644
--- a/DroidFish/jni/Android.mk
+++ b/DroidFish/jni/Android.mk
@@ -6,10 +6,12 @@ LOCAL_MODULE := nativeutil
LOCAL_SRC_FILES := nativeutil.cpp
LOCAL_CFLAGS := \
- -mandroid \
+ -mandroid \
-DTARGET_OS=android -D__ANDROID__ \
-isystem $(SYSROOT)/usr/include
include $(BUILD_SHARED_LIBRARY)
include jni/stockfish/Android.mk
+
+include jni/gtb/Android.mk
diff --git a/DroidFish/jni/gtb/Android.mk b/DroidFish/jni/gtb/Android.mk
new file mode 100644
index 0000000..34e86a8
--- /dev/null
+++ b/DroidFish/jni/gtb/Android.mk
@@ -0,0 +1,25 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := gtb
+LOCAL_SRC_FILES := \
+ gtb-probe.c gtb-dec.c gtb-att.c sysport/sysport.c compression/wrap.c \
+ compression/huffman/hzip.c compression/lzma/LzmaEnc.c compression/lzma/LzmaDec.c \
+ compression/lzma/Alloc.c compression/lzma/LzFind.c compression/lzma/Lzma86Enc.c \
+ compression/lzma/Lzma86Dec.c compression/lzma/Bra86.c compression/zlib/zcompress.c \
+ compression/zlib/uncompr.c compression/zlib/inflate.c compression/zlib/deflate.c \
+ compression/zlib/adler32.c compression/zlib/crc32.c compression/zlib/infback.c \
+ compression/zlib/inffast.c compression/zlib/inftrees.c compression/zlib/trees.c \
+ compression/zlib/zutil.c compression/liblzf/lzf_c.c compression/liblzf/lzf_d.c \
+ GtbProbe.cpp
+
+LOCAL_CFLAGS := \
+ -I $(LOCAL_PATH)/sysport/ -I $(LOCAL_PATH)/compression/ \
+ -I $(LOCAL_PATH)/compression/liblzf/ -I $(LOCAL_PATH)/compression/zlib/ \
+ -I $(LOCAL_PATH)/compression/lzma/ -I $(LOCAL_PATH)/compression/huffman/ \
+ -D Z_PREFIX -D NDEBUG -Wall\
+ -mandroid -DTARGET_OS=android -D__ANDROID__ \
+ -isystem $(SYSROOT)/usr/include
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/DroidFish/jni/gtb/GtbProbe.cpp b/DroidFish/jni/gtb/GtbProbe.cpp
new file mode 100644
index 0000000..cbfbf73
--- /dev/null
+++ b/DroidFish/jni/gtb/GtbProbe.cpp
@@ -0,0 +1,130 @@
+/*
+ DroidFish - An Android chess program.
+ Copyright (C) 2011-2012 Peter Österlund, peterosterlund2@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+#include "GtbProbe.h"
+#include "gtb-probe.h"
+#include
+
+using namespace std;
+
+static bool isInitialized = false;
+static bool initOk = false;
+static const char** paths = NULL;
+
+
+JNIEXPORT jboolean
+JNICALL Java_org_petero_droidfish_gtb_GtbProbe_init(
+ JNIEnv* env, jclass cls, jstring jTbPath)
+{
+ initOk = false;
+ const char* tbPath = (*env).GetStringUTFChars(jTbPath, NULL);
+ if (!tbPath)
+ return false;
+
+ if (isInitialized && paths)
+ tbpaths_done(paths);
+ paths = tbpaths_init();
+ if (paths == NULL) {
+ (*env).ReleaseStringUTFChars(jTbPath, tbPath);
+ return false;
+ }
+ paths = tbpaths_add(paths, tbPath);
+ if (paths == NULL) {
+ (*env).ReleaseStringUTFChars(jTbPath, tbPath);
+ return false;
+ }
+
+ TB_compression_scheme scheme = tb_CP4;
+ int verbose = 0;
+ int cacheSize = 4*1024*1024;
+ int wdlFraction = 8;
+ if (isInitialized) {
+ tb_restart (verbose, scheme, paths);
+ tbcache_restart(cacheSize, wdlFraction);
+ } else {
+ tb_init(verbose, scheme, paths);
+ tbcache_init(cacheSize, wdlFraction);
+ }
+ isInitialized = true;
+
+ (*env).ReleaseStringUTFChars(jTbPath, tbPath);
+ initOk = true;
+ return true;
+}
+
+#define WHITE_TO_MOVE 0
+#define BLACK_TO_MOVE 1
+
+JNIEXPORT jboolean
+JNICALL Java_org_petero_droidfish_gtb_GtbProbe_probeHard(
+ JNIEnv* env, jobject ths,
+ jboolean wtm, jint epSq, jint castleMask,
+ jintArray whiteSquares, jintArray blackSquares,
+ jbyteArray whitePieces, jbyteArray blackPieces,
+ jintArray result)
+{
+ if (!initOk)
+ return false;
+ if ((*env).GetArrayLength(result) < 2)
+ return false;
+
+ const int MAXLEN = 17;
+ unsigned char wp[MAXLEN];
+ unsigned int ws[MAXLEN];
+ unsigned char bp[MAXLEN];
+ unsigned int bs[MAXLEN];
+
+ int len = (*env).GetArrayLength(whiteSquares);
+ jint* jiPtr = (*env).GetIntArrayElements(whiteSquares, NULL);
+ for (int i = 0; i < min(len, MAXLEN); i++)
+ ws[i] = jiPtr[i];
+ (*env).ReleaseIntArrayElements(whiteSquares, jiPtr, 0);
+
+ len = (*env).GetArrayLength(blackSquares);
+ jiPtr = (*env).GetIntArrayElements(blackSquares, NULL);
+ for (int i = 0; i < min(len, MAXLEN); i++)
+ bs[i] = jiPtr[i];
+ (*env).ReleaseIntArrayElements(blackSquares, jiPtr, 0);
+
+ len = (*env).GetArrayLength(whitePieces);
+ jbyte* jcPtr = (*env).GetByteArrayElements(whitePieces, NULL);
+ for (int i = 0; i < min(len, MAXLEN); i++)
+ wp[i] = jcPtr[i];
+ (*env).ReleaseByteArrayElements(whitePieces, jcPtr, 0);
+
+ len = (*env).GetArrayLength(blackPieces);
+ jcPtr = (*env).GetByteArrayElements(blackPieces, NULL);
+ for (int i = 0; i < min(len, MAXLEN); i++)
+ bp[i] = jcPtr[i];
+ (*env).ReleaseByteArrayElements(blackPieces, jcPtr, 0);
+
+ unsigned int tbInfo;
+ unsigned int plies;
+ int ret = tb_probe_hard(wtm ? WHITE_TO_MOVE : BLACK_TO_MOVE,
+ epSq, castleMask,
+ ws,
+ bs,
+ wp,
+ bp,
+ &tbInfo, &plies);
+ jint res[2];
+ res[0] = tbInfo;
+ res[1] = plies;
+
+ (*env).SetIntArrayRegion(result, 0, 2, res);
+ return ret != 0;
+}
diff --git a/DroidFish/jni/gtb/GtbProbe.h b/DroidFish/jni/gtb/GtbProbe.h
new file mode 100644
index 0000000..3137625
--- /dev/null
+++ b/DroidFish/jni/gtb/GtbProbe.h
@@ -0,0 +1,63 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class org_petero_droidfish_gtb_GtbProbe */
+
+#ifndef _Included_org_petero_droidfish_gtb_GtbProbe
+#define _Included_org_petero_droidfish_gtb_GtbProbe
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef org_petero_droidfish_gtb_GtbProbe_NOPIECE
+#define org_petero_droidfish_gtb_GtbProbe_NOPIECE 0L
+#undef org_petero_droidfish_gtb_GtbProbe_PAWN
+#define org_petero_droidfish_gtb_GtbProbe_PAWN 1L
+#undef org_petero_droidfish_gtb_GtbProbe_KNIGHT
+#define org_petero_droidfish_gtb_GtbProbe_KNIGHT 2L
+#undef org_petero_droidfish_gtb_GtbProbe_BISHOP
+#define org_petero_droidfish_gtb_GtbProbe_BISHOP 3L
+#undef org_petero_droidfish_gtb_GtbProbe_ROOK
+#define org_petero_droidfish_gtb_GtbProbe_ROOK 4L
+#undef org_petero_droidfish_gtb_GtbProbe_QUEEN
+#define org_petero_droidfish_gtb_GtbProbe_QUEEN 5L
+#undef org_petero_droidfish_gtb_GtbProbe_KING
+#define org_petero_droidfish_gtb_GtbProbe_KING 6L
+#undef org_petero_droidfish_gtb_GtbProbe_NOSQUARE
+#define org_petero_droidfish_gtb_GtbProbe_NOSQUARE 64L
+#undef org_petero_droidfish_gtb_GtbProbe_H1_CASTLE
+#define org_petero_droidfish_gtb_GtbProbe_H1_CASTLE 8L
+#undef org_petero_droidfish_gtb_GtbProbe_A1_CASTLE
+#define org_petero_droidfish_gtb_GtbProbe_A1_CASTLE 4L
+#undef org_petero_droidfish_gtb_GtbProbe_H8_CASTLE
+#define org_petero_droidfish_gtb_GtbProbe_H8_CASTLE 2L
+#undef org_petero_droidfish_gtb_GtbProbe_A8_CASTLE
+#define org_petero_droidfish_gtb_GtbProbe_A8_CASTLE 1L
+#undef org_petero_droidfish_gtb_GtbProbe_DRAW
+#define org_petero_droidfish_gtb_GtbProbe_DRAW 0L
+#undef org_petero_droidfish_gtb_GtbProbe_WMATE
+#define org_petero_droidfish_gtb_GtbProbe_WMATE 1L
+#undef org_petero_droidfish_gtb_GtbProbe_BMATE
+#define org_petero_droidfish_gtb_GtbProbe_BMATE 2L
+#undef org_petero_droidfish_gtb_GtbProbe_FORBID
+#define org_petero_droidfish_gtb_GtbProbe_FORBID 3L
+#undef org_petero_droidfish_gtb_GtbProbe_UNKNOWN
+#define org_petero_droidfish_gtb_GtbProbe_UNKNOWN 7L
+/*
+ * Class: org_petero_droidfish_gtb_GtbProbe
+ * Method: probeHard
+ * Signature: (ZII[I[I[B[B[I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_petero_droidfish_gtb_GtbProbe_probeHard
+ (JNIEnv *, jobject, jboolean, jint, jint, jintArray, jintArray, jbyteArray, jbyteArray, jintArray);
+
+/*
+ * Class: org_petero_droidfish_gtb_GtbProbe
+ * Method: init
+ * Signature: (Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_org_petero_droidfish_gtb_GtbProbe_init
+ (JNIEnv *, jclass, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/DroidFish/jni/gtb/compression/huffman/ChangeLog b/DroidFish/jni/gtb/compression/huffman/ChangeLog
new file mode 100644
index 0000000..e69de29
diff --git a/DroidFish/jni/gtb/compression/huffman/hzip.c b/DroidFish/jni/gtb/compression/huffman/hzip.c
new file mode 100644
index 0000000..7419d0e
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/huffman/hzip.c
@@ -0,0 +1,973 @@
+/* hzip.c */
+/*
+| Routines designed to be used as a pilot experiment for compression
+| of tablebases. Not really optimized, but they are supposed to work
+| --Miguel A. Ballicora
+*/
+
+/*
+This Software is distributed with the following X11 License,
+sometimes also known as MIT license.
+
+Copyright (c) 2010 Miguel A. Ballicora
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "hzip.h"
+
+/*-------------------------------------------------------------------*\
+|
+| Huffman coding compression
+|
+\*-------------------------------------------------------------------*/
+
+#include
+#include
+#include
+#include
+
+#define MAXDIVERSITY (256)
+#define MAXHEAP (MAXDIVERSITY+1)
+#define MAXSTREAM (1<<18)
+#define MAXHUFF (2*MAXDIVERSITY)
+
+typedef int bool_t;
+
+#define TRUE 1
+#define FALSE 0;
+
+/* huffman tree */
+struct huff {
+ int freq;
+ int value;
+ int pleft;
+ int pright;
+ bool_t isleaf;
+};
+
+static int huff_end;
+static struct huff hufftree[MAXHUFF];
+
+/* heap */
+struct element {
+ int freq;
+ int huffidx;
+};
+
+static int heap_end;
+static struct element heap[MAXHEAP];
+
+unsigned char streambuffer[MAXSTREAM];
+
+/* stream */
+struct STREAM {
+ unsigned long pbit;
+ unsigned char *x;
+};
+
+typedef struct STREAM stream_t;
+
+/* read only */
+struct RO_STREAM {
+ unsigned long pbit;
+ const unsigned char *x;
+};
+
+typedef struct RO_STREAM ro_stream_t;
+
+/*
+|
+| VARIABLES
+|
+\*---------------------------*/
+
+static int freq[MAXDIVERSITY];
+static unsigned code_table[MAXDIVERSITY];
+static unsigned size_table[MAXDIVERSITY];
+static stream_t Stream = {0, NULL};
+static ro_stream_t RO_Stream = {0, NULL};
+static const unsigned int VALUEBITS = 8u;
+
+/*==== PROTOTYPES======================================*/
+
+
+/* heap */
+
+static void freq_init (const unsigned char *in, size_t max);
+static void heap_init (void);
+static void heap_append (struct element e);
+static void heap_sift_up (int x);
+static void heap_adjust_down (int top, int last);
+
+
+/* hufftree */
+
+static int hufftree_from_freq (void);
+static int hufftree_from_heap (void);
+static void hufftree_to_codes (int start, int n, unsigned code);
+static void hufftree_reset (void);
+static int hufftree_frombits (ro_stream_t *stream, bool_t *pok);
+static void hufftree_tobits (int thisnode, stream_t *stream);
+static unsigned int hufftree_readstream (int root, ro_stream_t *s);
+
+/* stream */
+
+/* read only */
+static void ro_stream_rewind (ro_stream_t *s);
+static void ro_stream_init (ro_stream_t *s, const unsigned char *buffer);
+static void ro_stream_done (ro_stream_t *s);
+
+/* read and write */
+static void stream_clear (stream_t *s);
+static void stream_init (stream_t *s, unsigned char *buffer);
+static void stream_done (stream_t *s);
+static size_t stream_len (stream_t *s);
+
+static void stream_rewind (stream_t *s);
+static unsigned int stream_nextbit (ro_stream_t *s);
+static unsigned int stream_nextbit_n (ro_stream_t *s, unsigned int width);
+static void stream_writebit (stream_t *s, unsigned z);
+static void stream_write_n (unsigned code, unsigned width, stream_t *s);
+
+
+static bool_t decode_from_stream (ro_stream_t *stream, size_t n, unsigned char *out);
+static void encode_to_stream (const unsigned char *in, size_t inlen, stream_t *stream);
+
+/*static unsigned int stream_next8 (stream_t *s);*/
+/*static void stream_write8 (stream_t *s, unsigned z);*/
+
+/* supporting functions */
+
+/*
+static void heap_plot (void);
+static int fill_block(unsigned char *out);
+static char *binstream(unsigned int x, int n);
+static void stream_print(stream_t *s, int n);
+static void stream_printnext (stream_t *s, int n);
+static void stream_dump (stream_t *s, int ori, int n);
+static void freq_report (void);
+*/
+
+/*=== ENCODE/DECODE=================================================*/
+
+size_t TB_hzip_unused;
+
+static int
+huffman_decode (size_t z, const unsigned char *bz, size_t n, unsigned char *bp)
+/* bz:buffer huffman zipped to bp:buffer decoded */
+{
+ bool_t ok;
+ TB_hzip_unused = z; /* to silence compiler */
+ ro_stream_init (&RO_Stream, bz);
+ ok = decode_from_stream (&RO_Stream, n, bp);
+ ro_stream_done (&RO_Stream);
+ return ok;
+}
+
+static int
+huffman_encode (size_t n, const unsigned char *bp, size_t *z, unsigned char *bz)
+/* bz:buffer huffman zipped to bp:buffer decoded */
+{
+ size_t i, zz;
+ stream_init (&Stream, streambuffer);
+ encode_to_stream (bp, n, &Stream);
+ zz = stream_len (&Stream);
+ for (i = 0; i < zz; i++) {
+ bz[i] = Stream.x[i];
+ }
+ *z = zz;
+ stream_done (&Stream);
+ return TRUE;
+}
+
+extern int
+huff_decode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max)
+{
+ size_t n = (size_t)in_start[0]
+ | ((size_t)in_start[1] << 8)
+ | ((size_t)in_start[2] << 16)
+ | ((size_t)in_start[3] << 24);
+ TB_hzip_unused = out_max;
+ *pout_len = n;
+ return huffman_decode (in_len-4, in_start+4, n, out_start);
+}
+
+
+extern int
+huff_encode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max)
+{
+ bool_t ok;
+ size_t hlen = 0;
+ TB_hzip_unused = out_max;
+ out_start[0] = (unsigned char) ((in_len ) & 0xffu);
+ out_start[1] = (unsigned char) ((in_len >> 8) & 0xffu);
+ out_start[2] = (unsigned char) ((in_len >> 16) & 0xffu);
+ out_start[3] = (unsigned char) ((in_len >> 24) & 0xffu);
+ ok = huffman_encode (in_len, in_start, &hlen, out_start+4);
+ *pout_len = hlen + 4;
+ return ok;
+}
+
+
+static bool_t
+decode_from_stream (ro_stream_t *s, size_t n, unsigned char *out)
+{
+ int root;
+ bool_t ok = TRUE; /* default */
+
+ hufftree_reset ();
+ ro_stream_rewind (s);
+ root = hufftree_frombits (s, &ok);
+
+ if (ok) {
+ while (n-->0) {
+ *out++ = (unsigned char) hufftree_readstream (root, s); /* cast to silence compiler */
+ }
+ }
+ return ok;
+}
+
+
+static void
+encode_to_stream (const unsigned char *in, size_t inlen, stream_t *stream)
+{
+ size_t i;
+ unsigned x, c, s;
+ int root;
+
+ stream_clear (&Stream);
+ stream_rewind(&Stream);
+
+ /* pass to collect frequencies */
+ freq_init (in, inlen);
+
+ /* frequency --> heap --> hufftrees */
+ root = hufftree_from_freq();
+
+ /* hufftree --> codes */
+ hufftree_to_codes (root, 0, 0);
+
+ /* hufftrees --> stored in bits (stream) */
+ hufftree_tobits (root, stream) ;
+
+ /* input + codes --> stored in bits (stream) */
+ for (i = 0; i < inlen; i++) {
+ x = in[i];
+ c = code_table[x];
+ s = size_table[x];
+ stream_write_n (c, s, stream);
+ }
+ return;
+}
+
+/*=== STREAM =================================================*/
+/*
+static char buffer[256];
+*/
+/*
+static char *
+binstream(unsigned int x, int n)
+{
+ char *s = buffer;
+ int i;
+
+ for (i = 0; i < n; i++) {
+ if (0!=(x&(1<pbit = 0; return;}
+
+static void
+ro_stream_init (ro_stream_t *s, const unsigned char *buffer)
+{
+ s->x = buffer;
+ s->pbit = 0;
+ return;
+}
+
+static void
+ro_stream_done (ro_stream_t *s)
+{
+ s->x = NULL;
+ s->pbit = 0;
+ return;
+}
+
+
+/* READ AND WRITE */
+static void stream_rewind (stream_t *s) {s->pbit = 0; return;}
+
+static void
+stream_init (stream_t *s, unsigned char *buffer)
+{
+ s->x = buffer;
+ s->pbit = 0;
+ return;
+}
+
+static void
+stream_done (stream_t *s)
+{
+ s->x = NULL;
+ s->pbit = 0;
+ return;
+}
+
+static void
+stream_clear (stream_t *s)
+{ int i;
+ for (i = 0; i < MAXSTREAM; i++) {
+ s->x[i] = 0;
+ }
+ s->pbit = 0;
+ return;
+}
+
+static size_t
+stream_len (stream_t *s)
+{
+ return 1 + s->pbit/8;
+}
+
+static unsigned int
+stream_nextbit (ro_stream_t *s)
+{
+ unsigned long y, byte, bit;
+ y = s->pbit++;
+ byte = y / 8;
+ bit = y & 7;
+ return 1u & (((unsigned)s->x[byte]) >> bit);
+}
+
+static unsigned int
+stream_nextbit_n (ro_stream_t *s, unsigned int width)
+{
+ unsigned i;
+ unsigned x;
+ unsigned r = 0;
+ for (i = 0; i < width; i++) {
+ x = stream_nextbit (s);
+ r |= (x << i);
+ }
+ return r;
+}
+
+/*
+static unsigned int
+stream_next8 (stream_t *s)
+{
+ unsigned a,b,y,byte,bit;
+ y = s->pbit;
+ s->pbit += 8;
+ byte = y / 8;
+ bit = y & 7;
+ a = 0xff & s->x[byte];
+ b = 0xff & s->x[byte+1];
+ return 0xff & ((a >> bit) | (b << (8-bit)));
+}
+*/
+
+#if 1
+static void
+stream_writebit (stream_t *s, unsigned z)
+{
+ unsigned long y,byte,bit;
+ y = s->pbit++;
+
+ byte = y / 8;
+ bit = y & 7;
+
+ /* s->x[byte] &= ~(1u << bit);*/
+ s->x[byte] = (unsigned char) (s->x[byte] | ((z&1u) << bit)); /* cast to silence compiler */
+ return;
+}
+
+#else
+static void
+stream_writebit (stream_t *s, unsigned z)
+{
+ /* This function will write the next bit, 0 or 1 depending on z, and will clear
+ | the following bits (when bit == 0) or some future bytes
+ | Do not use for writing after random access
+ | It is only useful when this function is use for sequential writing on a
+ | empty buffer.
+ */
+ unsigned long y, byte, bit;
+ unsigned char *p;
+ y = s->pbit++;
+
+ byte = y / 8;
+ bit = y & 7;
+
+ p = &(s->x[byte]);
+
+ /* hack to clear the byte only when bit == 0, otherwise, it clears future bytes
+ | This will avoid clearing the whole buffer beforehand or doing
+ | *p &= (unsigned char)(~(1u << bit));
+ */
+ p[bit] = 0;
+
+ *p |= (unsigned char)(z&1u) << bit);
+
+ return;
+}
+#endif
+
+
+/*
+static void
+stream_write8 (stream_t *s, unsigned z)
+{
+ unsigned a,b,c,y,byte,bit;
+ y = s->pbit;
+ s->pbit += 8;
+ byte = y / 8;
+ bit = y & 7;
+ a = 0xff & s->x[byte];
+ b = 0xff & s->x[byte+1];
+ c = a | (b << 8);
+
+ c &= ~(0xff << bit);
+ c |= z << bit;
+
+ s->x[byte] = c & 0xff;
+ s->x[byte+1] = 0xff & (c >> 8);
+
+ return;
+}
+*/
+
+static void
+stream_write_n (unsigned code, unsigned width, stream_t *s)
+{
+ unsigned i;
+ for (i = 0; i < width; i++) {
+ stream_writebit (s, 1u & (code >> i));
+ }
+ return;
+}
+
+/*
+static void
+stream_printnext (stream_t *s, int n)
+{
+ int i; unsigned int x;
+ unsigned long int oldpos = s->pbit;
+
+ printf("\n");
+ for (i = 0; i < n; i++) {
+ if ((i & 7) == 0)
+ printf ("\n");
+ x = stream_next8 (s);
+ printf ("%s ", binstream(x,8) );
+ }
+ printf("\n");
+
+ s->pbit = oldpos;
+ return;
+}
+*/
+
+/*
+static void
+stream_dump (stream_t *s, int ori, int n)
+{
+ int i; unsigned int x;
+ unsigned long int oldpos = s->pbit;
+
+ s->pbit = ori;
+
+ printf("\n");
+ for (i = 0; i < n; i++) {
+ if ((i & 7) == 0)
+ printf ("\n");
+ x = stream_next8 (s);
+ printf ("%s ", binstream(x,8) );
+ }
+ printf("\n");
+
+ s->pbit = oldpos;
+ return;
+}
+*/
+
+/*=== HUFFTREE=================================================*/
+
+#define LEFTCODE 0u
+#define RIGHTCODE 1u
+#define BITLEAF 1
+#define BITNODE 0
+
+static void
+hufftree_reset (void)
+{
+ struct huff h;
+ int i;
+ for (i = 0; i < 2*MAXDIVERSITY; i++) {
+ h.isleaf = FALSE;
+ h.value = 0;
+ h.freq = 0;
+ h.pleft = 0;
+ h.pright = 0;
+ hufftree[i] = h;
+ }
+ huff_end = 0;
+}
+
+static int
+hufftree_from_heap (void)
+{
+ int top, newidx /*, left, right, lesser */ ;
+ struct huff h;
+
+ for (;;)
+ {
+ if (heap_end == 2) { /* at least top element */
+ /* done */
+ break;
+ }
+
+ /* work at the top */
+ top = 1;
+/*
+ left = 2*top;
+ right = left + 1;
+
+ lesser = left;
+ if (right < heap_end && (heap[right].freq < heap[left].freq))
+ lesser = right;
+*/
+ /* new huff node */
+ newidx = huff_end++;
+
+ h.isleaf = FALSE;
+ h.value = -1;
+ h.freq = heap[top].freq; /* will be incremented later when in 'combine' */
+ h.pleft = heap[top].huffidx;
+ h.pright = -1; /* will be attached the next element */
+
+
+ #ifdef TRACE
+ printf ("\n\nBefore Eliminate Top\n");
+ heap_plot();
+ #endif
+
+ /* eliminate top */
+ heap[top] = heap[--heap_end];
+
+ /* next 'lesser' element at 'top' */
+ heap_adjust_down (1, heap_end-1);
+
+ #ifdef TRACE
+ printf ("\n\nEliminate Top\n");
+ heap_plot ();
+ #endif
+
+ /* combine */
+ h.pright = heap[1].huffidx;
+ h.freq += heap[1].freq; /* combine frequencies */
+ hufftree[newidx] = h;
+
+ heap[1].freq = h.freq;
+ heap[1].huffidx = newidx;
+
+ /* adjust the combined elements */
+ heap_adjust_down (1, heap_end-1);
+
+ #ifdef TRACE
+ printf ("\n\nAfter Combine\n");
+ heap_plot ();
+ #endif
+
+ }
+
+ return heap[1].huffidx;
+}
+
+
+static void
+hufftree_to_codes (int start, int n, unsigned code)
+{
+ int x, m;
+ unsigned c;
+ int value;
+
+ #ifdef TRACK
+ if (n == 0)
+ printf ("\nHufftree to codes\n");
+ #endif
+
+ assert (n >= 0);
+
+ x = hufftree[start].pleft;
+ c = code | (LEFTCODE << n);
+ m = n + 1;
+
+ /* LEFT */
+ if (hufftree[x].isleaf) {
+ value = hufftree[x].value;
+ code_table[value] = c;
+ size_table[value] = (unsigned)m;
+
+ #ifdef TRACK
+ printf ("value=%c:%d, code=%d \"%s\", size=%d\n", value,value, c, binstream(c,m), m);
+ #endif
+
+ } else {
+ hufftree_to_codes(x, m, c);
+ }
+
+
+ /* RIGHT */
+ x = hufftree[start].pright;
+ c = code | (RIGHTCODE << n);
+ m = n + 1;
+
+ if (hufftree[x].isleaf) {
+ value = hufftree[x].value;
+ code_table[value] = c;
+ size_table[value] = (unsigned)m;
+
+ #ifdef TRACK
+ printf ("value=%c:%d, code=%d \"%s\", size=%d\n", value,value, c, binstream(c,m), m);
+ #endif
+
+ } else {
+ hufftree_to_codes(x, m, c);
+ }
+
+ return;
+}
+
+
+static int
+hufftree_frombits (ro_stream_t *stream, bool_t *pok)
+{
+ unsigned bit;
+ unsigned value;
+ int thisnode;
+ struct huff h;
+
+ if (!*pok)
+ return 0;
+
+ bit = stream_nextbit(stream);
+ if (bit == BITLEAF) {
+ /* leaf */
+ value = stream_nextbit_n (stream, VALUEBITS);
+ thisnode = huff_end++;
+ h.isleaf = TRUE;
+ h.value = (int)value;
+ h.freq = 0;
+ h.pleft = 0;
+ h.pright = 0;
+
+ if (thisnode >= MAXHUFF) {
+ *pok = FALSE;
+ return 0;
+ }
+
+ hufftree[thisnode] = h;
+
+ #ifdef TRACK
+ printf ("Huff leaf, %d=%c\n", value, value);
+ #endif
+
+ return thisnode;
+
+ } else {
+ /* node */
+ thisnode = huff_end++;
+
+ if (thisnode >= MAXHUFF) {
+ *pok = FALSE;
+ return 0;
+ }
+
+ h.isleaf = FALSE;
+ h.value = -1;
+ h.freq = 0;
+ h.pleft = hufftree_frombits (stream, pok);
+ h.pright = hufftree_frombits (stream, pok);
+ hufftree[thisnode] = h;
+ return thisnode;
+ }
+}
+
+
+static void
+hufftree_tobits (int thisnode, stream_t *stream)
+{
+
+ if (hufftree[thisnode].isleaf) {
+
+ #ifdef TRACK
+ {int c = hufftree[thisnode].value; printf ("[leaf=1][%c:%d=%s]", c, c, binstream(c,8));}
+ #endif
+
+ assert (0 <= hufftree[thisnode].value);
+
+ stream_writebit (stream, BITLEAF);
+ stream_write_n ((unsigned)hufftree[thisnode].value, VALUEBITS, stream);
+
+ } else {
+ stream_writebit (stream, BITNODE);
+
+ #ifdef TRACK
+ printf ("[node=0]");
+ #endif
+
+ hufftree_tobits (hufftree[thisnode].pleft, stream);
+ hufftree_tobits (hufftree[thisnode].pright, stream);
+
+ }
+ return;
+}
+
+
+static unsigned int
+hufftree_readstream (int root, ro_stream_t *s)
+{
+ unsigned bit;
+ int next;
+
+ bit = stream_nextbit(s);
+ if (bit == RIGHTCODE) {
+ /* right */
+ next = hufftree[root].pright;
+ } else {
+ /*ASSERT (bit == LEFTCODE */
+ /* left */
+ next = hufftree[root].pleft;
+ }
+
+ if (hufftree[next].isleaf) {
+ assert (0 <= hufftree[next].value);
+ return (unsigned)hufftree[next].value;
+ } else {
+ return hufftree_readstream (next, s);
+ }
+}
+
+/*==== HEAP ==========================================*/
+
+static void
+heap_init (void)
+{
+ heap_end = 1;
+ return;
+}
+
+static void
+heap_append (struct element e)
+{
+ /*ASSERT (heap_end < MAXHEAP);*/
+ heap[heap_end++] = e;
+ return;
+}
+
+static void
+heap_sift_up (int x)
+{
+ struct element t;
+ int p;
+ int c = x;
+ while (c > 1) {
+ p = c / 2;
+ if (heap[c].freq < heap[p].freq) {
+ t = heap[c]; heap[c] = heap[p]; heap[p] = t;
+ } else {
+ break;
+ }
+ c = p;
+ }
+ return;
+}
+
+
+
+static void
+heap_adjust_down (int top, int last)
+{
+ struct element t;
+ int p;
+ int c;
+ int left, right;
+
+ if (last == top) { /* at least top element */
+ /* done */
+ return;
+ }
+
+ /* starts at the top */
+ p = top;
+
+ while (p <= last)
+ {
+ left = 2*p;
+ right = left + 1;
+
+ if (left > last)
+ break;
+
+ if (right <= last && (heap[right].freq < heap[left].freq))
+ c = right;
+ else
+ c = left;
+
+ if (c > last)
+ break;
+
+ if (heap[c].freq < heap[p].freq) {
+ t = heap[c]; heap[c] = heap[p]; heap[p] = t;
+ } else {
+ break;
+ }
+ p = c;
+ }
+ return;
+}
+
+
+/*
+static void
+heap_plot (void)
+{
+ unsigned int line, limit, j;
+ int n = heap_end;
+ printf("===========================\n");
+ line = 1;
+ j = 1;
+ while (j < n) {
+ limit = 1 << line;
+ while (j < limit && j < n) {
+ printf("%3d:%c ",heap[j].freq, hufftree[heap[j].huffidx].value);
+ j++;
+ }
+ while (j < limit) {
+ printf("%3s ","--");
+ j++;
+ }
+ line++; printf("\n");
+ }
+ printf("===========================\n");
+ return;
+}
+*/
+
+/*
+static void
+freq_report (void)
+{
+ int i;
+ printf ("\nFREQUENCIES\n");
+ for (i = 0; i < MAXDIVERSITY; i++) {
+ if (freq[i] > 0) {
+ printf ("%c: %2d: %d: %d\n", i, i, freq[i], code_table[i]);
+ }
+ }
+ printf ("\n");
+ return;
+}
+*/
+
+static void
+freq_init (const unsigned char *in, size_t max)
+{
+ size_t i;
+
+ /* clean up frequencies */
+ for (i = 0; i < MAXDIVERSITY; i++) {
+ freq [i] = 0;
+ code_table[i] = 0;
+ size_table[i] = 0;
+ }
+
+ /* build frequencies */
+ for (i = 0; i < max; i++) {
+ freq [in[i]]++;
+ }
+
+ #ifdef TRACK
+ freq_report();
+ #endif
+
+ return;
+}
+
+static int
+hufftree_from_freq (void)
+{
+ int i;
+ struct huff h;
+ struct element e;
+ int root;
+
+ hufftree_reset ();
+
+ /* build huff tree elements */
+ huff_end = 0;
+ for (i = 0; i < MAXDIVERSITY; i++) {
+ if (freq[i] > 0) {
+ h.isleaf = TRUE;
+ h.value = i;
+ h.freq = freq[i];
+ h.pleft = 0;
+ h.pright = 0;
+ hufftree[huff_end++] = h;
+ }
+ }
+
+ /* build heap */
+ heap_init();
+ for (i = 0; i < huff_end; i++) {
+ e.freq = hufftree[i].freq;
+ e.huffidx = i;
+ heap_append(e);
+ heap_sift_up(heap_end-1);
+ }
+
+ #ifdef TRACE
+ heap_plot ();
+ #endif
+
+ root = hufftree_from_heap();
+
+ /*hufftree_to_codes (root, 0, 0);*/
+
+ return root;
+}
+
+
+
diff --git a/DroidFish/jni/gtb/compression/huffman/hzip.h b/DroidFish/jni/gtb/compression/huffman/hzip.h
new file mode 100644
index 0000000..4382496
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/huffman/hzip.h
@@ -0,0 +1,51 @@
+/* hzip.h */
+/*
+| Routines designed to be used as a pilot experiment for compression
+| of tablebases. Not really optimized, but they are supposed to work
+| --Miguel A. Ballicora
+*/
+
+/*
+This Software is distributed with the following X11 License,
+sometimes also known as MIT license.
+
+Copyright (c) 2010 Miguel A. Ballicora
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#if !defined(H_HZIP)
+#define H_HZIP
+
+/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
+#include
+
+extern int
+huff_decode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max);
+
+extern int
+huff_encode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max);
+
+/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+#endif
diff --git a/DroidFish/jni/gtb/compression/liblzf/LICENSE b/DroidFish/jni/gtb/compression/liblzf/LICENSE
new file mode 100644
index 0000000..9d8e6ec
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/liblzf/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2000-2007 Marc Alexander Lehmann
+
+Redistribution and use in source and binary forms, with or without modifica-
+tion, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
+CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
+CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
+ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Alternatively, the following files carry an additional notice that
+explicitly allows relicensing under the GPLv2: lzf.c lzf.h lzfP.h lzf_c.c
+lzf_d.c
+
diff --git a/DroidFish/jni/gtb/compression/liblzf/lzf.h b/DroidFish/jni/gtb/compression/liblzf/lzf.h
new file mode 100644
index 0000000..919b6e6
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/liblzf/lzf.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2000-2008 Marc Alexander Lehmann
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
+ * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
+ * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
+ * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License ("GPL") version 2 or any later version,
+ * in which case the provisions of the GPL are applicable instead of
+ * the above. If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the BSD license, indicate your decision
+ * by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL. If you do not delete the
+ * provisions above, a recipient may use your version of this file under
+ * either the BSD or the GPL.
+ */
+
+#ifndef LZF_H
+#define LZF_H
+
+/***********************************************************************
+**
+** lzf -- an extremely fast/free compression/decompression-method
+** http://liblzf.plan9.de/
+**
+** This algorithm is believed to be patent-free.
+**
+***********************************************************************/
+
+#define LZF_VERSION 0x0105 /* 1.5, API version */
+
+/*
+ * Compress in_len bytes stored at the memory block starting at
+ * in_data and write the result to out_data, up to a maximum length
+ * of out_len bytes.
+ *
+ * If the output buffer is not large enough or any error occurs return 0,
+ * otherwise return the number of bytes used, which might be considerably
+ * more than in_len (but less than 104% of the original size), so it
+ * makes sense to always use out_len == in_len - 1), to ensure _some_
+ * compression, and store the data uncompressed otherwise (with a flag, of
+ * course.
+ *
+ * lzf_compress might use different algorithms on different systems and
+ * even different runs, thus might result in different compressed strings
+ * depending on the phase of the moon or similar factors. However, all
+ * these strings are architecture-independent and will result in the
+ * original data when decompressed using lzf_decompress.
+ *
+ * The buffers must not be overlapping.
+ *
+ * If the option LZF_STATE_ARG is enabled, an extra argument must be
+ * supplied which is not reflected in this header file. Refer to lzfP.h
+ * and lzf_c.c.
+ *
+ */
+unsigned int
+lzf_compress (const void *const in_data, unsigned int in_len,
+ void *out_data, unsigned int out_len);
+
+/*
+ * Decompress data compressed with some version of the lzf_compress
+ * function and stored at location in_data and length in_len. The result
+ * will be stored at out_data up to a maximum of out_len characters.
+ *
+ * If the output buffer is not large enough to hold the decompressed
+ * data, a 0 is returned and errno is set to E2BIG. Otherwise the number
+ * of decompressed bytes (i.e. the original length of the data) is
+ * returned.
+ *
+ * If an error in the compressed data is detected, a zero is returned and
+ * errno is set to EINVAL.
+ *
+ * This function is very fast, about as fast as a copying loop.
+ */
+unsigned int
+lzf_decompress (const void *const in_data, unsigned int in_len,
+ void *out_data, unsigned int out_len);
+
+#endif
+
diff --git a/DroidFish/jni/gtb/compression/liblzf/lzfP.h b/DroidFish/jni/gtb/compression/liblzf/lzfP.h
new file mode 100644
index 0000000..d533f18
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/liblzf/lzfP.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2000-2007 Marc Alexander Lehmann
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
+ * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
+ * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
+ * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License ("GPL") version 2 or any later version,
+ * in which case the provisions of the GPL are applicable instead of
+ * the above. If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the BSD license, indicate your decision
+ * by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL. If you do not delete the
+ * provisions above, a recipient may use your version of this file under
+ * either the BSD or the GPL.
+ */
+
+#ifndef LZFP_h
+#define LZFP_h
+
+#define STANDALONE 1 /* at the moment, this is ok. */
+
+#ifndef STANDALONE
+# include "lzf.h"
+#endif
+
+/*
+ * Size of hashtable is (1 << HLOG) * sizeof (char *)
+ * decompression is independent of the hash table size
+ * the difference between 15 and 14 is very small
+ * for small blocks (and 14 is usually a bit faster).
+ * For a low-memory/faster configuration, use HLOG == 13;
+ * For best compression, use 15 or 16 (or more, up to 23).
+ */
+#ifndef HLOG
+# define HLOG 16
+#endif
+
+/*
+ * Sacrifice very little compression quality in favour of compression speed.
+ * This gives almost the same compression as the default code, and is
+ * (very roughly) 15% faster. This is the preferred mode of operation.
+ */
+#ifndef VERY_FAST
+# define VERY_FAST 1
+#endif
+
+/*
+ * Sacrifice some more compression quality in favour of compression speed.
+ * (roughly 1-2% worse compression for large blocks and
+ * 9-10% for small, redundant, blocks and >>20% better speed in both cases)
+ * In short: when in need for speed, enable this for binary data,
+ * possibly disable this for text data.
+ */
+#ifndef ULTRA_FAST
+# define ULTRA_FAST 0
+#endif
+
+/*
+ * Unconditionally aligning does not cost very much, so do it if unsure
+ */
+#ifndef STRICT_ALIGN
+# define STRICT_ALIGN !(defined(__i386) || defined (__amd64))
+#endif
+
+/*
+ * You may choose to pre-set the hash table (might be faster on some
+ * modern cpus and large (>>64k) blocks, and also makes compression
+ * deterministic/repeatable when the configuration otherwise is the same).
+ */
+#ifndef INIT_HTAB
+# define INIT_HTAB 0
+#endif
+
+/*
+ * Avoid assigning values to errno variable? for some embedding purposes
+ * (linux kernel for example), this is neccessary. NOTE: this breaks
+ * the documentation in lzf.h.
+ */
+#ifndef AVOID_ERRNO
+# define AVOID_ERRNO 0
+#endif
+
+/*
+ * Wether to pass the LZF_STATE variable as argument, or allocate it
+ * on the stack. For small-stack environments, define this to 1.
+ * NOTE: this breaks the prototype in lzf.h.
+ */
+#ifndef LZF_STATE_ARG
+# define LZF_STATE_ARG 0
+#endif
+
+/*
+ * Wether to add extra checks for input validity in lzf_decompress
+ * and return EINVAL if the input stream has been corrupted. This
+ * only shields against overflowing the input buffer and will not
+ * detect most corrupted streams.
+ * This check is not normally noticable on modern hardware
+ * (<1% slowdown), but might slow down older cpus considerably.
+ */
+#ifndef CHECK_INPUT
+# define CHECK_INPUT 1
+#endif
+
+/*****************************************************************************/
+/* nothing should be changed below */
+
+typedef unsigned char u8;
+
+typedef const u8 *LZF_STATE[1 << (HLOG)];
+
+#if !STRICT_ALIGN
+/* for unaligned accesses we need a 16 bit datatype. */
+# include
+# if USHRT_MAX == 65535
+ typedef unsigned short u16;
+# elif UINT_MAX == 65535
+ typedef unsigned int u16;
+# else
+# undef STRICT_ALIGN
+# define STRICT_ALIGN 1
+# endif
+#endif
+
+#if ULTRA_FAST
+# if defined(VERY_FAST)
+# undef VERY_FAST
+# endif
+#endif
+
+#if INIT_HTAB
+# ifdef __cplusplus
+# include
+# else
+# include
+# endif
+#endif
+
+#endif
+
diff --git a/DroidFish/jni/gtb/compression/liblzf/lzf_c.c b/DroidFish/jni/gtb/compression/liblzf/lzf_c.c
new file mode 100644
index 0000000..a6d98e1
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/liblzf/lzf_c.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2000-2008 Marc Alexander Lehmann
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
+ * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
+ * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
+ * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License ("GPL") version 2 or any later version,
+ * in which case the provisions of the GPL are applicable instead of
+ * the above. If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the BSD license, indicate your decision
+ * by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL. If you do not delete the
+ * provisions above, a recipient may use your version of this file under
+ * either the BSD or the GPL.
+ */
+
+/*MAB: added this include to silence compiler */
+#include "lzf.h"
+
+#include "lzfP.h"
+
+#define HSIZE (1 << (HLOG))
+
+/*
+ * don't play with this unless you benchmark!
+ * decompression is not dependent on the hash function
+ * the hashing function might seem strange, just believe me
+ * it works ;)
+ */
+#ifndef FRST
+# define FRST(p) (((p[0]) << 8) | p[1])
+# define NEXT(v,p) (((v) << 8) | p[2])
+# if ULTRA_FAST
+# define IDX(h) ((( h >> (3*8 - HLOG)) - h ) & (HSIZE - 1))
+# elif VERY_FAST
+# define IDX(h) ((( h >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
+# else
+# define IDX(h) ((((h ^ (h << 5)) >> (3*8 - HLOG)) - h*5) & (HSIZE - 1))
+# endif
+#endif
+/*
+ * IDX works because it is very similar to a multiplicative hash, e.g.
+ * ((h * 57321 >> (3*8 - HLOG)) & (HSIZE - 1))
+ * the latter is also quite fast on newer CPUs, and compresses similarly.
+ *
+ * the next one is also quite good, albeit slow ;)
+ * (int)(cos(h & 0xffffff) * 1e6)
+ */
+
+#if 0
+/* original lzv-like hash function, much worse and thus slower */
+# define FRST(p) (p[0] << 5) ^ p[1]
+# define NEXT(v,p) ((v) << 5) ^ p[2]
+# define IDX(h) ((h) & (HSIZE - 1))
+#endif
+
+#define MAX_LIT (1 << 5)
+#define MAX_OFF (1 << 13)
+#define MAX_REF ((1 << 8) + (1 << 3))
+
+#if __GNUC__ >= 3
+# define expect(expr,value) __builtin_expect ((expr),(value))
+# define inline inline
+#else
+# define expect(expr,value) (expr)
+# define inline static
+#endif
+
+#define expect_false(expr) expect ((expr) != 0, 0)
+#define expect_true(expr) expect ((expr) != 0, 1)
+
+/*
+ * compressed format
+ *
+ * 000LLLLL ; literal
+ * LLLooooo oooooooo ; backref L
+ * 111ooooo LLLLLLLL oooooooo ; backref L+7
+ *
+ */
+
+unsigned int
+lzf_compress (const void *const in_data, unsigned int in_len,
+ void *out_data, unsigned int out_len
+#if LZF_STATE_ARG
+ , LZF_STATE htab
+#endif
+ )
+{
+#if !LZF_STATE_ARG
+ LZF_STATE htab;
+#endif
+ const u8 **hslot;
+ const u8 *ip = (const u8 *)in_data;
+ u8 *op = (u8 *)out_data;
+ const u8 *in_end = ip + in_len;
+ u8 *out_end = op + out_len;
+ const u8 *ref;
+
+ /* off requires a type wide enough to hold a general pointer difference.
+ * ISO C doesn't have that (size_t might not be enough and ptrdiff_t only
+ * works for differences within a single object). We also assume that no
+ * no bit pattern traps. Since the only platform that is both non-POSIX
+ * and fails to support both assumptions is windows 64 bit, we make a
+ * special workaround for it.
+ */
+#if defined (WIN32) && defined (_M_X64)
+ /*MAB fix bug, it is __int64 rather than _int64 */
+ unsigned __int64 off; /* workaround for missing POSIX compliance */
+#else
+ unsigned long off;
+#endif
+ unsigned int hval;
+ int lit;
+
+ if (!in_len || !out_len)
+ return 0;
+
+#if INIT_HTAB
+ memset (htab, 0, sizeof (htab));
+# if 0
+ for (hslot = htab; hslot < htab + HSIZE; hslot++)
+ *hslot++ = ip;
+# endif
+#endif
+
+ lit = 0; op++; /* start run */
+
+ hval = (unsigned)(FRST (ip)); /*MAB silence warning with cast*/
+ while (ip < in_end - 2)
+ {
+ hval = NEXT (hval, ip);
+ hslot = htab + IDX (hval);
+ ref = *hslot; *hslot = ip;
+
+ if (
+/*MAB: Remove 1, it was a constant, to silence compiler */
+#if INIT_HTAB
+ ref < ip /* the next test will actually take care of this, but this is faster */
+ &&
+#endif
+ (off = (unsigned long)(ip - ref - 1)) < MAX_OFF /*MAB silence warning with cast */
+ && ip + 4 < in_end
+ && ref > (u8 *)in_data
+#if STRICT_ALIGN
+ && ref[0] == ip[0]
+ && ref[1] == ip[1]
+ && ref[2] == ip[2]
+#else
+ && *(u16 *)ref == *(u16 *)ip
+ && ref[2] == ip[2]
+#endif
+ )
+ {
+ /* match found at *ref++ */
+ unsigned int len = 2;
+ unsigned int maxlen = (unsigned)(in_end - ip - (int)len); /* MAB silence warning with casting */
+ maxlen = maxlen > MAX_REF ? MAX_REF : maxlen;
+
+ if (expect_false (op + 3 + 1 >= out_end)) /* first a faster conservative test */
+ if (op - !lit + 3 + 1 >= out_end) /* second the exact but rare test */
+ return 0;
+
+ op [- lit - 1] = (u8) (lit - 1); /* stop run */ /*MAB: Casting to u8 to silence compiler */
+ op -= !lit; /* undo run if length is zero */
+
+ for (;;)
+ {
+ if (expect_true (maxlen > 16))
+ {
+ len++; if (ref [len] != ip [len]) break;
+ len++; if (ref [len] != ip [len]) break;
+ len++; if (ref [len] != ip [len]) break;
+ len++; if (ref [len] != ip [len]) break;
+
+ len++; if (ref [len] != ip [len]) break;
+ len++; if (ref [len] != ip [len]) break;
+ len++; if (ref [len] != ip [len]) break;
+ len++; if (ref [len] != ip [len]) break;
+
+ len++; if (ref [len] != ip [len]) break;
+ len++; if (ref [len] != ip [len]) break;
+ len++; if (ref [len] != ip [len]) break;
+ len++; if (ref [len] != ip [len]) break;
+
+ len++; if (ref [len] != ip [len]) break;
+ len++; if (ref [len] != ip [len]) break;
+ len++; if (ref [len] != ip [len]) break;
+ len++; if (ref [len] != ip [len]) break;
+ }
+
+ do
+ len++;
+ while (len < maxlen && ref[len] == ip[len]);
+
+ break;
+ }
+
+ len -= 2; /* len is now #octets - 1 */
+ ip++;
+
+ if (len < 7)
+ {
+ *op++ = (u8) ((off >> 8) + (len << 5)); /*MAB: Casting to u8 to silence compiler */
+ }
+ else
+ {
+ *op++ = (u8) ((off >> 8) + ( 7 << 5)); /*MAB: Casting to u8 to silence compiler */
+ *op++ = (u8) (len - 7); /*MAB: Casting to u8 to silence compiler */
+ }
+
+ *op++ = (u8) off; /*MAB: Casting to u8 to silence compiler */
+ lit = 0; op++; /* start run */
+
+ ip += len + 1;
+
+ if (expect_false (ip >= in_end - 2))
+ break;
+
+#if ULTRA_FAST || VERY_FAST
+ --ip;
+# if VERY_FAST && !ULTRA_FAST
+ --ip;
+# endif
+ hval = (unsigned)(FRST (ip)); /*MAB silence warning with cast*/
+
+ hval = NEXT (hval, ip);
+ htab[IDX (hval)] = ip;
+ ip++;
+
+# if VERY_FAST && !ULTRA_FAST
+ hval = NEXT (hval, ip);
+ htab[IDX (hval)] = ip;
+ ip++;
+# endif
+#else
+ ip -= len + 1;
+
+ do
+ {
+ hval = NEXT (hval, ip);
+ htab[IDX (hval)] = ip;
+ ip++;
+ }
+ while (len--);
+#endif
+ }
+ else
+ {
+ /* one more literal byte we must copy */
+ if (expect_false (op >= out_end))
+ return 0;
+
+ lit++; *op++ = *ip++;
+
+ if (expect_false (lit == MAX_LIT))
+ {
+ op [- lit - 1] = (u8) (lit - 1); /* stop run */ /*MAB: Casting to u8 to silence compiler */
+ lit = 0; op++; /* start run */
+ }
+ }
+ }
+
+ if (op + 3 > out_end) /* at most 3 bytes can be missing here */
+ return 0;
+
+ while (ip < in_end)
+ {
+ lit++; *op++ = *ip++;
+
+ if (expect_false (lit == MAX_LIT))
+ {
+ op [- lit - 1] = (u8) (lit - 1); /* stop run */ /*MAB: Casting to u8 to silence compiler */
+ lit = 0; op++; /* start run */
+ }
+ }
+
+ op [- lit - 1] = (u8) (lit - 1); /* end run */ /*MAB: Casting to u8 to silence compiler */
+ op -= !lit; /* undo run if length is zero */
+
+ return (unsigned)(op - (u8 *)out_data); /*MAB: Casting to unsigned to silence compiler */
+}
+
diff --git a/DroidFish/jni/gtb/compression/liblzf/lzf_d.c b/DroidFish/jni/gtb/compression/liblzf/lzf_d.c
new file mode 100644
index 0000000..3bb91ab
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/liblzf/lzf_d.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2000-2007 Marc Alexander Lehmann
+ *
+ * Redistribution and use in source and binary forms, with or without modifica-
+ * tion, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
+ * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
+ * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
+ * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * the GNU General Public License ("GPL") version 2 or any later version,
+ * in which case the provisions of the GPL are applicable instead of
+ * the above. If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the BSD license, indicate your decision
+ * by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL. If you do not delete the
+ * provisions above, a recipient may use your version of this file under
+ * either the BSD or the GPL.
+ */
+
+/*MAB: added this include to silence compiler */
+#include "lzf.h"
+
+#include "lzfP.h"
+
+#if AVOID_ERRNO
+# define SET_ERRNO(n)
+#else
+# include
+# define SET_ERRNO(n) errno = (n)
+#endif
+
+/*MAB: __i386 and __amd64 surrounded by defined() to silence intel compiler */
+/*MAB: added __STRICT_ANSI__ flag so it could be checked with -ansi -pedantic */
+#if (defined(__i386) || defined(__amd64)) && __GNUC__ >= 3 && !defined(__STRICT_ANSI__)
+# define lzf_movsb(dst, src, len) \
+ asm ("rep movsb" \
+ : "=D" (dst), "=S" (src), "=c" (len) \
+ : "0" (dst), "1" (src), "2" (len));
+#endif
+
+unsigned int
+lzf_decompress (const void *const in_data, unsigned int in_len,
+ void *out_data, unsigned int out_len)
+{
+ u8 const *ip = (const u8 *)in_data;
+ u8 *op = (u8 *)out_data;
+ u8 const *const in_end = ip + in_len;
+ u8 *const out_end = op + out_len;
+
+ do
+ {
+ unsigned int ctrl = *ip++;
+
+ if (ctrl < (1 << 5)) /* literal run */
+ {
+ ctrl++;
+
+ if (op + ctrl > out_end)
+ {
+ SET_ERRNO (E2BIG);
+ return 0;
+ }
+
+#if CHECK_INPUT
+ if (ip + ctrl > in_end)
+ {
+ SET_ERRNO (EINVAL);
+ return 0;
+ }
+#endif
+
+#ifdef lzf_movsb
+ lzf_movsb (op, ip, ctrl);
+#else
+ do
+ *op++ = *ip++;
+ while (--ctrl);
+#endif
+ }
+ else /* back reference */
+ {
+ unsigned int len = ctrl >> 5;
+
+ u8 *ref = op - ((ctrl & 0x1f) << 8) - 1;
+
+#if CHECK_INPUT
+ if (ip >= in_end)
+ {
+ SET_ERRNO (EINVAL);
+ return 0;
+ }
+#endif
+ if (len == 7)
+ {
+ len += *ip++;
+#if CHECK_INPUT
+ if (ip >= in_end)
+ {
+ SET_ERRNO (EINVAL);
+ return 0;
+ }
+#endif
+ }
+
+ ref -= *ip++;
+
+ if (op + len + 2 > out_end)
+ {
+ SET_ERRNO (E2BIG);
+ return 0;
+ }
+
+ if (ref < (u8 *)out_data)
+ {
+ SET_ERRNO (EINVAL);
+ return 0;
+ }
+
+#ifdef lzf_movsb
+ len += 2;
+ lzf_movsb (op, ref, len);
+#else
+ *op++ = *ref++;
+ *op++ = *ref++;
+
+ do
+ *op++ = *ref++;
+ while (--len);
+#endif
+ }
+ }
+ while (ip < in_end);
+
+#if 0
+ return op - (u8 *)out_data;
+#else
+ return (unsigned int)(op - (u8 *)out_data); /*MAB: cast to silence warning */
+#endif
+}
+
diff --git a/DroidFish/jni/gtb/compression/lzma/Alloc.c b/DroidFish/jni/gtb/compression/lzma/Alloc.c
new file mode 100755
index 0000000..eb5196b
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/Alloc.c
@@ -0,0 +1,127 @@
+/* Alloc.c -- Memory allocation functions
+2008-09-24
+Igor Pavlov
+Public domain */
+
+#ifdef _WIN32
+#include
+#endif
+#include
+
+#include "Alloc.h"
+
+/* #define _SZ_ALLOC_DEBUG */
+
+/* use _SZ_ALLOC_DEBUG to debug alloc/free operations */
+#ifdef _SZ_ALLOC_DEBUG
+#include
+int g_allocCount = 0;
+int g_allocCountMid = 0;
+int g_allocCountBig = 0;
+#endif
+
+void *MyAlloc(size_t size)
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ {
+ void *p = malloc(size);
+ fprintf(stderr, "\nAlloc %10d bytes, count = %10d, addr = %8X", size, g_allocCount++, (unsigned)p);
+ return p;
+ }
+ #else
+ return malloc(size);
+ #endif
+}
+
+void MyFree(void *address)
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree; count = %10d, addr = %8X", --g_allocCount, (unsigned)address);
+ #endif
+ free(address);
+}
+
+#ifdef _WIN32
+
+void *MidAlloc(size_t size)
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc_Mid %10d bytes; count = %10d", size, g_allocCountMid++);
+ #endif
+ return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void MidFree(void *address)
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree_Mid; count = %10d", --g_allocCountMid);
+ #endif
+ if (address == 0)
+ return;
+ VirtualFree(address, 0, MEM_RELEASE);
+}
+
+#ifndef MEM_LARGE_PAGES
+#undef _7ZIP_LARGE_PAGES
+#endif
+
+#ifdef _7ZIP_LARGE_PAGES
+SIZE_T g_LargePageSize = 0;
+typedef SIZE_T (WINAPI *GetLargePageMinimumP)();
+#endif
+
+void SetLargePageSize(void)
+{
+ #ifdef _7ZIP_LARGE_PAGES
+ SIZE_T size = 0;
+ GetLargePageMinimumP largePageMinimum = (GetLargePageMinimumP)
+ GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetLargePageMinimum");
+ if (largePageMinimum == 0)
+ return;
+ size = largePageMinimum();
+ if (size == 0 || (size & (size - 1)) != 0)
+ return;
+ g_LargePageSize = size;
+ #endif
+}
+
+
+void *BigAlloc(size_t size)
+{
+ if (size == 0)
+ return 0;
+ #ifdef _SZ_ALLOC_DEBUG
+ fprintf(stderr, "\nAlloc_Big %10d bytes; count = %10d", size, g_allocCountBig++);
+ #endif
+
+ #ifdef _7ZIP_LARGE_PAGES
+ if (g_LargePageSize != 0 && g_LargePageSize <= (1 << 30) && size >= (1 << 18))
+ {
+ void *res = VirtualAlloc(0, (size + g_LargePageSize - 1) & (~(g_LargePageSize - 1)),
+ MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
+ if (res != 0)
+ return res;
+ }
+ #endif
+ return VirtualAlloc(0, size, MEM_COMMIT, PAGE_READWRITE);
+}
+
+void BigFree(void *address)
+{
+ #ifdef _SZ_ALLOC_DEBUG
+ if (address != 0)
+ fprintf(stderr, "\nFree_Big; count = %10d", --g_allocCountBig);
+ #endif
+
+ if (address == 0)
+ return;
+ VirtualFree(address, 0, MEM_RELEASE);
+}
+
+#endif
diff --git a/DroidFish/jni/gtb/compression/lzma/Alloc.h b/DroidFish/jni/gtb/compression/lzma/Alloc.h
new file mode 100755
index 0000000..9d81f1f
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/Alloc.h
@@ -0,0 +1,32 @@
+/* Alloc.h -- Memory allocation functions
+2008-03-13
+Igor Pavlov
+Public domain */
+
+#ifndef __COMMON_ALLOC_H
+#define __COMMON_ALLOC_H
+
+#include
+
+void *MyAlloc(size_t size);
+void MyFree(void *address);
+
+#ifdef _WIN32
+
+void SetLargePageSize(void);
+
+void *MidAlloc(size_t size);
+void MidFree(void *address);
+void *BigAlloc(size_t size);
+void BigFree(void *address);
+
+#else
+
+#define MidAlloc(size) MyAlloc(size)
+#define MidFree(address) MyFree(address)
+#define BigAlloc(size) MyAlloc(size)
+#define BigFree(address) MyFree(address)
+
+#endif
+
+#endif
diff --git a/DroidFish/jni/gtb/compression/lzma/Bra.h b/DroidFish/jni/gtb/compression/lzma/Bra.h
new file mode 100755
index 0000000..b9018eb
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/Bra.h
@@ -0,0 +1,60 @@
+/* Bra.h -- Branch converters for executables
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __BRA_H
+#define __BRA_H
+
+#include "Types.h"
+
+/*
+These functions convert relative addresses to absolute addresses
+in CALL instructions to increase the compression ratio.
+
+ In:
+ data - data buffer
+ size - size of data
+ ip - current virtual Instruction Pinter (IP) value
+ state - state variable for x86 converter
+ encoding - 0 (for decoding), 1 (for encoding)
+
+ Out:
+ state - state variable for x86 converter
+
+ Returns:
+ The number of processed bytes. If you call these functions with multiple calls,
+ you must start next call with first byte after block of processed bytes.
+
+ Type Endian Alignment LookAhead
+
+ x86 little 1 4
+ ARMT little 2 2
+ ARM little 4 0
+ PPC big 4 0
+ SPARC big 4 0
+ IA64 little 16 0
+
+ size must be >= Alignment + LookAhead, if it's not last block.
+ If (size < Alignment + LookAhead), converter returns 0.
+
+ Example:
+
+ UInt32 ip = 0;
+ for ()
+ {
+ ; size must be >= Alignment + LookAhead, if it's not last block
+ SizeT processed = Convert(data, size, ip, 1);
+ data += processed;
+ size -= processed;
+ ip += processed;
+ }
+*/
+
+#define x86_Convert_Init(state) { state = 0; }
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
+SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
+
+#endif
diff --git a/DroidFish/jni/gtb/compression/lzma/Bra86.c b/DroidFish/jni/gtb/compression/lzma/Bra86.c
new file mode 100755
index 0000000..5bec666
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/Bra86.c
@@ -0,0 +1,85 @@
+/* Bra86.c -- Converter for x86 code (BCJ)
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include "Bra.h"
+
+#define Test86MSByte(b) ((b) == 0 || (b) == 0xFF)
+
+const Byte kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0};
+const Byte kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3};
+
+SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
+{
+ SizeT bufferPos = 0, prevPosT;
+ UInt32 prevMask = *state & 0x7;
+ if (size < 5)
+ return 0;
+ ip += 5;
+ prevPosT = (SizeT)0 - 1;
+
+ for (;;)
+ {
+ Byte *p = data + bufferPos;
+ Byte *limit = data + size - 4;
+ for (; p < limit; p++)
+ if ((*p & 0xFE) == 0xE8)
+ break;
+ bufferPos = (SizeT)(p - data);
+ if (p >= limit)
+ break;
+ prevPosT = bufferPos - prevPosT;
+ if (prevPosT > 3)
+ prevMask = 0;
+ else
+ {
+ prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7;
+ if (prevMask != 0)
+ {
+ Byte b = p[4 - kMaskToBitNumber[prevMask]];
+ if (!kMaskToAllowedStatus[prevMask] || Test86MSByte(b))
+ {
+ prevPosT = bufferPos;
+ prevMask = ((prevMask << 1) & 0x7) | 1;
+ bufferPos++;
+ continue;
+ }
+ }
+ }
+ prevPosT = bufferPos;
+
+ if (Test86MSByte(p[4]))
+ {
+ UInt32 src = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
+ UInt32 dest;
+ for (;;)
+ {
+ Byte b;
+ int index;
+ if (encoding)
+ dest = (ip + (UInt32)bufferPos) + src;
+ else
+ dest = src - (ip + (UInt32)bufferPos);
+ if (prevMask == 0)
+ break;
+ index = kMaskToBitNumber[prevMask] * 8;
+ b = (Byte)(dest >> (24 - index));
+ if (!Test86MSByte(b))
+ break;
+ src = dest ^ (((UInt32)1 << (32 - index)) - (UInt32)1);
+ }
+ p[4] = (Byte)(~(((dest >> 24) & 1) - 1));
+ p[3] = (Byte)(dest >> 16);
+ p[2] = (Byte)(dest >> 8);
+ p[1] = (Byte)dest;
+ bufferPos += 5;
+ }
+ else
+ {
+ prevMask = ((prevMask << 1) & 0x7) | 1;
+ bufferPos++;
+ }
+ }
+ prevPosT = bufferPos - prevPosT;
+ *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7));
+ return bufferPos;
+}
diff --git a/DroidFish/jni/gtb/compression/lzma/LzFind.c b/DroidFish/jni/gtb/compression/lzma/LzFind.c
new file mode 100755
index 0000000..51ae22e
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/LzFind.c
@@ -0,0 +1,758 @@
+/* LzFind.c -- Match finder for LZ algorithms
+2008-10-04 : Igor Pavlov : Public domain */
+
+#include
+
+#include "LzFind.h"
+#include "LzHash.h"
+
+#define kEmptyHashValue 0
+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
+#define kNormalizeStepMin (1u << 10) /* it must be power of 2 */ /*MAB 1u */
+#define kNormalizeMask (~(kNormalizeStepMin - 1))
+#define kMaxHistorySize ((UInt32)3 << 30)
+
+#define kStartMaxLen 3
+
+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
+{
+ if (!p->directInput)
+ {
+ alloc->Free(alloc, p->bufferBase);
+ p->bufferBase = 0;
+ }
+}
+
+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
+
+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
+{
+ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
+ if (p->directInput)
+ {
+ p->blockSize = blockSize;
+ return 1;
+ }
+ if (p->bufferBase == 0 || p->blockSize != blockSize)
+ {
+ LzInWindow_Free(p, alloc);
+ p->blockSize = blockSize;
+ p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
+ }
+ return (p->bufferBase != 0);
+}
+
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
+
+/*MAB: static added, index replaced by idx to avoid shadowing a global variable */
+static
+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 idx) { return p->buffer[idx]; }
+
+/*MAB: static added */
+static
+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
+
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
+{
+ p->posLimit -= subValue;
+ p->pos -= subValue;
+ p->streamPos -= subValue;
+}
+
+static void MatchFinder_ReadBlock(CMatchFinder *p)
+{
+ if (p->streamEndWasReached || p->result != SZ_OK)
+ return;
+ for (;;)
+ {
+ Byte *dest = p->buffer + (p->streamPos - p->pos);
+ size_t size = (size_t)(p->bufferBase + p->blockSize - dest);
+ if (size == 0)
+ return;
+ p->result = p->stream->Read(p->stream, dest, &size);
+ if (p->result != SZ_OK)
+ return;
+ if (size == 0)
+ {
+ p->streamEndWasReached = 1;
+ return;
+ }
+ p->streamPos += (UInt32)size;
+ if (p->streamPos - p->pos > p->keepSizeAfter)
+ return;
+ }
+}
+
+void MatchFinder_MoveBlock(CMatchFinder *p)
+{
+ memmove(p->bufferBase,
+ p->buffer - p->keepSizeBefore,
+ (size_t)(p->streamPos - p->pos + p->keepSizeBefore));
+ p->buffer = p->bufferBase + p->keepSizeBefore;
+}
+
+int MatchFinder_NeedMove(CMatchFinder *p)
+{
+ /* if (p->streamEndWasReached) return 0; */
+ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
+}
+
+void MatchFinder_ReadIfRequired(CMatchFinder *p)
+{
+ if (p->streamEndWasReached)
+ return;
+ if (p->keepSizeAfter >= p->streamPos - p->pos)
+ MatchFinder_ReadBlock(p);
+}
+
+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
+{
+ if (MatchFinder_NeedMove(p))
+ MatchFinder_MoveBlock(p);
+ MatchFinder_ReadBlock(p);
+}
+
+static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
+{
+ p->cutValue = 32;
+ p->btMode = 1;
+ p->numHashBytes = 4;
+ /* p->skipModeBits = 0; */
+ p->directInput = 0;
+ p->bigHash = 0;
+}
+
+#define kCrcPoly 0xEDB88320
+
+void MatchFinder_Construct(CMatchFinder *p)
+{
+ UInt32 i;
+ p->bufferBase = 0;
+ p->directInput = 0;
+ p->hash = 0;
+ MatchFinder_SetDefaultSettings(p);
+
+ for (i = 0; i < 256; i++)
+ {
+ UInt32 r = i;
+ int j;
+ for (j = 0; j < 8; j++)
+ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
+ p->crc[i] = r;
+ }
+}
+
+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->hash);
+ p->hash = 0;
+}
+
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
+{
+ MatchFinder_FreeThisClassMemory(p, alloc);
+ LzInWindow_Free(p, alloc);
+}
+
+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
+{
+ size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
+ if (sizeInBytes / sizeof(CLzRef) != num)
+ return 0;
+ return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
+}
+
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
+ ISzAlloc *alloc)
+{
+ UInt32 sizeReserv;
+ if (historySize > kMaxHistorySize)
+ {
+ MatchFinder_Free(p, alloc);
+ return 0;
+ }
+ sizeReserv = historySize >> 1;
+ if (historySize > ((UInt32)2 << 30))
+ sizeReserv = historySize >> 2;
+ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
+
+ p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
+ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
+ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
+ if (LzInWindow_Create(p, sizeReserv, alloc))
+ {
+ UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1;
+ UInt32 hs;
+ p->matchMaxLen = matchMaxLen;
+ {
+ p->fixedHashSize = 0;
+ if (p->numHashBytes == 2)
+ hs = (1 << 16) - 1;
+ else
+ {
+ hs = historySize - 1;
+ hs |= (hs >> 1);
+ hs |= (hs >> 2);
+ hs |= (hs >> 4);
+ hs |= (hs >> 8);
+ hs >>= 1;
+ /* hs >>= p->skipModeBits; */
+ hs |= 0xFFFF; /* don't change it! It's required for Deflate */
+ if (hs > (1 << 24))
+ {
+ if (p->numHashBytes == 3)
+ hs = (1 << 24) - 1;
+ else
+ hs >>= 1;
+ }
+ }
+ p->hashMask = hs;
+ hs++;
+ if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
+ if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
+ if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
+ hs += p->fixedHashSize;
+ }
+
+ {
+ UInt32 prevSize = p->hashSizeSum + p->numSons;
+ UInt32 newSize;
+ p->historySize = historySize;
+ p->hashSizeSum = hs;
+ p->cyclicBufferSize = newCyclicBufferSize;
+ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
+ newSize = p->hashSizeSum + p->numSons;
+ if (p->hash != 0 && prevSize == newSize)
+ return 1;
+ MatchFinder_FreeThisClassMemory(p, alloc);
+ p->hash = AllocRefs(newSize, alloc);
+ if (p->hash != 0)
+ {
+ p->son = p->hash + p->hashSizeSum;
+ return 1;
+ }
+ }
+ }
+ MatchFinder_Free(p, alloc);
+ return 0;
+}
+
+static void MatchFinder_SetLimits(CMatchFinder *p)
+{
+ UInt32 limit = kMaxValForNormalize - p->pos;
+ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
+ if (limit2 < limit)
+ limit = limit2;
+ limit2 = p->streamPos - p->pos;
+ if (limit2 <= p->keepSizeAfter)
+ {
+ if (limit2 > 0)
+ limit2 = 1;
+ }
+ else
+ limit2 -= p->keepSizeAfter;
+ if (limit2 < limit)
+ limit = limit2;
+ {
+ UInt32 lenLimit = p->streamPos - p->pos;
+ if (lenLimit > p->matchMaxLen)
+ lenLimit = p->matchMaxLen;
+ p->lenLimit = lenLimit;
+ }
+ p->posLimit = p->pos + limit;
+}
+
+void MatchFinder_Init(CMatchFinder *p)
+{
+ UInt32 i;
+ for (i = 0; i < p->hashSizeSum; i++)
+ p->hash[i] = kEmptyHashValue;
+ p->cyclicBufferPos = 0;
+ p->buffer = p->bufferBase;
+ p->pos = p->streamPos = p->cyclicBufferSize;
+ p->result = SZ_OK;
+ p->streamEndWasReached = 0;
+ MatchFinder_ReadBlock(p);
+ MatchFinder_SetLimits(p);
+}
+
+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
+{
+ return (p->pos - p->historySize - 1) & kNormalizeMask;
+}
+
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
+{
+ UInt32 i;
+ for (i = 0; i < numItems; i++)
+ {
+ UInt32 value = items[i];
+ if (value <= subValue)
+ value = kEmptyHashValue;
+ else
+ value -= subValue;
+ items[i] = value;
+ }
+}
+
+static void MatchFinder_Normalize(CMatchFinder *p)
+{
+ UInt32 subValue = MatchFinder_GetSubValue(p);
+ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
+ MatchFinder_ReduceOffsets(p, subValue);
+}
+
+static void MatchFinder_CheckLimits(CMatchFinder *p)
+{
+ if (p->pos == kMaxValForNormalize)
+ MatchFinder_Normalize(p);
+
+ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
+ MatchFinder_CheckAndMoveAndRead(p);
+ if (p->cyclicBufferPos == p->cyclicBufferSize)
+ p->cyclicBufferPos = 0;
+ MatchFinder_SetLimits(p);
+}
+
+static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
+ UInt32 *distances, UInt32 maxLen)
+{
+ son[_cyclicBufferPos] = curMatch;
+ for (;;)
+ {
+ UInt32 delta = pos - curMatch;
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+ return distances;
+ {
+ const Byte *pb = cur - delta;
+ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
+ if (pb[maxLen] == cur[maxLen] && *pb == *cur)
+ {
+ UInt32 len = 0;
+ while (++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ if (maxLen < len)
+ {
+ *distances++ = maxLen = len;
+ *distances++ = delta - 1;
+ if (len == lenLimit)
+ return distances;
+ }
+ }
+ }
+ }
+}
+
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
+ UInt32 *distances, UInt32 maxLen)
+{
+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
+ UInt32 len0 = 0, len1 = 0;
+ for (;;)
+ {
+ UInt32 delta = pos - curMatch;
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+ {
+ *ptr0 = *ptr1 = kEmptyHashValue;
+ return distances;
+ }
+ {
+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+ const Byte *pb = cur - delta;
+ UInt32 len = (len0 < len1 ? len0 : len1);
+ if (pb[len] == cur[len])
+ {
+ if (++len != lenLimit && pb[len] == cur[len])
+ while (++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ if (maxLen < len)
+ {
+ *distances++ = maxLen = len;
+ *distances++ = delta - 1;
+ if (len == lenLimit)
+ {
+ *ptr1 = pair[0];
+ *ptr0 = pair[1];
+ return distances;
+ }
+ }
+ }
+ if (pb[len] < cur[len])
+ {
+ *ptr1 = curMatch;
+ ptr1 = pair + 1;
+ curMatch = *ptr1;
+ len1 = len;
+ }
+ else
+ {
+ *ptr0 = curMatch;
+ ptr0 = pair;
+ curMatch = *ptr0;
+ len0 = len;
+ }
+ }
+ }
+}
+
+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
+{
+ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
+ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
+ UInt32 len0 = 0, len1 = 0;
+ for (;;)
+ {
+ UInt32 delta = pos - curMatch;
+ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
+ {
+ *ptr0 = *ptr1 = kEmptyHashValue;
+ return;
+ }
+ {
+ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
+ const Byte *pb = cur - delta;
+ UInt32 len = (len0 < len1 ? len0 : len1);
+ if (pb[len] == cur[len])
+ {
+ while (++len != lenLimit)
+ if (pb[len] != cur[len])
+ break;
+ {
+ if (len == lenLimit)
+ {
+ *ptr1 = pair[0];
+ *ptr0 = pair[1];
+ return;
+ }
+ }
+ }
+ if (pb[len] < cur[len])
+ {
+ *ptr1 = curMatch;
+ ptr1 = pair + 1;
+ curMatch = *ptr1;
+ len1 = len;
+ }
+ else
+ {
+ *ptr0 = curMatch;
+ ptr0 = pair;
+ curMatch = *ptr0;
+ len0 = len;
+ }
+ }
+ }
+}
+
+#define MOVE_POS \
+ ++p->cyclicBufferPos; \
+ p->buffer++; \
+ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
+
+#define MOVE_POS_RET MOVE_POS return offset;
+
+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
+
+#define GET_MATCHES_HEADER2(minLen, ret_op) \
+ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
+ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
+ cur = p->buffer;
+
+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
+#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
+
+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
+
+#define GET_MATCHES_FOOTER(offset, maxLen) \
+ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
+ distances + offset, maxLen) - distances); MOVE_POS_RET;
+
+#define SKIP_FOOTER \
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
+
+static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 offset;
+ GET_MATCHES_HEADER(2)
+ HASH2_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ offset = 0;
+ GET_MATCHES_FOOTER(offset, 1)
+}
+
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 offset;
+ GET_MATCHES_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ offset = 0;
+ GET_MATCHES_FOOTER(offset, 2)
+}
+
+static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 hash2Value, delta2, maxLen, offset;
+ GET_MATCHES_HEADER(3)
+
+ HASH3_CALC;
+
+ delta2 = p->pos - p->hash[hash2Value];
+ curMatch = p->hash[kFix3HashSize + hashValue];
+
+ p->hash[hash2Value] =
+ p->hash[kFix3HashSize + hashValue] = p->pos;
+
+
+ maxLen = 2;
+ offset = 0;
+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+ {
+ for (; maxLen != lenLimit; maxLen++)
+ if (cur[(ptrdiff_t)maxLen - (ptrdiff_t)delta2] != cur[maxLen]) /*MAB second casts (ptrdiff_t)*/
+ break;
+ distances[0] = maxLen;
+ distances[1] = delta2 - 1;
+ offset = 2;
+ if (maxLen == lenLimit)
+ {
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
+ MOVE_POS_RET;
+ }
+ }
+ GET_MATCHES_FOOTER(offset, maxLen)
+}
+
+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+ GET_MATCHES_HEADER(4)
+
+ HASH4_CALC;
+
+ delta2 = p->pos - p->hash[ hash2Value];
+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
+ curMatch = p->hash[kFix4HashSize + hashValue];
+
+ p->hash[ hash2Value] =
+ p->hash[kFix3HashSize + hash3Value] =
+ p->hash[kFix4HashSize + hashValue] = p->pos;
+
+ maxLen = 1;
+ offset = 0;
+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+ {
+ distances[0] = maxLen = 2;
+ distances[1] = delta2 - 1;
+ offset = 2;
+ }
+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+ {
+ maxLen = 3;
+ distances[offset + 1] = delta3 - 1;
+ offset += 2;
+ delta2 = delta3;
+ }
+ if (offset != 0)
+ {
+ for (; maxLen != lenLimit; maxLen++)
+ if (cur[(ptrdiff_t)maxLen - (ptrdiff_t)delta2] != cur[maxLen]) /*MAB casts second (ptrdiff_t)*/
+ break;
+ distances[offset - 2] = maxLen;
+ if (maxLen == lenLimit)
+ {
+ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
+ MOVE_POS_RET;
+ }
+ }
+ if (maxLen < 3)
+ maxLen = 3;
+ GET_MATCHES_FOOTER(offset, maxLen)
+}
+
+static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
+ GET_MATCHES_HEADER(4)
+
+ HASH4_CALC;
+
+ delta2 = p->pos - p->hash[ hash2Value];
+ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
+ curMatch = p->hash[kFix4HashSize + hashValue];
+
+ p->hash[ hash2Value] =
+ p->hash[kFix3HashSize + hash3Value] =
+ p->hash[kFix4HashSize + hashValue] = p->pos;
+
+ maxLen = 1;
+ offset = 0;
+ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
+ {
+ distances[0] = maxLen = 2;
+ distances[1] = delta2 - 1;
+ offset = 2;
+ }
+ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
+ {
+ maxLen = 3;
+ distances[offset + 1] = delta3 - 1;
+ offset += 2;
+ delta2 = delta3;
+ }
+ if (offset != 0)
+ {
+ for (; maxLen != lenLimit; maxLen++)
+ if (cur[(ptrdiff_t)maxLen - (ptrdiff_t)delta2] != cur[maxLen]) /*MAB casts second (ptrdiff_t) */
+ break;
+
+ distances[offset - 2] = maxLen;
+ if (maxLen == lenLimit)
+ {
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS_RET;
+ }
+ }
+ if (maxLen < 3)
+ maxLen = 3;
+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+ distances + offset, maxLen) - (distances));
+ MOVE_POS_RET
+}
+
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
+{
+ UInt32 offset;
+ GET_MATCHES_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
+ distances, 2) - (distances));
+ MOVE_POS_RET
+}
+
+static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ SKIP_HEADER(2)
+ HASH2_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ SKIP_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 hash2Value;
+ SKIP_HEADER(3)
+ HASH3_CALC;
+ curMatch = p->hash[kFix3HashSize + hashValue];
+ p->hash[hash2Value] =
+ p->hash[kFix3HashSize + hashValue] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 hash2Value, hash3Value;
+ SKIP_HEADER(4)
+ HASH4_CALC;
+ curMatch = p->hash[kFix4HashSize + hashValue];
+ p->hash[ hash2Value] =
+ p->hash[kFix3HashSize + hash3Value] = p->pos;
+ p->hash[kFix4HashSize + hashValue] = p->pos;
+ SKIP_FOOTER
+ }
+ while (--num != 0);
+}
+
+static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ UInt32 hash2Value, hash3Value;
+ SKIP_HEADER(4)
+ HASH4_CALC;
+ curMatch = p->hash[kFix4HashSize + hashValue];
+ p->hash[ hash2Value] =
+ p->hash[kFix3HashSize + hash3Value] =
+ p->hash[kFix4HashSize + hashValue] = p->pos;
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS
+ }
+ while (--num != 0);
+}
+
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
+{
+ do
+ {
+ SKIP_HEADER(3)
+ HASH_ZIP_CALC;
+ curMatch = p->hash[hashValue];
+ p->hash[hashValue] = p->pos;
+ p->son[p->cyclicBufferPos] = curMatch;
+ MOVE_POS
+ }
+ while (--num != 0);
+}
+
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
+{
+ vTable->Init = (Mf_Init_Func)MatchFinder_Init;
+ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
+ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
+ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
+ if (!p->btMode)
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
+ }
+ else if (p->numHashBytes == 2)
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
+ }
+ else if (p->numHashBytes == 3)
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
+ }
+ else
+ {
+ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
+ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
+ }
+}
diff --git a/DroidFish/jni/gtb/compression/lzma/LzFind.h b/DroidFish/jni/gtb/compression/lzma/LzFind.h
new file mode 100755
index 0000000..423d67e
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/LzFind.h
@@ -0,0 +1,107 @@
+/* LzFind.h -- Match finder for LZ algorithms
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZFIND_H
+#define __LZFIND_H
+
+#include "Types.h"
+
+typedef UInt32 CLzRef;
+
+typedef struct _CMatchFinder
+{
+ Byte *buffer;
+ UInt32 pos;
+ UInt32 posLimit;
+ UInt32 streamPos;
+ UInt32 lenLimit;
+
+ UInt32 cyclicBufferPos;
+ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
+
+ UInt32 matchMaxLen;
+ CLzRef *hash;
+ CLzRef *son;
+ UInt32 hashMask;
+ UInt32 cutValue;
+
+ Byte *bufferBase;
+ ISeqInStream *stream;
+ int streamEndWasReached;
+
+ UInt32 blockSize;
+ UInt32 keepSizeBefore;
+ UInt32 keepSizeAfter;
+
+ UInt32 numHashBytes;
+ int directInput;
+ int btMode;
+ /* int skipModeBits; */
+ int bigHash;
+ UInt32 historySize;
+ UInt32 fixedHashSize;
+ UInt32 hashSizeSum;
+ UInt32 numSons;
+ SRes result;
+ UInt32 crc[256];
+} CMatchFinder;
+
+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
+
+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
+
+int MatchFinder_NeedMove(CMatchFinder *p);
+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
+void MatchFinder_MoveBlock(CMatchFinder *p);
+void MatchFinder_ReadIfRequired(CMatchFinder *p);
+
+void MatchFinder_Construct(CMatchFinder *p);
+
+/* Conditions:
+ historySize <= 3 GB
+ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
+*/
+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
+ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
+ ISzAlloc *alloc);
+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
+
+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
+ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
+ UInt32 *distances, UInt32 maxLen);
+
+/*
+Conditions:
+ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
+ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
+*/
+
+typedef void (*Mf_Init_Func)(void *object);
+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
+typedef void (*Mf_Skip_Func)(void *object, UInt32);
+
+typedef struct _IMatchFinder
+{
+ Mf_Init_Func Init;
+ Mf_GetIndexByte_Func GetIndexByte;
+ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
+ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
+ Mf_GetMatches_Func GetMatches;
+ Mf_Skip_Func Skip;
+} IMatchFinder;
+
+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
+
+void MatchFinder_Init(CMatchFinder *p);
+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
+
+#endif
diff --git a/DroidFish/jni/gtb/compression/lzma/LzFindMt.h b/DroidFish/jni/gtb/compression/lzma/LzFindMt.h
new file mode 100755
index 0000000..b7ead2d
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/LzFindMt.h
@@ -0,0 +1,97 @@
+/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZFINDMT_H
+#define __LZFINDMT_H
+
+#include "Threads.h"
+#include "LzFind.h"
+
+#define kMtHashBlockSize (1 << 13)
+#define kMtHashNumBlocks (1 << 3)
+#define kMtHashNumBlocksMask (kMtHashNumBlocks - 1)
+
+#define kMtBtBlockSize (1 << 14)
+#define kMtBtNumBlocks (1 << 6)
+#define kMtBtNumBlocksMask (kMtBtNumBlocks - 1)
+
+typedef struct _CMtSync
+{
+ Bool wasCreated;
+ Bool needStart;
+ Bool exit;
+ Bool stopWriting;
+
+ CThread thread;
+ CAutoResetEvent canStart;
+ CAutoResetEvent wasStarted;
+ CAutoResetEvent wasStopped;
+ CSemaphore freeSemaphore;
+ CSemaphore filledSemaphore;
+ Bool csWasInitialized;
+ Bool csWasEntered;
+ CCriticalSection cs;
+ UInt32 numProcessedBlocks;
+} CMtSync;
+
+typedef UInt32 * (*Mf_Mix_Matches)(void *p, UInt32 matchMinPos, UInt32 *distances);
+
+/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */
+#define kMtCacheLineDummy 128
+
+typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos,
+ UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc);
+
+typedef struct _CMatchFinderMt
+{
+ /* LZ */
+ const Byte *pointerToCurPos;
+ UInt32 *btBuf;
+ UInt32 btBufPos;
+ UInt32 btBufPosLimit;
+ UInt32 lzPos;
+ UInt32 btNumAvailBytes;
+
+ UInt32 *hash;
+ UInt32 fixedHashSize;
+ UInt32 historySize;
+ const UInt32 *crc;
+
+ Mf_Mix_Matches MixMatchesFunc;
+
+ /* LZ + BT */
+ CMtSync btSync;
+ Byte btDummy[kMtCacheLineDummy];
+
+ /* BT */
+ UInt32 *hashBuf;
+ UInt32 hashBufPos;
+ UInt32 hashBufPosLimit;
+ UInt32 hashNumAvail;
+
+ CLzRef *son;
+ UInt32 matchMaxLen;
+ UInt32 numHashBytes;
+ UInt32 pos;
+ Byte *buffer;
+ UInt32 cyclicBufferPos;
+ UInt32 cyclicBufferSize; /* it must be historySize + 1 */
+ UInt32 cutValue;
+
+ /* BT + Hash */
+ CMtSync hashSync;
+ /* Byte hashDummy[kMtCacheLineDummy]; */
+
+ /* Hash */
+ Mf_GetHeads GetHeadsFunc;
+ CMatchFinder *MatchFinder;
+} CMatchFinderMt;
+
+void MatchFinderMt_Construct(CMatchFinderMt *p);
+void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAlloc *alloc);
+SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
+ UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAlloc *alloc);
+void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder *vTable);
+void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
+
+#endif
diff --git a/DroidFish/jni/gtb/compression/lzma/LzHash.h b/DroidFish/jni/gtb/compression/lzma/LzHash.h
new file mode 100755
index 0000000..c923417
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/LzHash.h
@@ -0,0 +1,54 @@
+/* LzHash.h -- HASH functions for LZ algorithms
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZHASH_H
+#define __LZHASH_H
+
+#define kHash2Size (1 << 10)
+#define kHash3Size (1 << 16)
+#define kHash4Size (1 << 20)
+
+#define kFix3HashSize (kHash2Size)
+#define kFix4HashSize (kHash2Size + kHash3Size)
+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
+
+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
+
+#define HASH3_CALC { \
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
+
+#define HASH4_CALC { \
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
+
+#define HASH5_CALC { \
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
+ hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
+ hash4Value &= (kHash4Size - 1); }
+
+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
+
+
+#define MT_HASH2_CALC \
+ hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
+
+#define MT_HASH3_CALC { \
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
+
+#define MT_HASH4_CALC { \
+ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
+ hash2Value = temp & (kHash2Size - 1); \
+ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
+ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
+
+#endif
diff --git a/DroidFish/jni/gtb/compression/lzma/Lzma86Dec.c b/DroidFish/jni/gtb/compression/lzma/Lzma86Dec.c
new file mode 100755
index 0000000..c3f1dff
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/Lzma86Dec.c
@@ -0,0 +1,61 @@
+/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
+2008-04-07
+Igor Pavlov
+Public domain */
+
+#include "Lzma86Dec.h"
+
+#include "Alloc.h"
+#include "Bra.h"
+#include "LzmaDec.h"
+
+#define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE)
+#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
+
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
+static void SzFree(void *p, void *address) { p = p; MyFree(address); }
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
+{
+ unsigned i;
+ if (srcLen < LZMA86_HEADER_SIZE)
+ return SZ_ERROR_INPUT_EOF;
+ *unpackSize = 0;
+ for (i = 0; i < sizeof(UInt64); i++)
+ *unpackSize += ((UInt64)src[LZMA86_SIZE_OFFSET + i]) << (8 * i);
+ return SZ_OK;
+}
+
+SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen)
+{
+ SRes res;
+ int useFilter;
+ SizeT inSizePure;
+ ELzmaStatus status;
+
+ if (*srcLen < LZMA86_HEADER_SIZE)
+ return SZ_ERROR_INPUT_EOF;
+
+ useFilter = src[0];
+
+ if (useFilter > 1)
+ {
+ *destLen = 0;
+ return SZ_ERROR_UNSUPPORTED;
+ }
+
+ inSizePure = *srcLen - LZMA86_HEADER_SIZE;
+ res = LzmaDecode(dest, destLen, src + LZMA86_HEADER_SIZE, &inSizePure,
+ src + 1, LZMA_PROPS_SIZE, LZMA_FINISH_ANY, &status, &g_Alloc);
+ *srcLen = inSizePure + LZMA86_HEADER_SIZE;
+ if (res != SZ_OK)
+ return res;
+ if (useFilter == 1)
+ {
+ UInt32 x86State;
+ x86_Convert_Init(x86State);
+ x86_Convert(dest, *destLen, 0, &x86State, 0);
+ }
+ return SZ_OK;
+}
diff --git a/DroidFish/jni/gtb/compression/lzma/Lzma86Dec.h b/DroidFish/jni/gtb/compression/lzma/Lzma86Dec.h
new file mode 100755
index 0000000..3ddb227
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/Lzma86Dec.h
@@ -0,0 +1,45 @@
+/* Lzma86Dec.h -- LZMA + x86 (BCJ) Filter Decoder
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#ifndef __LZMA86DEC_H
+#define __LZMA86DEC_H
+
+#include "Types.h"
+
+/*
+Lzma86_GetUnpackSize:
+ In:
+ src - input data
+ srcLen - input data size
+ Out:
+ unpackSize - size of uncompressed stream
+ Return code:
+ SZ_OK - OK
+ SZ_ERROR_INPUT_EOF - Error in headers
+*/
+
+SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize);
+
+/*
+Lzma86_Decode:
+ In:
+ dest - output data
+ destLen - output data size
+ src - input data
+ srcLen - input data size
+ Out:
+ destLen - processed output size
+ srcLen - processed input size
+ Return code:
+ SZ_OK - OK
+ SZ_ERROR_DATA - Data error
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_UNSUPPORTED - unsupported file
+ SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer
+*/
+
+SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen);
+
+#endif
diff --git a/DroidFish/jni/gtb/compression/lzma/Lzma86Enc.c b/DroidFish/jni/gtb/compression/lzma/Lzma86Enc.c
new file mode 100755
index 0000000..4cd30e6
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/Lzma86Enc.c
@@ -0,0 +1,113 @@
+/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#include
+
+#include "Lzma86Enc.h"
+
+#include "Alloc.h"
+#include "Bra.h"
+#include "LzmaEnc.h"
+
+#define SZE_OUT_OVERFLOW SZE_DATA_ERROR
+
+static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); }
+static void SzFree(void *p, void *address) { p = p; MyFree(address); }
+static ISzAlloc g_Alloc = { SzAlloc, SzFree };
+
+#define LZMA86_SIZE_OFFSET (1 + LZMA_PROPS_SIZE)
+#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
+
+int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
+ int level, UInt32 dictSize, int filterMode)
+{
+ size_t outSize2 = *destLen;
+ Byte *filteredStream;
+ Bool useFilter;
+ int mainResult = SZ_ERROR_OUTPUT_EOF;
+ CLzmaEncProps props;
+ LzmaEncProps_Init(&props);
+ props.level = level;
+ props.dictSize = dictSize;
+
+ *destLen = 0;
+ if (outSize2 < LZMA86_HEADER_SIZE)
+ return SZ_ERROR_OUTPUT_EOF;
+
+ {
+ int i;
+ UInt64 t = srcLen;
+ for (i = 0; i < 8; i++, t >>= 8)
+ dest[LZMA86_SIZE_OFFSET + i] = (Byte)t;
+ }
+
+ filteredStream = 0;
+ useFilter = (filterMode != SZ_FILTER_NO);
+ if (useFilter)
+ {
+ if (srcLen != 0)
+ {
+ filteredStream = (Byte *)MyAlloc(srcLen);
+ if (filteredStream == 0)
+ return SZ_ERROR_MEM;
+ memcpy(filteredStream, src, srcLen);
+ }
+ {
+ UInt32 x86State;
+ x86_Convert_Init(x86State);
+ x86_Convert(filteredStream, srcLen, 0, &x86State, 1);
+ }
+ }
+
+ {
+ size_t minSize = 0;
+ Bool bestIsFiltered = False;
+
+ /* passes for SZ_FILTER_AUTO:
+ 0 - BCJ + LZMA
+ 1 - LZMA
+ 2 - BCJ + LZMA agaian, if pass 0 (BCJ + LZMA) is better.
+ */
+ int numPasses = (filterMode == SZ_FILTER_AUTO) ? 3 : 1;
+
+ int i;
+ for (i = 0; i < numPasses; i++)
+ {
+ size_t outSizeProcessed = outSize2 - LZMA86_HEADER_SIZE;
+ size_t outPropsSize = 5;
+ SRes curRes;
+ Bool curModeIsFiltered = (numPasses > 1 && i == numPasses - 1);
+ if (curModeIsFiltered && !bestIsFiltered)
+ break;
+ if (useFilter && i == 0)
+ curModeIsFiltered = True;
+
+ curRes = LzmaEncode(dest + LZMA86_HEADER_SIZE, &outSizeProcessed,
+ curModeIsFiltered ? filteredStream : src, srcLen,
+ &props, dest + 1, &outPropsSize, 0,
+ NULL, &g_Alloc, &g_Alloc);
+
+ if (curRes != SZ_ERROR_OUTPUT_EOF)
+ {
+ if (curRes != SZ_OK)
+ {
+ mainResult = curRes;
+ break;
+ }
+ if (outSizeProcessed <= minSize || mainResult != SZ_OK)
+ {
+ minSize = outSizeProcessed;
+ bestIsFiltered = curModeIsFiltered;
+ mainResult = SZ_OK;
+ }
+ }
+ }
+ dest[0] = (unsigned char) (bestIsFiltered ? 1 : 0); /*MAB: Cast to silence compiler */
+ *destLen = LZMA86_HEADER_SIZE + minSize;
+ }
+ if (useFilter)
+ MyFree(filteredStream);
+ return mainResult;
+}
diff --git a/DroidFish/jni/gtb/compression/lzma/Lzma86Enc.h b/DroidFish/jni/gtb/compression/lzma/Lzma86Enc.h
new file mode 100755
index 0000000..eb7ba7d
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/Lzma86Enc.h
@@ -0,0 +1,72 @@
+/* Lzma86Enc.h -- LZMA + x86 (BCJ) Filter Encoder
+2008-08-05
+Igor Pavlov
+Public domain */
+
+#ifndef __LZMA86ENC_H
+#define __LZMA86ENC_H
+
+#include "Types.h"
+
+/*
+It's an example for LZMA + x86 Filter use.
+You can use .lzma86 extension, if you write that stream to file.
+.lzma86 header adds one additional byte to standard .lzma header.
+.lzma86 header (14 bytes):
+ Offset Size Description
+ 0 1 = 0 - no filter,
+ = 1 - x86 filter
+ 1 1 lc, lp and pb in encoded form
+ 2 4 dictSize (little endian)
+ 6 8 uncompressed size (little endian)
+
+
+Lzma86_Encode
+-------------
+level - compression level: 0 <= level <= 9, the default value for "level" is 5.
+
+
+dictSize - The dictionary size in bytes. The maximum value is
+ 128 MB = (1 << 27) bytes for 32-bit version
+ 1 GB = (1 << 30) bytes for 64-bit version
+ The default value is 16 MB = (1 << 24) bytes, for level = 5.
+ It's recommended to use the dictionary that is larger than 4 KB and
+ that can be calculated as (1 << N) or (3 << N) sizes.
+ For better compression ratio dictSize must be >= inSize.
+
+filterMode:
+ SZ_FILTER_NO - no Filter
+ SZ_FILTER_YES - x86 Filter
+ SZ_FILTER_AUTO - it tries both alternatives to select best.
+ Encoder will use 2 or 3 passes:
+ 2 passes when FILTER_NO provides better compression.
+ 3 passes when FILTER_YES provides better compression.
+
+Lzma86Encode allocates Data with MyAlloc functions.
+RAM Requirements for compressing:
+ RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize
+ filterMode FilterBlockSize
+ SZ_FILTER_NO 0
+ SZ_FILTER_YES inSize
+ SZ_FILTER_AUTO inSize
+
+
+Return code:
+ SZ_OK - OK
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_PARAM - Incorrect paramater
+ SZ_ERROR_OUTPUT_EOF - output buffer overflow
+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
+*/
+
+enum ESzFilterMode
+{
+ SZ_FILTER_NO,
+ SZ_FILTER_YES,
+ SZ_FILTER_AUTO
+};
+
+SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
+ int level, UInt32 dictSize, int filterMode);
+
+#endif
diff --git a/DroidFish/jni/gtb/compression/lzma/LzmaDec.c b/DroidFish/jni/gtb/compression/lzma/LzmaDec.c
new file mode 100755
index 0000000..00f93aa
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/LzmaDec.c
@@ -0,0 +1,1012 @@
+/* LzmaDec.c -- LZMA Decoder
+2008-11-06 : Igor Pavlov : Public domain */
+
+#include "LzmaDec.h"
+
+#include
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+
+#define RC_INIT_SIZE 5
+
+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
+ { UPDATE_0(p); i = (i + i); A0; } else \
+ { UPDATE_1(p); i = (i + i) + 1; A1; }
+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
+
+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
+#define TREE_DECODE(probs, limit, i) \
+ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
+
+/* #define _LZMA_SIZE_OPT */
+
+#ifdef _LZMA_SIZE_OPT
+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
+#else
+#define TREE_6_DECODE(probs, i) \
+ { i = 1; \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ TREE_GET_BIT(probs, i); \
+ i -= 0x40; }
+#endif
+
+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
+
+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
+#define UPDATE_0_CHECK range = bound;
+#define UPDATE_1_CHECK range -= bound; code -= bound;
+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
+ { UPDATE_0_CHECK; i = (i + i); A0; } else \
+ { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
+#define TREE_DECODE_CHECK(probs, limit, i) \
+ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
+
+
+#define kNumPosBitsMax 4
+#define kNumPosStatesMax (1 << kNumPosBitsMax)
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define LenChoice 0
+#define LenChoice2 (LenChoice + 1)
+#define LenLow (LenChoice2 + 1)
+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
+
+
+#define kNumStates 12
+#define kNumLitStates 7
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
+
+#define kNumPosSlotBits 6
+#define kNumLenToPosStates 4
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+
+#define kMatchMinLen 2
+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
+
+#define IsMatch 0
+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
+#define IsRepG0 (IsRep + kNumStates)
+#define IsRepG1 (IsRepG0 + kNumStates)
+#define IsRepG2 (IsRepG1 + kNumStates)
+#define IsRep0Long (IsRepG2 + kNumStates)
+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
+#define LenCoder (Align + kAlignTableSize)
+#define RepLenCoder (LenCoder + kNumLenProbs)
+#define Literal (RepLenCoder + kNumLenProbs)
+
+#define LZMA_BASE_SIZE 1846
+#define LZMA_LIT_SIZE 768
+/*MAB casts next... */
+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + ((unsigned)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
+
+#if Literal != LZMA_BASE_SIZE
+StopCompilingDueBUG
+#endif
+
+static const Byte kLiteralNextStates[kNumStates * 2] =
+{
+ 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
+ 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
+};
+
+#define LZMA_DIC_MIN (1 << 12)
+
+/* First LZMA-symbol is always decoded.
+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
+Out:
+ Result:
+ SZ_OK - OK
+ SZ_ERROR_DATA - Error
+ p->remainLen:
+ < kMatchSpecLenStart : normal remain
+ = kMatchSpecLenStart : finished
+ = kMatchSpecLenStart + 1 : Flush marker
+ = kMatchSpecLenStart + 2 : State Init Marker
+*/
+
+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+ CLzmaProb *probs = p->probs;
+
+ unsigned state = p->state;
+ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
+ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
+ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
+ unsigned lc = p->prop.lc;
+
+ Byte *dic = p->dic;
+ SizeT dicBufSize = p->dicBufSize;
+ SizeT dicPos = p->dicPos;
+
+ UInt32 processedPos = p->processedPos;
+ UInt32 checkDicSize = p->checkDicSize;
+ unsigned len = 0;
+
+ const Byte *buf = p->buf;
+ UInt32 range = p->range;
+ UInt32 code = p->code;
+
+ do
+ {
+ CLzmaProb *prob;
+ UInt32 bound;
+ unsigned ttt;
+ unsigned posState = processedPos & pbMask;
+
+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+ IF_BIT_0(prob)
+ {
+ unsigned symbol;
+ UPDATE_0(prob);
+ prob = probs + Literal;
+ if (checkDicSize != 0 || processedPos != 0)
+ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + (UInt32) ( /*MAB casts */
+ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))) )
+ ;
+ if (state < kNumLitStates)
+ {
+ symbol = 1;
+ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
+ }
+ else
+ {
+ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ unsigned offs = 0x100;
+ symbol = 1;
+ do
+ {
+ unsigned bit;
+ CLzmaProb *probLit;
+ matchByte <<= 1;
+ bit = (matchByte & offs);
+ probLit = prob + offs + bit + symbol;
+ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
+ }
+ while (symbol < 0x100);
+ }
+ dic[dicPos++] = (Byte)symbol;
+ processedPos++;
+
+ state = kLiteralNextStates[state];
+ /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
+ continue;
+ }
+ else
+ {
+ UPDATE_1(prob);
+ prob = probs + IsRep + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ state += kNumStates;
+ prob = probs + LenCoder;
+ }
+ else
+ {
+ UPDATE_1(prob);
+ if (checkDicSize == 0 && processedPos == 0)
+ return SZ_ERROR_DATA;
+ prob = probs + IsRepG0 + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ dicPos++;
+ processedPos++;
+ state = state < kNumLitStates ? 9 : 11;
+ continue;
+ }
+ UPDATE_1(prob);
+ }
+ else
+ {
+ UInt32 distance;
+ UPDATE_1(prob);
+ prob = probs + IsRepG1 + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ distance = rep1;
+ }
+ else
+ {
+ UPDATE_1(prob);
+ prob = probs + IsRepG2 + state;
+ IF_BIT_0(prob)
+ {
+ UPDATE_0(prob);
+ distance = rep2;
+ }
+ else
+ {
+ UPDATE_1(prob);
+ distance = rep3;
+ rep3 = rep2;
+ }
+ rep2 = rep1;
+ }
+ rep1 = rep0;
+ rep0 = distance;
+ }
+ state = state < kNumLitStates ? 8 : 11;
+ prob = probs + RepLenCoder;
+ }
+ {
+ /*MAB: limit changed to limit__ because it was hiding a variable limit */
+ unsigned limit__, offset;
+ CLzmaProb *probLen = prob + LenChoice;
+ IF_BIT_0(probLen)
+ {
+ UPDATE_0(probLen);
+ probLen = prob + LenLow + (posState << kLenNumLowBits);
+ offset = 0;
+ limit__ = (1 << kLenNumLowBits);
+ }
+ else
+ {
+ UPDATE_1(probLen);
+ probLen = prob + LenChoice2;
+ IF_BIT_0(probLen)
+ {
+ UPDATE_0(probLen);
+ probLen = prob + LenMid + (posState << kLenNumMidBits);
+ offset = kLenNumLowSymbols;
+ limit__ = (1 << kLenNumMidBits);
+ }
+ else
+ {
+ UPDATE_1(probLen);
+ probLen = prob + LenHigh;
+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
+ limit__ = (1 << kLenNumHighBits);
+ }
+ }
+ TREE_DECODE(probLen, limit__, len);
+ len += offset;
+ }
+
+ if (state >= kNumStates)
+ {
+ UInt32 distance;
+ prob = probs + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
+ TREE_6_DECODE(prob, distance);
+ if (distance >= kStartPosModelIndex)
+ {
+ unsigned posSlot = (unsigned)distance;
+ int numDirectBits = (int)(((distance >> 1) - 1));
+ distance = (2 | (distance & 1));
+ if (posSlot < kEndPosModelIndex)
+ {
+ distance <<= numDirectBits;
+ prob = probs + SpecPos + distance - posSlot - 1;
+ {
+ UInt32 mask = 1;
+ unsigned i = 1;
+ do
+ {
+ GET_BIT2(prob + i, i, ; , distance |= mask);
+ mask <<= 1;
+ }
+ while (--numDirectBits != 0);
+ }
+ }
+ else
+ {
+ numDirectBits -= kNumAlignBits;
+ do
+ {
+ NORMALIZE
+ range >>= 1;
+
+ {
+ UInt32 t;
+ code -= range;
+ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
+ distance = (distance << 1) + (t + 1);
+ code += range & t;
+ }
+ /*
+ distance <<= 1;
+ if (code >= range)
+ {
+ code -= range;
+ distance |= 1;
+ }
+ */
+ }
+ while (--numDirectBits != 0);
+ prob = probs + Align;
+ distance <<= kNumAlignBits;
+ {
+ unsigned i = 1;
+ GET_BIT2(prob + i, i, ; , distance |= 1);
+ GET_BIT2(prob + i, i, ; , distance |= 2);
+ GET_BIT2(prob + i, i, ; , distance |= 4);
+ GET_BIT2(prob + i, i, ; , distance |= 8);
+ }
+ if (distance == (UInt32)0xFFFFFFFF)
+ {
+ len += kMatchSpecLenStart;
+ state -= kNumStates;
+ break;
+ }
+ }
+ }
+ rep3 = rep2;
+ rep2 = rep1;
+ rep1 = rep0;
+ rep0 = distance + 1;
+ if (checkDicSize == 0)
+ {
+ if (distance >= processedPos)
+ return SZ_ERROR_DATA;
+ }
+ else if (distance >= checkDicSize)
+ return SZ_ERROR_DATA;
+ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
+ /* state = kLiteralNextStates[state]; */
+ }
+
+ len += kMatchMinLen;
+
+ if (limit == dicPos)
+ return SZ_ERROR_DATA;
+ {
+ SizeT rem = limit - dicPos;
+ unsigned curLen = ((rem < len) ? (unsigned)rem : len);
+ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
+
+ processedPos += curLen;
+
+ len -= curLen;
+ if (pos + curLen <= dicBufSize)
+ {
+ Byte *dest = dic + dicPos;
+ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
+ const Byte *lim = dest + curLen;
+ dicPos += curLen;
+ do
+ *(dest) = (Byte)*(dest + src);
+ while (++dest != lim);
+ }
+ else
+ {
+ do
+ {
+ dic[dicPos++] = dic[pos];
+ if (++pos == dicBufSize)
+ pos = 0;
+ }
+ while (--curLen != 0);
+ }
+ }
+ }
+ }
+ while (dicPos < limit && buf < bufLimit);
+ NORMALIZE;
+ p->buf = buf;
+ p->range = range;
+ p->code = code;
+ p->remainLen = len;
+ p->dicPos = dicPos;
+ p->processedPos = processedPos;
+ p->reps[0] = rep0;
+ p->reps[1] = rep1;
+ p->reps[2] = rep2;
+ p->reps[3] = rep3;
+ p->state = state;
+
+ return SZ_OK;
+}
+
+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
+{
+ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
+ {
+ Byte *dic = p->dic;
+ SizeT dicPos = p->dicPos;
+ SizeT dicBufSize = p->dicBufSize;
+ unsigned len = p->remainLen;
+ UInt32 rep0 = p->reps[0];
+ if (limit - dicPos < len)
+ len = (unsigned)(limit - dicPos);
+
+ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
+ p->checkDicSize = p->prop.dicSize;
+
+ p->processedPos += len;
+ p->remainLen -= len;
+ while (len-- != 0)
+ {
+ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
+ dicPos++;
+ }
+ p->dicPos = dicPos;
+ }
+}
+
+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
+{
+ do
+ {
+ SizeT limit2 = limit;
+ if (p->checkDicSize == 0)
+ {
+ UInt32 rem = p->prop.dicSize - p->processedPos;
+ if (limit - p->dicPos > rem)
+ limit2 = p->dicPos + rem;
+ }
+ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
+ if (p->processedPos >= p->prop.dicSize)
+ p->checkDicSize = p->prop.dicSize;
+ LzmaDec_WriteRem(p, limit);
+ }
+ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
+
+ if (p->remainLen > kMatchSpecLenStart)
+ {
+ p->remainLen = kMatchSpecLenStart;
+ }
+ return 0;
+}
+
+typedef enum ELzmaDummy
+{
+ DUMMY_ERROR, /* unexpected end of input stream */
+ DUMMY_LIT,
+ DUMMY_MATCH,
+ DUMMY_REP
+} ELzmaDummy;
+
+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
+{
+ UInt32 range = p->range;
+ UInt32 code = p->code;
+ const Byte *bufLimit = buf + inSize;
+ CLzmaProb *probs = p->probs;
+ unsigned state = p->state;
+ ELzmaDummy res;
+
+ {
+ CLzmaProb *prob;
+ UInt32 bound;
+ unsigned ttt;
+ unsigned posState = (p->processedPos) & ((1u << p->prop.pb) - 1u); /*MAB 1u */
+
+ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK
+
+ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
+
+ prob = probs + Literal;
+ if (p->checkDicSize != 0 || p->processedPos != 0)
+ prob += (LZMA_LIT_SIZE *
+ ( (unsigned) /*MAB casts */
+ (((p->processedPos) & ((1u << (p->prop.lp)) - 1u)) << p->prop.lc) +
+ (unsigned) /*MAB casts */
+ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
+
+ if (state < kNumLitStates)
+ {
+ unsigned symbol = 1;
+ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
+ }
+ else
+ {
+ unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
+ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
+ unsigned offs = 0x100;
+ unsigned symbol = 1;
+ do
+ {
+ unsigned bit;
+ CLzmaProb *probLit;
+ matchByte <<= 1;
+ bit = (matchByte & offs);
+ probLit = prob + offs + bit + symbol;
+ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
+ }
+ while (symbol < 0x100);
+ }
+ res = DUMMY_LIT;
+ }
+ else
+ {
+ unsigned len;
+ UPDATE_1_CHECK;
+
+ prob = probs + IsRep + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ state = 0;
+ prob = probs + LenCoder;
+ res = DUMMY_MATCH;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ res = DUMMY_REP;
+ prob = probs + IsRepG0 + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ NORMALIZE_CHECK;
+ return DUMMY_REP;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ }
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ prob = probs + IsRepG1 + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ prob = probs + IsRepG2 + state;
+ IF_BIT_0_CHECK(prob)
+ {
+ UPDATE_0_CHECK;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ }
+ }
+ }
+ state = kNumStates;
+ prob = probs + RepLenCoder;
+ }
+ {
+ unsigned limit, offset;
+ CLzmaProb *probLen = prob + LenChoice;
+ IF_BIT_0_CHECK(probLen)
+ {
+ UPDATE_0_CHECK;
+ probLen = prob + LenLow + (posState << kLenNumLowBits);
+ offset = 0;
+ limit = 1 << kLenNumLowBits;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ probLen = prob + LenChoice2;
+ IF_BIT_0_CHECK(probLen)
+ {
+ UPDATE_0_CHECK;
+ probLen = prob + LenMid + (posState << kLenNumMidBits);
+ offset = kLenNumLowSymbols;
+ limit = 1 << kLenNumMidBits;
+ }
+ else
+ {
+ UPDATE_1_CHECK;
+ probLen = prob + LenHigh;
+ offset = kLenNumLowSymbols + kLenNumMidSymbols;
+ limit = 1 << kLenNumHighBits;
+ }
+ }
+ TREE_DECODE_CHECK(probLen, limit, len);
+ len += offset;
+ }
+
+ if (state < 4)
+ {
+ unsigned posSlot;
+ prob = probs + PosSlot +
+ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
+ kNumPosSlotBits);
+ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
+ if (posSlot >= kStartPosModelIndex)
+ {
+ int numDirectBits = (int)((posSlot >> 1) - 1); /*MAB casts */
+
+ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
+
+ if (posSlot < kEndPosModelIndex)
+ {
+ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
+ }
+ else
+ {
+ numDirectBits -= kNumAlignBits;
+ do
+ {
+ NORMALIZE_CHECK
+ range >>= 1;
+ code -= range & (((code - range) >> 31) - 1);
+ /* if (code >= range) code -= range; */
+ }
+ while (--numDirectBits != 0);
+ prob = probs + Align;
+ numDirectBits = kNumAlignBits;
+ }
+ {
+ unsigned i = 1;
+ do
+ {
+ GET_BIT_CHECK(prob + i, i);
+ }
+ while (--numDirectBits != 0);
+ }
+ }
+ }
+ }
+ }
+ NORMALIZE_CHECK;
+ return res;
+}
+
+
+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
+{
+ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
+ p->range = 0xFFFFFFFF;
+ p->needFlush = 0;
+}
+
+/*MAB: static added because it is not used externally */
+static
+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
+{
+ p->needFlush = 1;
+ p->remainLen = 0;
+ p->tempBufSize = 0;
+
+ if (initDic)
+ {
+ p->processedPos = 0;
+ p->checkDicSize = 0;
+ p->needInitState = 1;
+ }
+ if (initState)
+ p->needInitState = 1;
+}
+
+void LzmaDec_Init(CLzmaDec *p)
+{
+ p->dicPos = 0;
+ LzmaDec_InitDicAndState(p, True, True);
+}
+
+static void LzmaDec_InitStateReal(CLzmaDec *p)
+{
+ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
+ UInt32 i;
+ CLzmaProb *probs = p->probs;
+ for (i = 0; i < numProbs; i++)
+ probs[i] = kBitModelTotal >> 1;
+ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
+ p->state = 0;
+ p->needInitState = 0;
+}
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
+ ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+ SizeT inSize = *srcLen;
+ (*srcLen) = 0;
+ LzmaDec_WriteRem(p, dicLimit);
+
+ *status = LZMA_STATUS_NOT_SPECIFIED;
+
+ while (p->remainLen != kMatchSpecLenStart)
+ {
+ int checkEndMarkNow;
+
+ if (p->needFlush != 0)
+ {
+ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
+ p->tempBuf[p->tempBufSize++] = *src++;
+ if (p->tempBufSize < RC_INIT_SIZE)
+ {
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+ return SZ_OK;
+ }
+ if (p->tempBuf[0] != 0)
+ return SZ_ERROR_DATA;
+
+ LzmaDec_InitRc(p, p->tempBuf);
+ p->tempBufSize = 0;
+ }
+
+ checkEndMarkNow = 0;
+ if (p->dicPos >= dicLimit)
+ {
+ if (p->remainLen == 0 && p->code == 0)
+ {
+ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
+ return SZ_OK;
+ }
+ if (finishMode == LZMA_FINISH_ANY)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_OK;
+ }
+ if (p->remainLen != 0)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_ERROR_DATA;
+ }
+ checkEndMarkNow = 1;
+ }
+
+ if (p->needInitState)
+ LzmaDec_InitStateReal(p);
+
+ if (p->tempBufSize == 0)
+ {
+ SizeT processed;
+ const Byte *bufLimit;
+ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+ {
+ int dummyRes = LzmaDec_TryDummy(p, src, inSize);
+ if (dummyRes == DUMMY_ERROR)
+ {
+ memcpy(p->tempBuf, src, inSize);
+ p->tempBufSize = (unsigned)inSize;
+ (*srcLen) += inSize;
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+ return SZ_OK;
+ }
+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_ERROR_DATA;
+ }
+ bufLimit = src;
+ }
+ else
+ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
+ p->buf = src;
+ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
+ return SZ_ERROR_DATA;
+ processed = (SizeT)(p->buf - src);
+ (*srcLen) += processed;
+ src += processed;
+ inSize -= processed;
+ }
+ else
+ {
+ unsigned rem = p->tempBufSize, lookAhead = 0;
+ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
+ p->tempBuf[rem++] = src[lookAhead++];
+ p->tempBufSize = rem;
+ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
+ {
+ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
+ if (dummyRes == DUMMY_ERROR)
+ {
+ (*srcLen) += lookAhead;
+ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
+ return SZ_OK;
+ }
+ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
+ {
+ *status = LZMA_STATUS_NOT_FINISHED;
+ return SZ_ERROR_DATA;
+ }
+ }
+ p->buf = p->tempBuf;
+ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
+ return SZ_ERROR_DATA;
+ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
+ (*srcLen) += lookAhead;
+ src += lookAhead;
+ inSize -= lookAhead;
+ p->tempBufSize = 0;
+ }
+ }
+ if (p->code == 0)
+ *status = LZMA_STATUS_FINISHED_WITH_MARK;
+ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
+}
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
+{
+ SizeT outSize = *destLen;
+ SizeT inSize = *srcLen;
+ *srcLen = *destLen = 0;
+ for (;;)
+ {
+ SizeT inSizeCur = inSize, outSizeCur, dicPos;
+ ELzmaFinishMode curFinishMode;
+ SRes res;
+ if (p->dicPos == p->dicBufSize)
+ p->dicPos = 0;
+ dicPos = p->dicPos;
+ if (outSize > p->dicBufSize - dicPos)
+ {
+ outSizeCur = p->dicBufSize;
+ curFinishMode = LZMA_FINISH_ANY;
+ }
+ else
+ {
+ outSizeCur = dicPos + outSize;
+ curFinishMode = finishMode;
+ }
+
+ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
+ src += inSizeCur;
+ inSize -= inSizeCur;
+ *srcLen += inSizeCur;
+ outSizeCur = p->dicPos - dicPos;
+ memcpy(dest, p->dic + dicPos, outSizeCur);
+ dest += outSizeCur;
+ outSize -= outSizeCur;
+ *destLen += outSizeCur;
+ if (res != 0)
+ return res;
+ if (outSizeCur == 0 || outSize == 0)
+ return SZ_OK;
+ }
+}
+
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->probs);
+ p->probs = 0;
+}
+
+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->dic);
+ p->dic = 0;
+}
+
+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
+{
+ LzmaDec_FreeProbs(p, alloc);
+ LzmaDec_FreeDict(p, alloc);
+}
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
+{
+ UInt32 dicSize;
+ Byte d;
+
+ if (size < LZMA_PROPS_SIZE)
+ return SZ_ERROR_UNSUPPORTED;
+ else
+ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
+
+ if (dicSize < LZMA_DIC_MIN)
+ dicSize = LZMA_DIC_MIN;
+ p->dicSize = dicSize;
+
+ d = data[0];
+ if (d >= (9 * 5 * 5))
+ return SZ_ERROR_UNSUPPORTED;
+
+ p->lc = d % 9;
+ d /= 9;
+ p->pb = d / 5;
+ p->lp = d % 5;
+
+ return SZ_OK;
+}
+
+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
+{
+ UInt32 numProbs = (UInt32) (LzmaProps_GetNumProbs(propNew)); /*MAB casts */
+ if (p->probs == 0 || numProbs != p->numProbs)
+ {
+ LzmaDec_FreeProbs(p, alloc);
+ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
+ p->numProbs = numProbs;
+ if (p->probs == 0)
+ return SZ_ERROR_MEM;
+ }
+ return SZ_OK;
+}
+
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+ CLzmaProps propNew;
+ RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+ p->prop = propNew;
+ return SZ_OK;
+}
+
+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
+{
+ CLzmaProps propNew;
+ SizeT dicBufSize;
+ RINOK(LzmaProps_Decode(&propNew, props, propsSize));
+ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
+ dicBufSize = propNew.dicSize;
+ if (p->dic == 0 || dicBufSize != p->dicBufSize)
+ {
+ LzmaDec_FreeDict(p, alloc);
+ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
+ if (p->dic == 0)
+ {
+ LzmaDec_FreeProbs(p, alloc);
+ return SZ_ERROR_MEM;
+ }
+ }
+ p->dicBufSize = dicBufSize;
+ p->prop = propNew;
+ return SZ_OK;
+}
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+ ELzmaStatus *status, ISzAlloc *alloc)
+{
+ CLzmaDec p;
+ SRes res;
+ SizeT inSize = *srcLen;
+ SizeT outSize = *destLen;
+ *srcLen = *destLen = 0;
+ if (inSize < RC_INIT_SIZE)
+ return SZ_ERROR_INPUT_EOF;
+
+ LzmaDec_Construct(&p);
+ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
+ if (res != 0)
+ return res;
+ p.dic = dest;
+ p.dicBufSize = outSize;
+
+ LzmaDec_Init(&p);
+
+ *srcLen = inSize;
+ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
+
+ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
+ res = SZ_ERROR_INPUT_EOF;
+
+ (*destLen) = p.dicPos;
+ LzmaDec_FreeProbs(&p, alloc);
+ return res;
+}
diff --git a/DroidFish/jni/gtb/compression/lzma/LzmaDec.h b/DroidFish/jni/gtb/compression/lzma/LzmaDec.h
new file mode 100755
index 0000000..00d8398
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/LzmaDec.h
@@ -0,0 +1,223 @@
+/* LzmaDec.h -- LZMA Decoder
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZMADEC_H
+#define __LZMADEC_H
+
+#include "Types.h"
+
+/* #define _LZMA_PROB32 */
+/* _LZMA_PROB32 can increase the speed on some CPUs,
+ but memory usage for CLzmaDec::probs will be doubled in that case */
+
+#ifdef _LZMA_PROB32
+#define CLzmaProb UInt32
+#else
+#define CLzmaProb UInt16
+#endif
+
+
+/* ---------- LZMA Properties ---------- */
+
+#define LZMA_PROPS_SIZE 5
+
+typedef struct _CLzmaProps
+{
+ unsigned lc, lp, pb;
+ UInt32 dicSize;
+} CLzmaProps;
+
+/* LzmaProps_Decode - decodes properties
+Returns:
+ SZ_OK
+ SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+
+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
+
+
+/* ---------- LZMA Decoder state ---------- */
+
+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
+ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
+
+#define LZMA_REQUIRED_INPUT_MAX 20
+
+typedef struct CLzmaDec
+{
+ CLzmaProps prop;
+ CLzmaProb *probs;
+ Byte *dic;
+ const Byte *buf;
+ UInt32 range, code;
+ SizeT dicPos;
+ SizeT dicBufSize;
+ UInt32 processedPos;
+ UInt32 checkDicSize;
+ unsigned state;
+ UInt32 reps[4];
+ unsigned remainLen;
+ int needFlush;
+ int needInitState;
+ UInt32 numProbs;
+ unsigned tempBufSize;
+ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
+} CLzmaDec;
+
+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
+
+void LzmaDec_Init(CLzmaDec *p);
+
+/* There are two types of LZMA streams:
+ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
+ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
+
+typedef enum ELzmaFinishMode
+{
+ LZMA_FINISH_ANY, /* finish at any point */
+ LZMA_FINISH_END /* block must be finished at the end */
+} ELzmaFinishMode;
+
+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
+
+ You must use LZMA_FINISH_END, when you know that current output buffer
+ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
+
+ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
+ and output value of destLen will be less than output buffer size limit.
+ You can check status result also.
+
+ You can use multiple checks to test data integrity after full decompression:
+ 1) Check Result and "status" variable.
+ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
+ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
+ You must use correct finish mode in that case. */
+
+typedef enum ELzmaStatus
+{
+ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
+ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
+ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
+ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
+} ELzmaStatus;
+
+/* ELzmaStatus is used only as output value for function call */
+
+
+/* ---------- Interfaces ---------- */
+
+/* There are 3 levels of interfaces:
+ 1) Dictionary Interface
+ 2) Buffer Interface
+ 3) One Call Interface
+ You can select any of these interfaces, but don't mix functions from different
+ groups for same object. */
+
+
+/* There are two variants to allocate state for Dictionary Interface:
+ 1) LzmaDec_Allocate / LzmaDec_Free
+ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
+ You can use variant 2, if you set dictionary buffer manually.
+ For Buffer Interface you must always use variant 1.
+
+LzmaDec_Allocate* can return:
+ SZ_OK
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_UNSUPPORTED - Unsupported properties
+*/
+
+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
+
+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
+
+/* ---------- Dictionary Interface ---------- */
+
+/* You can use it, if you want to eliminate the overhead for data copying from
+ dictionary to some other external buffer.
+ You must work with CLzmaDec variables directly in this interface.
+
+ STEPS:
+ LzmaDec_Constr()
+ LzmaDec_Allocate()
+ for (each new stream)
+ {
+ LzmaDec_Init()
+ while (it needs more decompression)
+ {
+ LzmaDec_DecodeToDic()
+ use data from CLzmaDec::dic and update CLzmaDec::dicPos
+ }
+ }
+ LzmaDec_Free()
+*/
+
+/* LzmaDec_DecodeToDic
+
+ The decoding to internal dictionary buffer (CLzmaDec::dic).
+ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
+
+finishMode:
+ It has meaning only if the decoding reaches output limit (dicLimit).
+ LZMA_FINISH_ANY - Decode just dicLimit bytes.
+ LZMA_FINISH_END - Stream must be finished after dicLimit.
+
+Returns:
+ SZ_OK
+ status:
+ LZMA_STATUS_FINISHED_WITH_MARK
+ LZMA_STATUS_NOT_FINISHED
+ LZMA_STATUS_NEEDS_MORE_INPUT
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+ SZ_ERROR_DATA - Data error
+*/
+
+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- Buffer Interface ---------- */
+
+/* It's zlib-like interface.
+ See LzmaDec_DecodeToDic description for information about STEPS and return results,
+ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
+ to work with CLzmaDec variables manually.
+
+finishMode:
+ It has meaning only if the decoding reaches output limit (*destLen).
+ LZMA_FINISH_ANY - Decode just destLen bytes.
+ LZMA_FINISH_END - Stream must be finished after (*destLen).
+*/
+
+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
+ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
+
+
+/* ---------- One Call Interface ---------- */
+
+/* LzmaDecode
+
+finishMode:
+ It has meaning only if the decoding reaches output limit (*destLen).
+ LZMA_FINISH_ANY - Decode just destLen bytes.
+ LZMA_FINISH_END - Stream must be finished after (*destLen).
+
+Returns:
+ SZ_OK
+ status:
+ LZMA_STATUS_FINISHED_WITH_MARK
+ LZMA_STATUS_NOT_FINISHED
+ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
+ SZ_ERROR_DATA - Data error
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_UNSUPPORTED - Unsupported properties
+ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
+*/
+
+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
+ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
+ ELzmaStatus *status, ISzAlloc *alloc);
+
+#endif
diff --git a/DroidFish/jni/gtb/compression/lzma/LzmaEnc.c b/DroidFish/jni/gtb/compression/lzma/LzmaEnc.c
new file mode 100755
index 0000000..fc9153c
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/LzmaEnc.c
@@ -0,0 +1,2330 @@
+/* LzmaEnc.c -- LZMA Encoder
+2009-02-02 : Igor Pavlov : Public domain */
+
+#include
+
+/* #define SHOW_STAT */
+/* #define SHOW_STAT2 */
+
+#if defined(SHOW_STAT) || defined(SHOW_STAT2)
+#include
+#endif
+
+#include "LzmaEnc.h"
+
+#include "LzFind.h"
+#ifdef COMPRESS_MF_MT
+#include "LzFindMt.h"
+#endif
+
+#ifdef SHOW_STAT
+static int ttt = 0;
+#endif
+
+#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
+
+#define kBlockSize (9 << 10)
+#define kUnpackBlockSize (1 << 18)
+#define kMatchArraySize (1 << 21)
+#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
+
+#define kNumMaxDirectBits (31)
+
+#define kNumTopBits 24
+#define kTopValue ((UInt32)1 << kNumTopBits)
+
+#define kNumBitModelTotalBits 11
+#define kBitModelTotal (1 << kNumBitModelTotalBits)
+#define kNumMoveBits 5
+#define kProbInitValue (kBitModelTotal >> 1)
+
+#define kNumMoveReducingBits 4
+#define kNumBitPriceShiftBits 4
+#define kBitPrice (1 << kNumBitPriceShiftBits)
+
+void LzmaEncProps_Init(CLzmaEncProps *p)
+{
+ p->level = 5;
+ p->dictSize = p->mc = 0;
+ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
+ p->writeEndMark = 0;
+}
+
+void LzmaEncProps_Normalize(CLzmaEncProps *p)
+{
+ int level = p->level;
+ if (level < 0) level = 5;
+ p->level = level;
+ if (p->dictSize == 0) p->dictSize = (UInt32) ((level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)))); /*MAB casts UInt32 */
+ if (p->lc < 0) p->lc = 3;
+ if (p->lp < 0) p->lp = 0;
+ if (p->pb < 0) p->pb = 2;
+ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
+ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
+ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
+ if (p->numHashBytes < 0) p->numHashBytes = 4;
+ if (p->mc == 0) p->mc = (UInt32) ((16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1)); /*MAB casts UInt32 */
+ if (p->numThreads < 0)
+ p->numThreads =
+ #ifdef COMPRESS_MF_MT
+ ((p->btMode && p->algo) ? 2 : 1);
+ #else
+ 1;
+ #endif
+}
+
+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
+{
+ CLzmaEncProps props = *props2;
+ LzmaEncProps_Normalize(&props);
+ return props.dictSize;
+}
+
+/* #define LZMA_LOG_BSR */
+/* Define it for Intel's CPU */
+
+
+#ifdef LZMA_LOG_BSR
+
+#define kDicLogSizeMaxCompress 30
+
+/*MAB: i changed to i__ to avoid possible hiding of a variable */
+#define BSR2_RET(pos, res) { unsigned long i__; _BitScanReverse(&i__, (pos)); res = (i__ + i__) + ((pos >> (i__ - 1)) & 1); }
+
+UInt32 GetPosSlot1(UInt32 pos)
+{
+ UInt32 res;
+ BSR2_RET(pos, res);
+ return res;
+}
+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
+
+#else
+
+#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
+
+/*MAB: static added */
+static
+void LzmaEnc_FastPosInit(Byte *g_FastPos)
+{
+ int c = 2, slotFast;
+ g_FastPos[0] = 0;
+ g_FastPos[1] = 1;
+
+ for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
+ {
+ UInt32 k = (UInt32) ((1 << ((slotFast >> 1) - 1))); /*MAB casts */
+ UInt32 j;
+ for (j = 0; j < k; j++, c++)
+ g_FastPos[c] = (Byte)slotFast;
+ }
+}
+
+/*MAB: i changed to i__ to avoid hiding a variable */
+#define BSR2_RET(pos, res) { UInt32 i__ = 6 + ((kNumLogBits - 1) & \
+ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
+ res = p->g_FastPos[pos >> i__] + (i__ * 2); }
+
+/*
+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
+ p->g_FastPos[pos >> 6] + 12 : \
+ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
+*/
+
+#define GetPosSlot1(pos) p->g_FastPos[pos]
+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
+
+#endif
+
+
+#define LZMA_NUM_REPS 4
+
+typedef unsigned CState;
+
+typedef struct _COptimal
+{
+ UInt32 price;
+
+ CState state;
+ int prev1IsChar;
+ int prev2;
+
+ UInt32 posPrev2;
+ UInt32 backPrev2;
+
+ UInt32 posPrev;
+ UInt32 backPrev;
+ UInt32 backs[LZMA_NUM_REPS];
+} COptimal;
+
+#define kNumOpts (1 << 12)
+
+#define kNumLenToPosStates 4
+#define kNumPosSlotBits 6
+#define kDicLogSizeMin 0
+#define kDicLogSizeMax 32
+#define kDistTableSizeMax (kDicLogSizeMax * 2)
+
+
+#define kNumAlignBits 4
+#define kAlignTableSize (1 << kNumAlignBits)
+#define kAlignMask (kAlignTableSize - 1)
+
+#define kStartPosModelIndex 4
+#define kEndPosModelIndex 14
+#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
+
+#define kNumFullDistances (1 << (kEndPosModelIndex / 2))
+
+#ifdef _LZMA_PROB32
+#define CLzmaProb UInt32
+#else
+#define CLzmaProb UInt16
+#endif
+
+#define LZMA_PB_MAX 4
+#define LZMA_LC_MAX 8
+#define LZMA_LP_MAX 4
+
+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
+
+
+#define kLenNumLowBits 3
+#define kLenNumLowSymbols (1 << kLenNumLowBits)
+#define kLenNumMidBits 3
+#define kLenNumMidSymbols (1 << kLenNumMidBits)
+#define kLenNumHighBits 8
+#define kLenNumHighSymbols (1 << kLenNumHighBits)
+
+#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
+
+#define LZMA_MATCH_LEN_MIN 2
+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
+
+#define kNumStates 12
+
+typedef struct CLenEnc
+{
+ CLzmaProb choice;
+ CLzmaProb choice2;
+ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
+ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
+ CLzmaProb high[kLenNumHighSymbols];
+} CLenEnc;
+
+typedef struct CLenPriceEnc
+{
+ CLenEnc p;
+ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
+ UInt32 tableSize;
+ UInt32 counters[LZMA_NUM_PB_STATES_MAX];
+} CLenPriceEnc;
+
+typedef struct _CRangeEnc
+{
+ UInt32 range;
+ Byte cache;
+ UInt64 low;
+ UInt64 cacheSize;
+ Byte *buf;
+ Byte *bufLim;
+ Byte *bufBase;
+ ISeqOutStream *outStream;
+ UInt64 processed;
+ SRes res;
+} CRangeEnc;
+
+typedef struct _CSeqInStreamBuf
+{
+ ISeqInStream funcTable;
+ const Byte *data;
+ SizeT rem;
+} CSeqInStreamBuf;
+
+static SRes MyRead(void *pp, void *data, size_t *size)
+{
+ size_t curSize = *size;
+ CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp;
+ if (p->rem < curSize)
+ curSize = p->rem;
+ memcpy(data, p->data, curSize);
+ p->rem -= curSize;
+ p->data += curSize;
+ *size = curSize;
+ return SZ_OK;
+}
+
+typedef struct CSaveState
+{
+ CLzmaProb *litProbs;
+
+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
+ CLzmaProb isRep[kNumStates];
+ CLzmaProb isRepG0[kNumStates];
+ CLzmaProb isRepG1[kNumStates];
+ CLzmaProb isRepG2[kNumStates];
+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
+
+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
+
+ CLenPriceEnc lenEnc;
+ CLenPriceEnc repLenEnc;
+
+ UInt32 reps[LZMA_NUM_REPS];
+ UInt32 state;
+} CSaveState;
+
+typedef struct _CLzmaEnc
+{
+ IMatchFinder matchFinder;
+ void *matchFinderObj;
+
+ #ifdef COMPRESS_MF_MT
+ Bool mtMode;
+ CMatchFinderMt matchFinderMt;
+ #endif
+
+ CMatchFinder matchFinderBase;
+
+ #ifdef COMPRESS_MF_MT
+ Byte pad[128];
+ #endif
+
+ UInt32 optimumEndIndex;
+ UInt32 optimumCurrentIndex;
+
+ UInt32 longestMatchLength;
+ UInt32 numPairs;
+ UInt32 numAvail;
+ COptimal opt[kNumOpts];
+
+ #ifndef LZMA_LOG_BSR
+ Byte g_FastPos[1 << kNumLogBits];
+ #endif
+
+ UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
+ UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
+ UInt32 numFastBytes;
+ UInt32 additionalOffset;
+ UInt32 reps[LZMA_NUM_REPS];
+ UInt32 state;
+
+ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
+ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
+ UInt32 alignPrices[kAlignTableSize];
+ UInt32 alignPriceCount;
+
+ UInt32 distTableSize;
+
+ unsigned lc, lp, pb;
+ unsigned lpMask, pbMask;
+
+ CLzmaProb *litProbs;
+
+ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
+ CLzmaProb isRep[kNumStates];
+ CLzmaProb isRepG0[kNumStates];
+ CLzmaProb isRepG1[kNumStates];
+ CLzmaProb isRepG2[kNumStates];
+ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
+
+ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
+ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
+ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
+
+ CLenPriceEnc lenEnc;
+ CLenPriceEnc repLenEnc;
+
+ unsigned lclp;
+
+ Bool fastMode;
+
+ CRangeEnc rc;
+
+ Bool writeEndMark;
+ UInt64 nowPos64;
+ UInt32 matchPriceCount;
+ Bool finished;
+ Bool multiThread;
+
+ SRes result;
+ UInt32 dictSize;
+ UInt32 matchFinderCycles;
+
+ ISeqInStream *inStream;
+ CSeqInStreamBuf seqBufInStream;
+
+ CSaveState saveState;
+} CLzmaEnc;
+
+
+#if defined(USE_UNUSED_CODE)
+/*MAB: static added */
+static
+void LzmaEnc_SaveState(CLzmaEncHandle pp)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ CSaveState *dest = &p->saveState;
+ int i;
+ dest->lenEnc = p->lenEnc;
+ dest->repLenEnc = p->repLenEnc;
+ dest->state = p->state;
+
+ for (i = 0; i < kNumStates; i++)
+ {
+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
+ }
+ for (i = 0; i < kNumLenToPosStates; i++)
+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
+ memcpy(dest->reps, p->reps, sizeof(p->reps));
+ memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
+}
+
+/*MAB: static added */
+static void LzmaEnc_RestoreState(CLzmaEncHandle pp)
+{
+ CLzmaEnc *dest = (CLzmaEnc *)pp;
+ const CSaveState *p = &dest->saveState;
+ int i;
+ dest->lenEnc = p->lenEnc;
+ dest->repLenEnc = p->repLenEnc;
+ dest->state = p->state;
+
+ for (i = 0; i < kNumStates; i++)
+ {
+ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
+ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
+ }
+ for (i = 0; i < kNumLenToPosStates; i++)
+ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
+ memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
+ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
+ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
+ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
+ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
+ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
+ memcpy(dest->reps, p->reps, sizeof(p->reps));
+ memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
+}
+#endif
+
+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ CLzmaEncProps props = *props2;
+ LzmaEncProps_Normalize(&props);
+
+ if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
+ props.dictSize > (1u << kDicLogSizeMaxCompress) || props.dictSize > (1u << 30)) /*MAB: 1u to silence warnings */
+ return SZ_ERROR_PARAM;
+ p->dictSize = props.dictSize;
+ p->matchFinderCycles = props.mc;
+ {
+ unsigned fb = (unsigned) props.fb; /*MAB casts */
+ if (fb < 5)
+ fb = 5;
+ if (fb > LZMA_MATCH_LEN_MAX)
+ fb = LZMA_MATCH_LEN_MAX;
+ p->numFastBytes = fb;
+ }
+ p->lc = (unsigned) props.lc;
+ p->lp = (unsigned) props.lp;
+ p->pb = (unsigned) props.pb;
+ p->fastMode = (props.algo == 0);
+ p->matchFinderBase.btMode = props.btMode;
+ {
+ UInt32 numHashBytes = 4;
+ if (props.btMode)
+ {
+ if (props.numHashBytes < 2)
+ numHashBytes = 2;
+ else if (props.numHashBytes < 4)
+ numHashBytes = (UInt32) props.numHashBytes; /*MAB casts */
+ }
+ p->matchFinderBase.numHashBytes = numHashBytes;
+ }
+
+ p->matchFinderBase.cutValue = props.mc;
+
+ p->writeEndMark = (Bool) props.writeEndMark; /*MAB casts */
+
+ #ifdef COMPRESS_MF_MT
+ /*
+ if (newMultiThread != _multiThread)
+ {
+ ReleaseMatchFinder();
+ _multiThread = newMultiThread;
+ }
+ */
+ p->multiThread = (props.numThreads > 1);
+ #endif
+
+ return SZ_OK;
+}
+
+static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
+static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
+static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
+static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
+
+#define IsCharState(s) ((s) < 7)
+
+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
+
+#define kInfinityPrice (1 << 30)
+
+static void RangeEnc_Construct(CRangeEnc *p)
+{
+ p->outStream = 0;
+ p->bufBase = 0;
+}
+
+#define RangeEnc_GetProcessed(p) ((p)->processed + (UInt64) ((p)->buf - (p)->bufBase) + (p)->cacheSize) /*MAB casts */
+
+#define RC_BUF_SIZE (1 << 16)
+static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
+{
+ if (p->bufBase == 0)
+ {
+ p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
+ if (p->bufBase == 0)
+ return 0;
+ p->bufLim = p->bufBase + RC_BUF_SIZE;
+ }
+ return 1;
+}
+
+static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->bufBase);
+ p->bufBase = 0;
+}
+
+static void RangeEnc_Init(CRangeEnc *p)
+{
+ /* Stream.Init(); */
+ p->low = 0;
+ p->range = 0xFFFFFFFF;
+ p->cacheSize = 1;
+ p->cache = 0;
+
+ p->buf = p->bufBase;
+
+ p->processed = 0;
+ p->res = SZ_OK;
+}
+
+static void RangeEnc_FlushStream(CRangeEnc *p)
+{
+ size_t num;
+ if (p->res != SZ_OK)
+ return;
+ num = (size_t)(p->buf - p->bufBase); /*MAB casts */
+ if (num != p->outStream->Write(p->outStream, p->bufBase, num))
+ p->res = SZ_ERROR_WRITE;
+ p->processed += num;
+ p->buf = p->bufBase;
+}
+
+static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
+{
+ if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
+ {
+ Byte temp = p->cache;
+ do
+ {
+ Byte *buf = p->buf;
+ *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
+ p->buf = buf;
+ if (buf == p->bufLim)
+ RangeEnc_FlushStream(p);
+ temp = 0xFF;
+ }
+ while (--p->cacheSize != 0);
+ p->cache = (Byte)((UInt32)p->low >> 24);
+ }
+ p->cacheSize++;
+ p->low = (UInt32)p->low << 8;
+}
+
+static void RangeEnc_FlushData(CRangeEnc *p)
+{
+ int i;
+ for (i = 0; i < 5; i++)
+ RangeEnc_ShiftLow(p);
+}
+
+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
+{
+ do
+ {
+ p->range >>= 1;
+ p->low += p->range & (0 - ((value >> --numBits) & 1));
+ if (p->range < kTopValue)
+ {
+ p->range <<= 8;
+ RangeEnc_ShiftLow(p);
+ }
+ }
+ while (numBits != 0);
+}
+
+static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
+{
+ UInt32 ttt = *prob;
+ UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
+ if (symbol == 0)
+ {
+ p->range = newBound;
+ ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
+ }
+ else
+ {
+ p->low += newBound;
+ p->range -= newBound;
+ ttt -= ttt >> kNumMoveBits;
+ }
+ *prob = (CLzmaProb)ttt;
+ if (p->range < kTopValue)
+ {
+ p->range <<= 8;
+ RangeEnc_ShiftLow(p);
+ }
+}
+
+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
+{
+ symbol |= 0x100;
+ do
+ {
+ RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
+ symbol <<= 1;
+ }
+ while (symbol < 0x10000);
+}
+
+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
+{
+ UInt32 offs = 0x100;
+ symbol |= 0x100;
+ do
+ {
+ matchByte <<= 1;
+ RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
+ symbol <<= 1;
+ offs &= ~(matchByte ^ symbol);
+ }
+ while (symbol < 0x10000);
+}
+
+/*MAB: static added */
+static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
+{
+ UInt32 i;
+ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
+ {
+ const int kCyclesBits = kNumBitPriceShiftBits;
+ UInt32 w = i;
+ UInt32 bitCount = 0;
+ int j;
+ for (j = 0; j < kCyclesBits; j++)
+ {
+ w = w * w;
+ bitCount <<= 1;
+ while (w >= ((UInt32)1 << 16))
+ {
+ w >>= 1;
+ bitCount++;
+ }
+ }
+ ProbPrices[i >> kNumMoveReducingBits] = (/*MAB: cast to silence*/(UInt32)(kNumBitModelTotalBits << kCyclesBits) - /*MAB: cast to silence*/(UInt32)15 - bitCount);
+ }
+}
+
+
+#define GET_PRICE(prob, symbol) \
+ p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
+
+#define GET_PRICEa(prob, symbol) \
+ ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
+
+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
+
+#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
+#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
+
+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
+{
+ UInt32 price = 0;
+ symbol |= 0x100;
+ do
+ {
+ price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
+ symbol <<= 1;
+ }
+ while (symbol < 0x10000);
+ return price;
+}
+
+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
+{
+ UInt32 price = 0;
+ UInt32 offs = 0x100;
+ symbol |= 0x100;
+ do
+ {
+ matchByte <<= 1;
+ price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);
+ symbol <<= 1;
+ offs &= ~(matchByte ^ symbol);
+ }
+ while (symbol < 0x10000);
+ return price;
+}
+
+
+static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
+{
+ UInt32 m = 1;
+ int i;
+ for (i = numBitLevels; i != 0;)
+ {
+ UInt32 bit;
+ i--;
+ bit = (symbol >> i) & 1;
+ RangeEnc_EncodeBit(rc, probs + m, bit);
+ m = (m << 1) | bit;
+ }
+}
+
+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
+{
+ UInt32 m = 1;
+ int i;
+ for (i = 0; i < numBitLevels; i++)
+ {
+ UInt32 bit = symbol & 1;
+ RangeEnc_EncodeBit(rc, probs + m, bit);
+ m = (m << 1) | bit;
+ symbol >>= 1;
+ }
+}
+
+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
+{
+ UInt32 price = 0;
+ symbol |= (1u << numBitLevels); /*MAB 1u */
+ while (symbol != 1)
+ {
+ price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
+ symbol >>= 1;
+ }
+ return price;
+}
+
+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
+{
+ UInt32 price = 0;
+ UInt32 m = 1;
+ int i;
+ for (i = numBitLevels; i != 0; i--)
+ {
+ UInt32 bit = symbol & 1;
+ symbol >>= 1;
+ price += GET_PRICEa(probs[m], bit);
+ m = (m << 1) | bit;
+ }
+ return price;
+}
+
+
+static void LenEnc_Init(CLenEnc *p)
+{
+ unsigned i;
+ p->choice = p->choice2 = kProbInitValue;
+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
+ p->low[i] = kProbInitValue;
+ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
+ p->mid[i] = kProbInitValue;
+ for (i = 0; i < kLenNumHighSymbols; i++)
+ p->high[i] = kProbInitValue;
+}
+
+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
+{
+ if (symbol < kLenNumLowSymbols)
+ {
+ RangeEnc_EncodeBit(rc, &p->choice, 0);
+ RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
+ }
+ else
+ {
+ RangeEnc_EncodeBit(rc, &p->choice, 1);
+ if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
+ {
+ RangeEnc_EncodeBit(rc, &p->choice2, 0);
+ RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
+ }
+ else
+ {
+ RangeEnc_EncodeBit(rc, &p->choice2, 1);
+ RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
+ }
+ }
+}
+
+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
+{
+ UInt32 a0 = GET_PRICE_0a(p->choice);
+ UInt32 a1 = GET_PRICE_1a(p->choice);
+ UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
+ UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
+ UInt32 i = 0;
+ for (i = 0; i < kLenNumLowSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
+ }
+ for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
+ {
+ if (i >= numSymbols)
+ return;
+ prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
+ }
+ for (; i < numSymbols; i++)
+ prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
+}
+
+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
+{
+ LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
+ p->counters[posState] = p->tableSize;
+}
+
+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
+{
+ UInt32 posState;
+ for (posState = 0; posState < numPosStates; posState++)
+ LenPriceEnc_UpdateTable(p, posState, ProbPrices);
+}
+
+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
+{
+ LenEnc_Encode(&p->p, rc, symbol, posState);
+ if (updatePrice)
+ if (--p->counters[posState] == 0)
+ LenPriceEnc_UpdateTable(p, posState, ProbPrices);
+}
+
+
+
+
+static void MovePos(CLzmaEnc *p, UInt32 num)
+{
+ #ifdef SHOW_STAT
+ ttt += num;
+ printf("\n MovePos %d", num);
+ #endif
+ if (num != 0)
+ {
+ p->additionalOffset += num;
+ p->matchFinder.Skip(p->matchFinderObj, num);
+ }
+}
+
+static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
+{
+ UInt32 lenRes = 0, numPairs;
+ p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+ numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
+ #ifdef SHOW_STAT
+ printf("\n i = %d numPairs = %d ", ttt, numPairs / 2);
+ ttt++;
+ {
+ UInt32 i;
+ for (i = 0; i < numPairs; i += 2)
+ printf("%2d %6d | ", p->matches[i], p->matches[i + 1]);
+ }
+ #endif
+ if (numPairs > 0)
+ {
+ lenRes = p->matches[numPairs - 2];
+ if (lenRes == p->numFastBytes)
+ {
+ const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ UInt32 distance = p->matches[numPairs - 1] + 1;
+ UInt32 numAvail = p->numAvail;
+ if (numAvail > LZMA_MATCH_LEN_MAX)
+ numAvail = LZMA_MATCH_LEN_MAX;
+ {
+ const Byte *pby2 = pby - distance;
+ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
+ }
+ }
+ }
+ p->additionalOffset++;
+ *numDistancePairsRes = numPairs;
+ return lenRes;
+}
+
+
+#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
+#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
+#define IsShortRep(p) ((p)->backPrev == 0)
+
+static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
+{
+ return
+ GET_PRICE_0(p->isRepG0[state]) +
+ GET_PRICE_0(p->isRep0Long[state][posState]);
+}
+
+static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
+{
+ UInt32 price;
+ if (repIndex == 0)
+ {
+ price = GET_PRICE_0(p->isRepG0[state]);
+ price += GET_PRICE_1(p->isRep0Long[state][posState]);
+ }
+ else
+ {
+ price = GET_PRICE_1(p->isRepG0[state]);
+ if (repIndex == 1)
+ price += GET_PRICE_0(p->isRepG1[state]);
+ else
+ {
+ price += GET_PRICE_1(p->isRepG1[state]);
+ price += GET_PRICE(p->isRepG2[state], repIndex - 2);
+ }
+ }
+ return price;
+}
+
+static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
+{
+ return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
+ GetPureRepPrice(p, repIndex, state, posState);
+}
+
+static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
+{
+ UInt32 posMem = p->opt[cur].posPrev;
+ UInt32 backMem = p->opt[cur].backPrev;
+ p->optimumEndIndex = cur;
+ do
+ {
+ if (p->opt[cur].prev1IsChar)
+ {
+ MakeAsChar(&p->opt[posMem])
+ p->opt[posMem].posPrev = posMem - 1;
+ if (p->opt[cur].prev2)
+ {
+ p->opt[posMem - 1].prev1IsChar = False;
+ p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
+ p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
+ }
+ }
+ {
+ UInt32 posPrev = posMem;
+ UInt32 backCur = backMem;
+
+ backMem = p->opt[posPrev].backPrev;
+ posMem = p->opt[posPrev].posPrev;
+
+ p->opt[posPrev].backPrev = backCur;
+ p->opt[posPrev].posPrev = cur;
+ cur = posPrev;
+ }
+ }
+ while (cur != 0);
+ *backRes = p->opt[0].backPrev;
+ p->optimumCurrentIndex = p->opt[0].posPrev;
+ return p->optimumCurrentIndex;
+}
+
+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + (UInt32) ((prevByte) >> (8 - p->lc))) * 0x300) /*MAB cast UInt32 */
+
+static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
+{
+ UInt32 numAvail, mainLen, repMaxIndex, i, lenEnd, len, cur;
+ /*MAB: Changed numPairs_, posState_ avoid hiding a variable later */
+ UInt32 numPairs_, posState_;
+ /*MAB: Changed matchPrice_, repMatchPrice_ avoid hiding a variable later */
+ UInt32 matchPrice_, repMatchPrice_,
+ normalMatchPrice;
+ UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
+ UInt32 *matches;
+ /*MAB: Changed from data to avoid hiding a variable later */
+ const Byte *data_;
+ /*MAB: Changed from matchByte to avoid hiding a variable later */
+ Byte curByte_, matchByte_;
+ if (p->optimumEndIndex != p->optimumCurrentIndex)
+ {
+ const COptimal *opt = &p->opt[p->optimumCurrentIndex];
+ UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
+ *backRes = opt->backPrev;
+ p->optimumCurrentIndex = opt->posPrev;
+ return lenRes;
+ }
+ p->optimumCurrentIndex = p->optimumEndIndex = 0;
+
+ if (p->additionalOffset == 0)
+ mainLen = ReadMatchDistances(p, &numPairs_);
+ else
+ {
+ mainLen = p->longestMatchLength;
+ numPairs_ = p->numPairs;
+ }
+
+ numAvail = p->numAvail;
+ if (numAvail < 2)
+ {
+ *backRes = (UInt32)(-1);
+ return 1;
+ }
+ if (numAvail > LZMA_MATCH_LEN_MAX)
+ numAvail = LZMA_MATCH_LEN_MAX;
+
+ data_ = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ repMaxIndex = 0;
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ UInt32 lenTest;
+ const Byte *data2;
+ reps[i] = p->reps[i];
+ data2 = data_ - (reps[i] + 1);
+ if (data_[0] != data2[0] || data_[1] != data2[1])
+ {
+ repLens[i] = 0;
+ continue;
+ }
+ for (lenTest = 2; lenTest < numAvail && data_[lenTest] == data2[lenTest]; lenTest++);
+ repLens[i] = lenTest;
+ if (lenTest > repLens[repMaxIndex])
+ repMaxIndex = i;
+ }
+ if (repLens[repMaxIndex] >= p->numFastBytes)
+ {
+ UInt32 lenRes;
+ *backRes = repMaxIndex;
+ lenRes = repLens[repMaxIndex];
+ MovePos(p, lenRes - 1);
+ return lenRes;
+ }
+
+ matches = p->matches;
+ if (mainLen >= p->numFastBytes)
+ {
+ *backRes = matches[numPairs_ - 1] + LZMA_NUM_REPS;
+ MovePos(p, mainLen - 1);
+ return mainLen;
+ }
+ curByte_ = *data_;
+ matchByte_ = *(data_ - (reps[0] + 1));
+
+ if (mainLen < 2 && curByte_ != matchByte_ && repLens[repMaxIndex] < 2)
+ {
+ *backRes = (UInt32)-1;
+ return 1;
+ }
+
+ p->opt[0].state = (CState)p->state;
+
+ posState_ = (position & p->pbMask);
+
+ {
+ const CLzmaProb *probs = LIT_PROBS(position, *(data_ - 1));
+ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState_]) +
+ (!IsCharState(p->state) ?
+ LitEnc_GetPriceMatched(probs, curByte_, matchByte_, p->ProbPrices) :
+ LitEnc_GetPrice(probs, curByte_, p->ProbPrices));
+ }
+
+ MakeAsChar(&p->opt[1]);
+
+ matchPrice_ = GET_PRICE_1(p->isMatch[p->state][posState_]);
+ repMatchPrice_ = matchPrice_ + GET_PRICE_1(p->isRep[p->state]);
+
+ if (matchByte_ == curByte_)
+ {
+ UInt32 shortRepPrice = repMatchPrice_ + GetRepLen1Price(p, p->state, posState_);
+ if (shortRepPrice < p->opt[1].price)
+ {
+ p->opt[1].price = shortRepPrice;
+ MakeAsShortRep(&p->opt[1]);
+ }
+ }
+ lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]);
+
+ if (lenEnd < 2)
+ {
+ *backRes = p->opt[1].backPrev;
+ return 1;
+ }
+
+ p->opt[1].posPrev = 0;
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ p->opt[0].backs[i] = reps[i];
+
+ len = lenEnd;
+ do
+ p->opt[len--].price = kInfinityPrice;
+ while (len >= 2);
+
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ UInt32 repLen = repLens[i];
+ UInt32 price;
+ if (repLen < 2)
+ continue;
+ price = repMatchPrice_ + GetPureRepPrice(p, i, p->state, posState_);
+ do
+ {
+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState_][repLen - 2];
+ COptimal *opt = &p->opt[repLen];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = 0;
+ opt->backPrev = i;
+ opt->prev1IsChar = False;
+ }
+ }
+ while (--repLen >= 2);
+ }
+
+ normalMatchPrice = matchPrice_ + GET_PRICE_0(p->isRep[p->state]);
+
+ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
+ if (len <= mainLen)
+ {
+ UInt32 offs = 0;
+ while (len > matches[offs])
+ offs += 2;
+ for (; ; len++)
+ {
+ COptimal *opt;
+ UInt32 distance = matches[offs + 1];
+
+ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState_][len - LZMA_MATCH_LEN_MIN];
+ UInt32 lenToPosState = GetLenToPosState(len);
+ if (distance < kNumFullDistances)
+ curAndLenPrice += p->distancesPrices[lenToPosState][distance];
+ else
+ {
+ UInt32 slot;
+ GetPosSlot2(distance, slot);
+ curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
+ }
+ opt = &p->opt[len];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = 0;
+ opt->backPrev = distance + LZMA_NUM_REPS;
+ opt->prev1IsChar = False;
+ }
+ if (len == matches[offs])
+ {
+ offs += 2;
+ if (offs == numPairs_)
+ break;
+ }
+ }
+ }
+
+ cur = 0;
+
+ #ifdef SHOW_STAT2
+ if (position >= 0)
+ {
+ unsigned i__;
+ printf("\n pos = %4X", position);
+ for (i__ = cur; i__ <= lenEnd; i__++)
+ printf("\nprice[%4X] = %d", position - cur + i__, p->opt[i__].price);
+ }
+ #endif
+
+ for (;;)
+ {
+ UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
+ UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
+ Bool nextIsChar;
+ Byte curByte, matchByte;
+ const Byte *data;
+ COptimal *curOpt;
+ COptimal *nextOpt;
+
+ cur++;
+ if (cur == lenEnd)
+ return Backward(p, backRes, cur);
+
+ newLen = ReadMatchDistances(p, &numPairs);
+ if (newLen >= p->numFastBytes)
+ {
+ p->numPairs = numPairs;
+ p->longestMatchLength = newLen;
+ return Backward(p, backRes, cur);
+ }
+ position++;
+ curOpt = &p->opt[cur];
+ posPrev = curOpt->posPrev;
+ if (curOpt->prev1IsChar)
+ {
+ posPrev--;
+ if (curOpt->prev2)
+ {
+ state = p->opt[curOpt->posPrev2].state;
+ if (curOpt->backPrev2 < LZMA_NUM_REPS)
+ state = (UInt32) kRepNextStates[state]; /*MAB casts */
+ else
+ state = (UInt32) kMatchNextStates[state]; /*MAB casts */
+ }
+ else
+ state = p->opt[posPrev].state;
+ state = (UInt32) kLiteralNextStates[state]; /*MAB casts */
+ }
+ else
+ state = p->opt[posPrev].state;
+ if (posPrev == cur - 1)
+ {
+ if (IsShortRep(curOpt))
+ state = (UInt32) kShortRepNextStates[state]; /*MAB casts */
+ else
+ state = (UInt32) kLiteralNextStates[state]; /*MAB casts */
+ }
+ else
+ {
+ UInt32 pos;
+ const COptimal *prevOpt;
+ if (curOpt->prev1IsChar && curOpt->prev2)
+ {
+ posPrev = curOpt->posPrev2;
+ pos = curOpt->backPrev2;
+ state = (UInt32) kRepNextStates[state]; /*MAB casts */
+ }
+ else
+ {
+ pos = curOpt->backPrev;
+ if (pos < LZMA_NUM_REPS)
+ state = (UInt32) kRepNextStates[state]; /*MAB casts */
+ else
+ state = (UInt32) kMatchNextStates[state]; /*MAB casts */
+ }
+ prevOpt = &p->opt[posPrev];
+ if (pos < LZMA_NUM_REPS)
+ {
+ /*MAB: i changed to i__ to avoid hiding a variable */
+ UInt32 i__;
+ reps[0] = prevOpt->backs[pos];
+ for (i__ = 1; i__ <= pos; i__++)
+ reps[i__] = prevOpt->backs[i__ - 1];
+ for (; i__ < LZMA_NUM_REPS; i__++)
+ reps[i__] = prevOpt->backs[i__];
+ }
+ else
+ {
+ /*MAB: i changed to i__ to avoid hiding a variable */
+ UInt32 i__;
+ reps[0] = (pos - LZMA_NUM_REPS);
+ for (i__ = 1; i__ < LZMA_NUM_REPS; i__++)
+ reps[i__] = prevOpt->backs[i__ - 1];
+ }
+ }
+ curOpt->state = (CState)state;
+
+ curOpt->backs[0] = reps[0];
+ curOpt->backs[1] = reps[1];
+ curOpt->backs[2] = reps[2];
+ curOpt->backs[3] = reps[3];
+
+ curPrice = curOpt->price;
+ nextIsChar = False;
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ curByte = *data;
+ matchByte = *(data - (reps[0] + 1));
+
+ posState = (position & p->pbMask);
+
+ curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
+ {
+ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
+ curAnd1Price +=
+ (!IsCharState(state) ?
+ LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
+ LitEnc_GetPrice(probs, curByte, p->ProbPrices));
+ }
+
+ nextOpt = &p->opt[cur + 1];
+
+ if (curAnd1Price < nextOpt->price)
+ {
+ nextOpt->price = curAnd1Price;
+ nextOpt->posPrev = cur;
+ MakeAsChar(nextOpt);
+ nextIsChar = True;
+ }
+
+ matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
+ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
+
+ if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
+ {
+ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
+ if (shortRepPrice <= nextOpt->price)
+ {
+ nextOpt->price = shortRepPrice;
+ nextOpt->posPrev = cur;
+ MakeAsShortRep(nextOpt);
+ nextIsChar = True;
+ }
+ }
+ numAvailFull = p->numAvail;
+ {
+ UInt32 temp = kNumOpts - 1 - cur;
+ if (temp < numAvailFull)
+ numAvailFull = temp;
+ }
+
+ if (numAvailFull < 2)
+ continue;
+ numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
+
+ if (!nextIsChar && matchByte != curByte) /* speed optimization */
+ {
+ /* try Literal + rep0 */
+ UInt32 temp;
+ UInt32 lenTest2;
+ const Byte *data2 = data - (reps[0] + 1);
+ UInt32 limit = p->numFastBytes + 1;
+ if (limit > numAvailFull)
+ limit = numAvailFull;
+
+ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
+ lenTest2 = temp - 1;
+ if (lenTest2 >= 2)
+ {
+ UInt32 state2 = (UInt32) kLiteralNextStates[state]; /*MAB casts */
+ UInt32 posStateNext = (position + 1) & p->pbMask;
+ UInt32 nextRepMatchPrice = curAnd1Price +
+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
+ GET_PRICE_1(p->isRep[state2]);
+ /* for (; lenTest2 >= 2; lenTest2--) */
+ {
+ UInt32 curAndLenPrice;
+ COptimal *opt;
+ UInt32 offset = cur + 1 + lenTest2;
+ while (lenEnd < offset)
+ p->opt[++lenEnd].price = kInfinityPrice;
+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+ opt = &p->opt[offset];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = cur + 1;
+ opt->backPrev = 0;
+ opt->prev1IsChar = True;
+ opt->prev2 = False;
+ }
+ }
+ }
+ }
+
+ startLen = 2; /* speed optimization */
+ {
+ UInt32 repIndex;
+ for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
+ {
+ UInt32 lenTest;
+ UInt32 lenTestTemp;
+ UInt32 price;
+ const Byte *data2 = data - (reps[repIndex] + 1);
+ if (data[0] != data2[0] || data[1] != data2[1])
+ continue;
+ for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
+ while (lenEnd < cur + lenTest)
+ p->opt[++lenEnd].price = kInfinityPrice;
+ lenTestTemp = lenTest;
+ price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
+ do
+ {
+ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
+ COptimal *opt = &p->opt[cur + lenTest];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = cur;
+ opt->backPrev = repIndex;
+ opt->prev1IsChar = False;
+ }
+ }
+ while (--lenTest >= 2);
+ lenTest = lenTestTemp;
+
+ if (repIndex == 0)
+ startLen = lenTest + 1;
+
+ /* if (_maxMode) */
+ {
+ UInt32 lenTest2 = lenTest + 1;
+ UInt32 limit = lenTest2 + p->numFastBytes;
+ UInt32 nextRepMatchPrice;
+ if (limit > numAvailFull)
+ limit = numAvailFull;
+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
+ lenTest2 -= lenTest + 1;
+ if (lenTest2 >= 2)
+ {
+ UInt32 state2 = (UInt32) kRepNextStates[state]; /*MAB casts */
+ UInt32 posStateNext = (position + lenTest) & p->pbMask;
+ UInt32 curAndLenCharPrice =
+ price + p->repLenEnc.prices[posState][lenTest - 2] +
+ GET_PRICE_0(p->isMatch[state2][posStateNext]) +
+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
+ data[lenTest], data2[lenTest], p->ProbPrices);
+ state2 = (UInt32) kLiteralNextStates[state2]; /*MAB casts */
+ posStateNext = (position + lenTest + 1) & p->pbMask;
+ nextRepMatchPrice = curAndLenCharPrice +
+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
+ GET_PRICE_1(p->isRep[state2]);
+
+ /* for (; lenTest2 >= 2; lenTest2--) */
+ {
+ UInt32 curAndLenPrice;
+ COptimal *opt;
+ UInt32 offset = cur + lenTest + 1 + lenTest2;
+ while (lenEnd < offset)
+ p->opt[++lenEnd].price = kInfinityPrice;
+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+ opt = &p->opt[offset];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = cur + lenTest + 1;
+ opt->backPrev = 0;
+ opt->prev1IsChar = True;
+ opt->prev2 = True;
+ opt->posPrev2 = cur;
+ opt->backPrev2 = repIndex;
+ }
+ }
+ }
+ }
+ }
+ }
+ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
+ if (newLen > numAvail)
+ {
+ newLen = numAvail;
+ for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2);
+ matches[numPairs] = newLen;
+ numPairs += 2;
+ }
+ if (newLen >= startLen)
+ {
+ /*MAB: normalMatchPrice changed to normalMatchPrice__ not to hide a variable later */
+ UInt32 normalMatchPrice__ = matchPrice + GET_PRICE_0(p->isRep[state]);
+ UInt32 offs, curBack, posSlot;
+ UInt32 lenTest;
+ while (lenEnd < cur + newLen)
+ p->opt[++lenEnd].price = kInfinityPrice;
+
+ offs = 0;
+ while (startLen > matches[offs])
+ offs += 2;
+ curBack = matches[offs + 1];
+ GetPosSlot2(curBack, posSlot);
+ for (lenTest = /*2*/ startLen; ; lenTest++)
+ {
+ /*MAB: curAndLenPrice changed to curAndLenPrice__ not to hide a variable later */
+ UInt32 curAndLenPrice__ = normalMatchPrice__ + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
+ UInt32 lenToPosState = GetLenToPosState(lenTest);
+ /*MAB: opt changed to opt__ not to hide a variable later */
+ COptimal *opt__;
+ if (curBack < kNumFullDistances)
+ curAndLenPrice__ += p->distancesPrices[lenToPosState][curBack];
+ else
+ curAndLenPrice__ += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
+
+ opt__ = &p->opt[cur + lenTest];
+ if (curAndLenPrice__ < opt__->price)
+ {
+ opt__->price = curAndLenPrice__;
+ opt__->posPrev = cur;
+ opt__->backPrev = curBack + LZMA_NUM_REPS;
+ opt__->prev1IsChar = False;
+ }
+
+ if (/*_maxMode && */lenTest == matches[offs])
+ {
+ /* Try Match + Literal + Rep0 */
+ const Byte *data2 = data - (curBack + 1);
+ UInt32 lenTest2 = lenTest + 1;
+ UInt32 limit = lenTest2 + p->numFastBytes;
+ UInt32 nextRepMatchPrice;
+ if (limit > numAvailFull)
+ limit = numAvailFull;
+ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
+ lenTest2 -= lenTest + 1;
+ if (lenTest2 >= 2)
+ {
+ UInt32 state2 = (UInt32) kMatchNextStates[state]; /*MAB casts */
+ UInt32 posStateNext = (position + lenTest) & p->pbMask;
+ UInt32 curAndLenCharPrice = curAndLenPrice__ +
+ GET_PRICE_0(p->isMatch[state2][posStateNext]) +
+ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
+ data[lenTest], data2[lenTest], p->ProbPrices);
+ state2 = (UInt32) kLiteralNextStates[state2]; /*MAB casts */
+ posStateNext = (posStateNext + 1) & p->pbMask;
+ nextRepMatchPrice = curAndLenCharPrice +
+ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
+ GET_PRICE_1(p->isRep[state2]);
+
+ /* for (; lenTest2 >= 2; lenTest2--) */
+ {
+ UInt32 offset = cur + lenTest + 1 + lenTest2;
+ UInt32 curAndLenPrice;
+ COptimal *opt;
+ while (lenEnd < offset)
+ p->opt[++lenEnd].price = kInfinityPrice;
+ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
+ opt = &p->opt[offset];
+ if (curAndLenPrice < opt->price)
+ {
+ opt->price = curAndLenPrice;
+ opt->posPrev = cur + lenTest + 1;
+ opt->backPrev = 0;
+ opt->prev1IsChar = True;
+ opt->prev2 = True;
+ opt->posPrev2 = cur;
+ opt->backPrev2 = curBack + LZMA_NUM_REPS;
+ }
+ }
+ }
+ offs += 2;
+ if (offs == numPairs)
+ break;
+ curBack = matches[offs + 1];
+ if (curBack >= kNumFullDistances)
+ GetPosSlot2(curBack, posSlot);
+ }
+ }
+ }
+ }
+}
+
+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
+
+static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
+{
+ UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;
+ const Byte *data;
+ const UInt32 *matches;
+
+ if (p->additionalOffset == 0)
+ mainLen = ReadMatchDistances(p, &numPairs);
+ else
+ {
+ mainLen = p->longestMatchLength;
+ numPairs = p->numPairs;
+ }
+
+ numAvail = p->numAvail;
+ *backRes = (UInt32)-1;
+ if (numAvail < 2)
+ return 1;
+ if (numAvail > LZMA_MATCH_LEN_MAX)
+ numAvail = LZMA_MATCH_LEN_MAX;
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+
+ repLen = repIndex = 0;
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ UInt32 len;
+ const Byte *data2 = data - (p->reps[i] + 1);
+ if (data[0] != data2[0] || data[1] != data2[1])
+ continue;
+ for (len = 2; len < numAvail && data[len] == data2[len]; len++);
+ if (len >= p->numFastBytes)
+ {
+ *backRes = i;
+ MovePos(p, len - 1);
+ return len;
+ }
+ if (len > repLen)
+ {
+ repIndex = i;
+ repLen = len;
+ }
+ }
+
+ matches = p->matches;
+ if (mainLen >= p->numFastBytes)
+ {
+ *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
+ MovePos(p, mainLen - 1);
+ return mainLen;
+ }
+
+ mainDist = 0; /* for GCC */
+ if (mainLen >= 2)
+ {
+ mainDist = matches[numPairs - 1];
+ while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)
+ {
+ if (!ChangePair(matches[numPairs - 3], mainDist))
+ break;
+ numPairs -= 2;
+ mainLen = matches[numPairs - 2];
+ mainDist = matches[numPairs - 1];
+ }
+ if (mainLen == 2 && mainDist >= 0x80)
+ mainLen = 1;
+ }
+
+ if (repLen >= 2 && (
+ (repLen + 1 >= mainLen) ||
+ (repLen + 2 >= mainLen && mainDist >= (1 << 9)) ||
+ (repLen + 3 >= mainLen && mainDist >= (1 << 15))))
+ {
+ *backRes = repIndex;
+ MovePos(p, repLen - 1);
+ return repLen;
+ }
+
+ if (mainLen < 2 || numAvail <= 2)
+ return 1;
+
+ p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
+ if (p->longestMatchLength >= 2)
+ {
+ UInt32 newDistance = matches[p->numPairs - 1];
+ if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
+ (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
+ (p->longestMatchLength > mainLen + 1) ||
+ (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))
+ return 1;
+ }
+
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
+ for (i = 0; i < LZMA_NUM_REPS; i++)
+ {
+ UInt32 len, limit;
+ const Byte *data2 = data - (p->reps[i] + 1);
+ if (data[0] != data2[0] || data[1] != data2[1])
+ continue;
+ limit = mainLen - 1;
+ for (len = 2; len < limit && data[len] == data2[len]; len++);
+ if (len >= limit)
+ return 1;
+ }
+ *backRes = mainDist + LZMA_NUM_REPS;
+ MovePos(p, mainLen - 2);
+ return mainLen;
+}
+
+static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
+{
+ UInt32 len;
+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
+ p->state = (UInt32) kMatchNextStates[p->state]; /*MAB casts */
+ len = LZMA_MATCH_LEN_MIN;
+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
+ RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
+}
+
+static SRes CheckErrors(CLzmaEnc *p)
+{
+ if (p->result != SZ_OK)
+ return p->result;
+ if (p->rc.res != SZ_OK)
+ p->result = SZ_ERROR_WRITE;
+ if (p->matchFinderBase.result != SZ_OK)
+ p->result = SZ_ERROR_READ;
+ if (p->result != SZ_OK)
+ p->finished = True;
+ return p->result;
+}
+
+static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
+{
+ /* ReleaseMFStream(); */
+ p->finished = True;
+ if (p->writeEndMark)
+ WriteEndMarker(p, nowPos & p->pbMask);
+ RangeEnc_FlushData(&p->rc);
+ RangeEnc_FlushStream(&p->rc);
+ return CheckErrors(p);
+}
+
+static void FillAlignPrices(CLzmaEnc *p)
+{
+ UInt32 i;
+ for (i = 0; i < kAlignTableSize; i++)
+ p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
+ p->alignPriceCount = 0;
+}
+
+static void FillDistancesPrices(CLzmaEnc *p)
+{
+ UInt32 tempPrices[kNumFullDistances];
+ /*MAB: i changed to j to avoid warnings later of hiding i */
+ UInt32 j, lenToPosState;
+ for (j = kStartPosModelIndex; j < kNumFullDistances; j++)
+ {
+ UInt32 posSlot = GetPosSlot1(j);
+ UInt32 footerBits = ((posSlot >> 1) - 1);
+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+ tempPrices[j] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, (int)footerBits, j - base, p->ProbPrices); /*MAB casts */
+ }
+
+ for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
+ {
+ UInt32 posSlot;
+ const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
+ UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
+ for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
+ posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
+ for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
+ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
+
+ {
+ UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
+ /*MAB: i changed to i__ to avoid hiding a variable */
+ UInt32 i__;
+ for (i__ = 0; i__ < kStartPosModelIndex; i__++)
+ distancesPrices[i__] = posSlotPrices[i__];
+ for (; i__ < kNumFullDistances; i__++)
+ distancesPrices[i__] = posSlotPrices[GetPosSlot1(i__)] + tempPrices[i__];
+ }
+ }
+ p->matchPriceCount = 0;
+}
+
+/*MAB: static added */
+static void LzmaEnc_Construct(CLzmaEnc *p)
+{
+ RangeEnc_Construct(&p->rc);
+ MatchFinder_Construct(&p->matchFinderBase);
+ #ifdef COMPRESS_MF_MT
+ MatchFinderMt_Construct(&p->matchFinderMt);
+ p->matchFinderMt.MatchFinder = &p->matchFinderBase;
+ #endif
+
+ {
+ CLzmaEncProps props;
+ LzmaEncProps_Init(&props);
+ LzmaEnc_SetProps(p, &props);
+ }
+
+ #ifndef LZMA_LOG_BSR
+ LzmaEnc_FastPosInit(p->g_FastPos);
+ #endif
+
+ LzmaEnc_InitPriceTables(p->ProbPrices);
+ p->litProbs = 0;
+ p->saveState.litProbs = 0;
+}
+
+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
+{
+ void *p;
+ p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
+ if (p != 0)
+ LzmaEnc_Construct((CLzmaEnc *)p);
+ return p;
+}
+
+/*MAB: static added */
+static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
+{
+ alloc->Free(alloc, p->litProbs);
+ alloc->Free(alloc, p->saveState.litProbs);
+ p->litProbs = 0;
+ p->saveState.litProbs = 0;
+}
+
+/*MAB: static added */
+static void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ #ifdef COMPRESS_MF_MT
+ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
+ #endif
+ MatchFinder_Free(&p->matchFinderBase, allocBig);
+ LzmaEnc_FreeLits(p, alloc);
+ RangeEnc_Free(&p->rc, alloc);
+}
+
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
+ alloc->Free(alloc, p);
+}
+
+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
+{
+ UInt32 nowPos32, startPos32;
+ if (p->inStream != 0)
+ {
+ p->matchFinderBase.stream = p->inStream;
+ p->matchFinder.Init(p->matchFinderObj);
+ p->inStream = 0;
+ }
+
+ if (p->finished)
+ return p->result;
+ RINOK(CheckErrors(p));
+
+ nowPos32 = (UInt32)p->nowPos64;
+ startPos32 = nowPos32;
+
+ if (p->nowPos64 == 0)
+ {
+ UInt32 numPairs;
+ Byte curByte;
+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
+ return Flush(p, nowPos32);
+ ReadMatchDistances(p, &numPairs);
+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
+ p->state = (UInt32) kLiteralNextStates[p->state]; /*MAB casts */
+ curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, (Int32)(0 - p->additionalOffset)); /*MAB casts */
+ LitEnc_Encode(&p->rc, p->litProbs, curByte);
+ p->additionalOffset--;
+ nowPos32++;
+ }
+
+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
+ for (;;)
+ {
+ UInt32 pos, len, posState;
+
+ if (p->fastMode)
+ len = GetOptimumFast(p, &pos);
+ else
+ len = GetOptimum(p, nowPos32, &pos);
+
+ #ifdef SHOW_STAT2
+ printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos);
+ #endif
+
+ posState = nowPos32 & p->pbMask;
+ if (len == 1 && pos == (UInt32)-1)
+ {
+ Byte curByte;
+ CLzmaProb *probs;
+ const Byte *data;
+
+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
+ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
+ curByte = *data;
+ probs = LIT_PROBS(nowPos32, *(data - 1));
+ if (IsCharState(p->state))
+ LitEnc_Encode(&p->rc, probs, curByte);
+ else
+ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
+ p->state = (UInt32) kLiteralNextStates[p->state]; /*MAB casts */
+ }
+ else
+ {
+ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
+ if (pos < LZMA_NUM_REPS)
+ {
+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
+ if (pos == 0)
+ {
+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
+ RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
+ }
+ else
+ {
+ UInt32 distance = p->reps[pos];
+ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
+ if (pos == 1)
+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
+ else
+ {
+ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
+ RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
+ if (pos == 3)
+ p->reps[3] = p->reps[2];
+ p->reps[2] = p->reps[1];
+ }
+ p->reps[1] = p->reps[0];
+ p->reps[0] = distance;
+ }
+ if (len == 1)
+ p->state = (UInt32) kShortRepNextStates[p->state]; /*MAB casts */
+ else
+ {
+ LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+ p->state = (UInt32) kRepNextStates[p->state]; /*MAB casts */
+ }
+ }
+ else
+ {
+ UInt32 posSlot;
+ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
+ p->state = (UInt32) kMatchNextStates[p->state]; /*MAB casts */
+ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
+ pos -= LZMA_NUM_REPS;
+ GetPosSlot(pos, posSlot);
+ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
+
+ if (posSlot >= kStartPosModelIndex)
+ {
+ UInt32 footerBits = ((posSlot >> 1) - 1);
+ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
+ UInt32 posReduced = pos - base;
+
+ if (posSlot < kEndPosModelIndex)
+ RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, (int)footerBits, posReduced); /*MAB casts */
+ else
+ {
+ RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, (int)footerBits - kNumAlignBits); /*MAB casts */
+ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
+ p->alignPriceCount++;
+ }
+ }
+ p->reps[3] = p->reps[2];
+ p->reps[2] = p->reps[1];
+ p->reps[1] = p->reps[0];
+ p->reps[0] = pos;
+ p->matchPriceCount++;
+ }
+ }
+ p->additionalOffset -= len;
+ nowPos32 += len;
+ if (p->additionalOffset == 0)
+ {
+ UInt32 processed;
+ if (!p->fastMode)
+ {
+ if (p->matchPriceCount >= (1 << 7))
+ FillDistancesPrices(p);
+ if (p->alignPriceCount >= kAlignTableSize)
+ FillAlignPrices(p);
+ }
+ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
+ break;
+ processed = nowPos32 - startPos32;
+
+ if (useLimits)
+ {
+ if (processed + kNumOpts + 300 >= maxUnpackSize ||
+ RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
+ break;
+ }
+ else if (processed >= (1 << 15))
+ {
+ p->nowPos64 += nowPos32 - startPos32;
+ return CheckErrors(p);
+ }
+ }
+ }
+ p->nowPos64 += nowPos32 - startPos32;
+ return Flush(p, nowPos32);
+}
+
+#define kBigHashDicLimit ((UInt32)1 << 24)
+
+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ UInt32 beforeSize = kNumOpts;
+ #ifdef COMPRESS_MF_MT
+ Bool btMode; /*MAB: this line wrap inside the compilation ifdef, btMode not used without it */
+ #endif
+
+ if (!RangeEnc_Alloc(&p->rc, alloc))
+ return SZ_ERROR_MEM;
+
+ #ifdef COMPRESS_MF_MT
+ btMode = (p->matchFinderBase.btMode != 0); /*MAB: this line moved inside the compilation ifdef, btMode not used without it */
+
+ p->mtMode = (p->multiThread && !p->fastMode && btMode);
+ #endif
+
+ {
+ unsigned lclp = p->lc + p->lp;
+ if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
+ {
+ LzmaEnc_FreeLits(p, alloc);
+ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300u << lclp) * sizeof(CLzmaProb)); /*MAB 0x300 vs 0x300u*/
+ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300u << lclp) * sizeof(CLzmaProb)); /*MAB 0x300 vs 0x300u*/
+ if (p->litProbs == 0 || p->saveState.litProbs == 0)
+ {
+ LzmaEnc_FreeLits(p, alloc);
+ return SZ_ERROR_MEM;
+ }
+ p->lclp = lclp;
+ }
+ }
+
+ p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
+
+ if (beforeSize + p->dictSize < keepWindowSize)
+ beforeSize = keepWindowSize - p->dictSize;
+
+ #ifdef COMPRESS_MF_MT
+ if (p->mtMode)
+ {
+ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
+ p->matchFinderObj = &p->matchFinderMt;
+ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
+ }
+ else
+ #endif
+ {
+ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
+ return SZ_ERROR_MEM;
+ p->matchFinderObj = &p->matchFinderBase;
+ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
+ }
+ return SZ_OK;
+}
+
+/*MAB: static added */
+static void LzmaEnc_Init(CLzmaEnc *p)
+{
+ UInt32 i;
+ p->state = 0;
+ for (i = 0 ; i < LZMA_NUM_REPS; i++)
+ p->reps[i] = 0;
+
+ RangeEnc_Init(&p->rc);
+
+
+ for (i = 0; i < kNumStates; i++)
+ {
+ UInt32 j;
+ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
+ {
+ p->isMatch[i][j] = kProbInitValue;
+ p->isRep0Long[i][j] = kProbInitValue;
+ }
+ p->isRep[i] = kProbInitValue;
+ p->isRepG0[i] = kProbInitValue;
+ p->isRepG1[i] = kProbInitValue;
+ p->isRepG2[i] = kProbInitValue;
+ }
+
+ {
+ UInt32 num = (UInt32) (0x300 << (p->lp + p->lc)); /*MAB casts */
+ for (i = 0; i < num; i++)
+ p->litProbs[i] = kProbInitValue;
+ }
+
+ {
+ for (i = 0; i < kNumLenToPosStates; i++)
+ {
+ CLzmaProb *probs = p->posSlotEncoder[i];
+ UInt32 j;
+ for (j = 0; j < (1 << kNumPosSlotBits); j++)
+ probs[j] = kProbInitValue;
+ }
+ }
+ {
+ for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
+ p->posEncoders[i] = kProbInitValue;
+ }
+
+ LenEnc_Init(&p->lenEnc.p);
+ LenEnc_Init(&p->repLenEnc.p);
+
+ for (i = 0; i < (1 << kNumAlignBits); i++)
+ p->posAlignEncoder[i] = kProbInitValue;
+
+ p->optimumEndIndex = 0;
+ p->optimumCurrentIndex = 0;
+ p->additionalOffset = 0;
+
+ p->pbMask = (1u << p->pb) - 1u; /*MAB 1u */
+ p->lpMask = (1u << p->lp) - 1u; /*MAB 1u */
+}
+
+/*MAB: static added */
+static void LzmaEnc_InitPrices(CLzmaEnc *p)
+{
+ if (!p->fastMode)
+ {
+ FillDistancesPrices(p);
+ FillAlignPrices(p);
+ }
+
+ p->lenEnc.tableSize =
+ p->repLenEnc.tableSize =
+ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
+ LenPriceEnc_UpdateTables(&p->lenEnc, 1u << p->pb, p->ProbPrices); /*MAB 1u */
+ LenPriceEnc_UpdateTables(&p->repLenEnc, 1u << p->pb, p->ProbPrices); /*MAB 1u */
+}
+
+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ UInt32 i;
+ for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
+ if (p->dictSize <= ((UInt32)1 << i))
+ break;
+ p->distTableSize = i * 2;
+
+ p->finished = False;
+ p->result = SZ_OK;
+ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
+ LzmaEnc_Init(p);
+ LzmaEnc_InitPrices(p);
+ p->nowPos64 = 0;
+ return SZ_OK;
+}
+
+static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream,
+ ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ p->inStream = inStream;
+ p->rc.outStream = outStream;
+ return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
+}
+
+#if defined(USE_UNUSED_CODE)
+/*MAB: static added */
+static SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
+ ISeqInStream *inStream, UInt32 keepWindowSize,
+ ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ p->inStream = inStream;
+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
+}
+#endif
+
+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
+{
+ p->seqBufInStream.funcTable.Read = MyRead;
+ p->seqBufInStream.data = src;
+ p->seqBufInStream.rem = srcLen;
+}
+
+#if defined(USE_UNUSED_CODE)
+/*MAB: static added */
+static SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
+ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ LzmaEnc_SetInputBuf(p, src, srcLen);
+ p->inStream = &p->seqBufInStream.funcTable;
+ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
+}
+#endif
+
+/*MAB: static added */
+static void LzmaEnc_Finish(CLzmaEncHandle pp)
+{
+ #ifdef COMPRESS_MF_MT
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ if (p->mtMode)
+ MatchFinderMt_ReleaseStream(&p->matchFinderMt);
+ #else
+ pp = pp;
+ #endif
+}
+
+typedef struct _CSeqOutStreamBuf
+{
+ ISeqOutStream funcTable;
+ Byte *data;
+ SizeT rem;
+ Bool overflow;
+} CSeqOutStreamBuf;
+
+static size_t MyWrite(void *pp, const void *data, size_t size)
+{
+ CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
+ if (p->rem < size)
+ {
+ size = p->rem;
+ p->overflow = True;
+ }
+ memcpy(p->data, data, size);
+ p->rem -= size;
+ p->data += size;
+ return size;
+}
+
+#if defined(USE_UNUSED_CODE)
+/*MAB: static added */
+static UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
+{
+ const CLzmaEnc *p = (CLzmaEnc *)pp;
+ return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
+}
+
+/*MAB: static added */
+static
+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
+{
+ const CLzmaEnc *p = (CLzmaEnc *)pp;
+ return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
+}
+
+/*MAB: static added */
+static
+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
+ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ UInt64 nowPos64;
+ SRes res;
+ CSeqOutStreamBuf outStream;
+
+ outStream.funcTable.Write = MyWrite;
+ outStream.data = dest;
+ outStream.rem = *destLen;
+ outStream.overflow = False;
+
+ p->writeEndMark = False;
+ p->finished = False;
+ p->result = SZ_OK;
+
+ if (reInit)
+ LzmaEnc_Init(p);
+ LzmaEnc_InitPrices(p);
+ nowPos64 = p->nowPos64;
+ RangeEnc_Init(&p->rc);
+ p->rc.outStream = &outStream.funcTable;
+
+ res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
+
+ *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
+ *destLen -= outStream.rem;
+ if (outStream.overflow)
+ return SZ_ERROR_OUTPUT_EOF;
+
+ return res;
+}
+#endif
+
+SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
+ ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ SRes res = SZ_OK;
+
+ #ifdef COMPRESS_MF_MT
+ Byte allocaDummy[0x300];
+ int i = 0;
+ for (i = 0; i < 16; i++)
+ allocaDummy[i] = (Byte)i;
+ #endif
+
+ RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig));
+
+ for (;;)
+ {
+ res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
+ if (res != SZ_OK || p->finished != 0)
+ break;
+ if (progress != 0)
+ {
+ res = progress->Progress(progress, p->nowPos64, (UInt64) RangeEnc_GetProcessed(&p->rc)); /*MAB casts */
+ if (res != SZ_OK)
+ {
+ res = SZ_ERROR_PROGRESS;
+ break;
+ }
+ }
+ }
+ LzmaEnc_Finish(pp);
+ return res;
+}
+
+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
+{
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+ int i;
+ UInt32 dictSize = p->dictSize;
+ if (*size < LZMA_PROPS_SIZE)
+ return SZ_ERROR_PARAM;
+ *size = LZMA_PROPS_SIZE;
+ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
+
+ for (i = 11; i <= 30; i++)
+ {
+ if (dictSize <= ((UInt32)2 << i))
+ {
+ dictSize = (UInt32)(2 << i); /*MAB casts */
+ break;
+ }
+ if (dictSize <= ((UInt32)3 << i))
+ {
+ dictSize = (UInt32)(3 << i); /*MAB casts */
+ break;
+ }
+ }
+
+ for (i = 0; i < 4; i++)
+ props[1 + i] = (Byte)(dictSize >> (8 * i));
+ return SZ_OK;
+}
+
+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ SRes res;
+ CLzmaEnc *p = (CLzmaEnc *)pp;
+
+ CSeqOutStreamBuf outStream;
+
+ LzmaEnc_SetInputBuf(p, src, srcLen);
+
+ outStream.funcTable.Write = MyWrite;
+ outStream.data = dest;
+ outStream.rem = *destLen;
+ outStream.overflow = False;
+
+ p->writeEndMark = writeEndMark;
+ res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable,
+ progress, alloc, allocBig);
+
+ *destLen -= outStream.rem;
+ if (outStream.overflow)
+ return SZ_ERROR_OUTPUT_EOF;
+ return res;
+}
+
+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
+{
+ CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
+ SRes res;
+ if (p == 0)
+ return SZ_ERROR_MEM;
+
+ res = LzmaEnc_SetProps(p, props);
+ if (res == SZ_OK)
+ {
+ res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
+ if (res == SZ_OK)
+ res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
+ writeEndMark, progress, alloc, allocBig);
+ }
+
+ LzmaEnc_Destroy(p, alloc, allocBig);
+ return res;
+}
diff --git a/DroidFish/jni/gtb/compression/lzma/LzmaEnc.h b/DroidFish/jni/gtb/compression/lzma/LzmaEnc.h
new file mode 100755
index 0000000..e3d84fa
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/LzmaEnc.h
@@ -0,0 +1,72 @@
+/* LzmaEnc.h -- LZMA Encoder
+2008-10-04 : Igor Pavlov : Public domain */
+
+#ifndef __LZMAENC_H
+#define __LZMAENC_H
+
+#include "Types.h"
+
+#define LZMA_PROPS_SIZE 5
+
+typedef struct _CLzmaEncProps
+{
+ int level; /* 0 <= level <= 9 */
+ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
+ (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
+ default = (1 << 24) */
+ int lc; /* 0 <= lc <= 8, default = 3 */
+ int lp; /* 0 <= lp <= 4, default = 0 */
+ int pb; /* 0 <= pb <= 4, default = 2 */
+ int algo; /* 0 - fast, 1 - normal, default = 1 */
+ int fb; /* 5 <= fb <= 273, default = 32 */
+ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
+ int numHashBytes; /* 2, 3 or 4, default = 4 */
+ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
+ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
+ int numThreads; /* 1 or 2, default = 2 */
+} CLzmaEncProps;
+
+void LzmaEncProps_Init(CLzmaEncProps *p);
+void LzmaEncProps_Normalize(CLzmaEncProps *p);
+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
+
+
+/* ---------- CLzmaEncHandle Interface ---------- */
+
+/* LzmaEnc_* functions can return the following exit codes:
+Returns:
+ SZ_OK - OK
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_PARAM - Incorrect paramater in props
+ SZ_ERROR_WRITE - Write callback error.
+ SZ_ERROR_PROGRESS - some break from progress callback
+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
+*/
+
+typedef void * CLzmaEncHandle;
+
+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
+SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
+SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
+SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+
+/* ---------- One Call Interface ---------- */
+
+/* LzmaEncode
+Return code:
+ SZ_OK - OK
+ SZ_ERROR_MEM - Memory allocation error
+ SZ_ERROR_PARAM - Incorrect paramater
+ SZ_ERROR_OUTPUT_EOF - output buffer overflow
+ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
+*/
+
+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
+ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
+ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
+
+#endif
diff --git a/DroidFish/jni/gtb/compression/lzma/Types.h b/DroidFish/jni/gtb/compression/lzma/Types.h
new file mode 100755
index 0000000..4e58832
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/lzma/Types.h
@@ -0,0 +1,208 @@
+/* Types.h -- Basic types
+2008-11-23 : Igor Pavlov : Public domain */
+
+#ifndef __7Z_TYPES_H
+#define __7Z_TYPES_H
+
+#include
+
+#ifdef _WIN32
+#include
+#endif
+
+#define SZ_OK 0
+
+#define SZ_ERROR_DATA 1
+#define SZ_ERROR_MEM 2
+#define SZ_ERROR_CRC 3
+#define SZ_ERROR_UNSUPPORTED 4
+#define SZ_ERROR_PARAM 5
+#define SZ_ERROR_INPUT_EOF 6
+#define SZ_ERROR_OUTPUT_EOF 7
+#define SZ_ERROR_READ 8
+#define SZ_ERROR_WRITE 9
+#define SZ_ERROR_PROGRESS 10
+#define SZ_ERROR_FAIL 11
+#define SZ_ERROR_THREAD 12
+
+#define SZ_ERROR_ARCHIVE 16
+#define SZ_ERROR_NO_ARCHIVE 17
+
+typedef int SRes;
+
+#ifdef _WIN32
+typedef DWORD WRes;
+#else
+typedef int WRes;
+#endif
+
+#ifndef RINOK
+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
+#endif
+
+typedef unsigned char Byte;
+typedef short Int16;
+typedef unsigned short UInt16;
+
+#ifdef _LZMA_UINT32_IS_ULONG
+typedef long Int32;
+typedef unsigned long UInt32;
+#else
+typedef int Int32;
+typedef unsigned int UInt32;
+#endif
+
+#ifdef _SZ_NO_INT_64
+
+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
+ NOTES: Some code will work incorrectly in that case! */
+
+typedef long Int64;
+typedef unsigned long UInt64;
+
+#else
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef __int64 Int64;
+typedef unsigned __int64 UInt64;
+#else
+typedef long long int Int64;
+typedef unsigned long long int UInt64;
+#endif
+
+#endif
+
+#ifdef _LZMA_NO_SYSTEM_SIZE_T
+typedef UInt32 SizeT;
+#else
+typedef size_t SizeT;
+#endif
+
+typedef int Bool;
+#define True 1
+#define False 0
+
+
+#ifdef _MSC_VER
+
+#if _MSC_VER >= 1300
+#define MY_NO_INLINE __declspec(noinline)
+#else
+#define MY_NO_INLINE
+#endif
+
+#define MY_CDECL __cdecl
+#define MY_STD_CALL __stdcall
+#define MY_FAST_CALL MY_NO_INLINE __fastcall
+
+#else
+
+#define MY_CDECL
+#define MY_STD_CALL
+#define MY_FAST_CALL
+
+#endif
+
+
+/* The following interfaces use first parameter as pointer to structure */
+
+typedef struct ISeqInStream
+{
+ SRes (*Read)(void *p, void *buf, size_t *size);
+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+ (output(*size) < input(*size)) is allowed */
+} ISeqInStream;
+
+/* it can return SZ_ERROR_INPUT_EOF */
+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
+
+typedef struct ISeqOutStream
+{
+ size_t (*Write)(void *p, const void *buf, size_t size);
+ /* Returns: result - the number of actually written bytes.
+ (result < size) means error */
+} ISeqOutStream;
+
+typedef enum ESzSeek
+{
+ SZ_SEEK_SET = 0,
+ SZ_SEEK_CUR = 1,
+ SZ_SEEK_END = 2
+} ESzSeek;
+
+typedef struct ISeekInStream
+{
+ SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
+} ISeekInStream;
+
+typedef struct ILookInStream
+{
+ SRes (*Look)(void *p, void **buf, size_t *size);
+ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
+ (output(*size) > input(*size)) is not allowed
+ (output(*size) < input(*size)) is allowed */
+ SRes (*Skip)(void *p, size_t offset);
+ /* offset must be <= output(*size) of Look */
+
+ SRes (*Read)(void *p, void *buf, size_t *size);
+ /* reads directly (without buffer). It's same as ISeqInStream::Read */
+ SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
+} ILookInStream;
+
+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
+
+/* reads via ILookInStream::Read */
+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
+
+#define LookToRead_BUF_SIZE (1 << 14)
+
+typedef struct CLookToRead
+{
+ ILookInStream s;
+ ISeekInStream *realStream;
+ size_t pos;
+ size_t size;
+ Byte buf[LookToRead_BUF_SIZE];
+} CLookToRead;
+
+void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
+void LookToRead_Init(CLookToRead *p);
+
+typedef struct CSecToLook
+{
+ ISeqInStream s;
+ ILookInStream *realStream;
+} CSecToLook;
+
+void SecToLook_CreateVTable(CSecToLook *p);
+
+typedef struct CSecToRead
+{
+ ISeqInStream s;
+ ILookInStream *realStream;
+} CSecToRead;
+
+void SecToRead_CreateVTable(CSecToRead *p);
+
+typedef struct ICompressProgress
+{
+ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
+ /* Returns: result. (result != SZ_OK) means break.
+ Value (UInt64)(Int64)-1 for size means unknown value. */
+} ICompressProgress;
+
+typedef struct ISzAlloc
+{
+ void *(*Alloc)(void *p, size_t size);
+ void (*Free)(void *p, void *address); /* address can be 0 */
+} ISzAlloc;
+
+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
+#define IAlloc_Free(p, a) (p)->Free((p), a)
+
+#endif
diff --git a/DroidFish/jni/gtb/compression/wrap.c b/DroidFish/jni/gtb/compression/wrap.c
new file mode 100644
index 0000000..8aae16e
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/wrap.c
@@ -0,0 +1,338 @@
+/* wrap.c */
+
+/*
+This Software is distributed with the following X11 License,
+sometimes also known as MIT license.
+
+Copyright (c) 2010 Miguel A. Ballicora
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "wrap.h"
+
+#define LZMA86
+#define ZLIB
+#define HUFFMAN
+#define LIBLZF
+/*#define LIBBZIP2*/
+
+#if defined(LZMA86)
+#include "Lzma86Enc.h"
+#include "Lzma86Dec.h"
+#endif
+
+#if defined(ZLIB)
+#include "zlib.h"
+#endif
+
+#if defined(HUFFMAN)
+#include "hzip.h"
+#endif
+
+#if defined(LIBLZF)
+#include "lzf.h"
+#endif
+
+#if defined(LIBBZIP2)
+#include "bzlib.h"
+#endif
+
+#if !defined(NDEBUG)
+#define NDEBUG
+#endif
+#ifdef DEBUG
+#undef NDEBUG
+#endif
+#include "assert.h"
+
+/* external, so the compiler can be silenced */
+size_t TB_DUMMY_unused;
+
+/***********************************************************************************************************/
+
+extern int
+zlib_encode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max)
+{
+ enum COMPRESSION_LEVELS {ZLIB_MAXIMUM_COMPRESSION = 9};
+ int outcome;
+ unsigned long zz = (unsigned long)out_max;
+ outcome = compress2 (out_start, &zz, in_start, (z_uLong)in_len, ZLIB_MAXIMUM_COMPRESSION);
+ *pout_len = (size_t) zz;
+ return outcome == Z_OK;
+}
+
+extern int
+zlib_decode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max)
+{
+ int outcome;
+ unsigned long nn = (unsigned long) out_max /* *pout_len */;
+ outcome = uncompress (out_start, &nn, in_start, (unsigned long)in_len);
+ *pout_len = (size_t)nn;
+ return outcome == Z_OK;
+}
+
+/***********************************************************************************************************/
+
+extern int
+lzf_encode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max)
+{
+ size_t x = lzf_compress (in_start, (unsigned)in_len, out_start, (unsigned)(in_len-1) /* ensures best compression */);
+ TB_DUMMY_unused = out_max;
+ if (x != 0)
+ *pout_len = (size_t) x;
+ return x != 0;
+}
+
+extern int
+lzf_decode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max)
+{
+ *pout_len = (size_t)lzf_decompress (in_start, (unsigned)in_len, out_start, (unsigned)out_max);
+ return *pout_len != 0;
+}
+
+/***********************************************************************************************************/
+
+extern int
+lzma_encode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max)
+{
+ int level = 5; /* 5 => default compression level */
+ unsigned int memory = 4096; /* dictionary size */
+ int filter = SZ_FILTER_NO; /* => 0, use LZMA, do not try to optimize with x86 filter */
+ size_t zz = out_max; /* maximum memory allowed, receives back the actual size */
+ int x = Lzma86_Encode(out_start, &zz, in_start, in_len, level, memory, filter);
+ *pout_len = zz;
+ return x == 0;
+}
+
+extern int
+lzma_decode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max)
+{
+ size_t nn = out_max;
+ int x = Lzma86_Decode(out_start, &nn, in_start, &in_len);
+ *pout_len = nn;
+ return x == SZ_OK;
+}
+
+/***********************************************************************************************************/
+
+#if defined (LIBBZIP2)
+
+extern int
+bzip2_encode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max)
+{
+ int blockSize100k = 9;
+ int verbosity = 0;
+ int workFactor = 30;
+ size_t destlen = out_max;
+
+ int x = BZ2_bzBuffToBuffCompress( (char*)out_start, &destlen, (char*)in_start, in_len,
+ blockSize100k, verbosity, workFactor);
+ *pout_len = destlen;
+ return x == BZ_OK;
+}
+
+extern int
+bzip2_decode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max)
+{
+ int small = 1;
+ int verbosity = 0;
+ size_t destlen = n;
+
+ int x = BZ2_bzBuffToBuffDecompress( (char*)out_start, &destlen, (char*)in_start, in_len,
+ small, verbosity);
+ *pout_len = destlen;
+ return x == BZ_OK;
+}
+
+#endif
+
+/***********************************************************************************************************/
+
+extern int
+justcopy_encode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max)
+{
+ size_t i;
+ const unsigned char *in = in_start;
+ unsigned char *out = out_start;
+
+ if (in_len > out_max)
+ return 0;
+
+ for (i = 0; i < in_len; i++) {
+ *out++ = *in++;
+ }
+ *pout_len = in_len;
+ return 1;
+}
+
+extern int
+justcopy_decode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max)
+{
+ size_t i;
+ const unsigned char *in = in_start;
+ unsigned char *out = out_start;
+
+ if (in_len > out_max)
+ return 0;
+
+ for (i = 0; i < in_len; i++) {
+ *out++ = *in++;
+ }
+ *pout_len = in_len;
+ return 1;
+}
+
+/***********************************************************************************************************/
+
+#define RLE_ESC 253
+#define RLE_TER 254
+#define RLE_MAX 252
+#define TRUE 1
+#define FALSE 0
+
+extern int
+rle_encode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max)
+{
+ const unsigned char *p;
+ const unsigned char *in = in_start;
+ const unsigned char *in_end = in + in_len;
+ unsigned char *out = out_start;
+ int ok = TRUE;
+ int ch;
+ ptrdiff_t out_len;
+
+ while (in < in_end)
+ {
+ if (*in == RLE_ESC) {
+
+ *out++ = RLE_ESC;
+ *out++ = RLE_ESC;
+ in++;
+
+ } else {
+
+ ch = *in;
+
+ if ( (in_end-in) >= 3 /* enough space for a run */
+ && ch == in[1] && ch == in[2] && ch == in[3] /* enough length */) {
+
+ p = in;
+ while (p < in_end && *p == ch && (p-in) < RLE_MAX) {
+ p++;
+ }
+
+ *out++ = RLE_ESC;
+ assert (RLE_MAX < 256);
+ *out++ = (unsigned char)(p - in);
+ *out++ = (unsigned char)ch;
+ in = p;
+
+ } else {
+ *out++ = *in++;
+ }
+ }
+ }
+
+ if (ok) {
+ /* *out++ = RLE_ESC; *out++ = RLE_TER; */
+ out_len = out - out_start;
+ *pout_len = (size_t)out_len;
+ ok = (size_t)out_len <= out_max;
+ }
+
+ return ok;
+}
+
+extern int
+rle_decode
+(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max)
+{
+ const unsigned char *in = in_start;
+ const unsigned char *in_end = in + in_len;
+ unsigned char *out = out_start;
+ unsigned char *out_end = out + *pout_len;
+ int ok = TRUE;
+ int ch;
+ int n;
+ ptrdiff_t out_len;
+
+ while (in < in_end)
+ {
+ if (in >= in_end) { ok = FALSE; break;}
+ if (out >= out_end) { ok = FALSE; break;}
+
+ if (*in == RLE_ESC) {
+ ++in; if (in >= in_end) { ok = FALSE; break;}
+
+ if (*in == RLE_ESC) {
+ *out++ = *in++;
+ } /*else if (*in == RLE_TER) {ok = TRUE;break;} */ else {
+
+ /* rle */
+ n = *in++; if (in >= in_end) { ok = FALSE; break;}
+ ch = *in++;
+ while (n-->0) { if (out >= out_end) { ok = FALSE; break;}
+ *out++ = (unsigned char)ch;
+ }
+ }
+ } else {
+ *out++ = *in++;
+ }
+ }
+
+ out_len = out - out_start;
+
+ if (ok)
+ *pout_len = (size_t)out_len;
+
+ ok = ok && (out_max >= (size_t)out_len);
+
+ return ok;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DroidFish/jni/gtb/compression/wrap.h b/DroidFish/jni/gtb/compression/wrap.h
new file mode 100644
index 0000000..d02dcff
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/wrap.h
@@ -0,0 +1,58 @@
+/* wrap.h */
+
+/*
+ X11 License:
+
+ Copyright (c) 2010 Miguel A. Ballicora
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#if !defined(H_WRAP)
+#define H_WRAP
+
+/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
+#include
+
+extern int zlib_encode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max);
+extern int zlib_decode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max);
+
+extern int lzf_encode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max);
+extern int lzf_decode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max);
+
+extern int lzma_encode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max);
+extern int lzma_decode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max);
+
+#if defined (LIBBZIP2)
+extern int bzip2_encode(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max);
+extern int bzip2_decode(const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max);
+#endif
+
+extern int rle_encode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max);
+extern int rle_decode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max);
+
+extern int justcopy_encode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max);
+extern int justcopy_decode (const unsigned char *in_start, size_t in_len, unsigned char *out_start, size_t *pout_len, size_t out_max);
+
+
+/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+#endif
diff --git a/DroidFish/jni/gtb/compression/zlib/adler32.c b/DroidFish/jni/gtb/compression/zlib/adler32.c
new file mode 100644
index 0000000..e449c32
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/adler32.c
@@ -0,0 +1,143 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#define BASE 65521UL /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
+
+/* use NO_DIVIDE if your processor does not do division in hardware */
+#ifdef NO_DIVIDE
+# define MOD(a) \
+ do { \
+ if (a >= (BASE << 16)) a -= (BASE << 16); \
+ if (a >= (BASE << 15)) a -= (BASE << 15); \
+ if (a >= (BASE << 14)) a -= (BASE << 14); \
+ if (a >= (BASE << 13)) a -= (BASE << 13); \
+ if (a >= (BASE << 12)) a -= (BASE << 12); \
+ if (a >= (BASE << 11)) a -= (BASE << 11); \
+ if (a >= (BASE << 10)) a -= (BASE << 10); \
+ if (a >= (BASE << 9)) a -= (BASE << 9); \
+ if (a >= (BASE << 8)) a -= (BASE << 8); \
+ if (a >= (BASE << 7)) a -= (BASE << 7); \
+ if (a >= (BASE << 6)) a -= (BASE << 6); \
+ if (a >= (BASE << 5)) a -= (BASE << 5); \
+ if (a >= (BASE << 4)) a -= (BASE << 4); \
+ if (a >= (BASE << 3)) a -= (BASE << 3); \
+ if (a >= (BASE << 2)) a -= (BASE << 2); \
+ if (a >= (BASE << 1)) a -= (BASE << 1); \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+# define MOD4(a) \
+ do { \
+ if (a >= (BASE << 4)) a -= (BASE << 4); \
+ if (a >= (BASE << 3)) a -= (BASE << 3); \
+ if (a >= (BASE << 2)) a -= (BASE << 2); \
+ if (a >= (BASE << 1)) a -= (BASE << 1); \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+#else
+# define MOD(a) a %= BASE
+# define MOD4(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(uLong adler, const Bytef *buf, uInt len)
+{
+ unsigned long sum2;
+ unsigned n;
+
+ /* split Adler-32 into component sums */
+ sum2 = (adler >> 16) & 0xffff;
+ adler &= 0xffff;
+
+ /* in case user likes doing a byte at a time, keep it fast */
+ if (len == 1) {
+ adler += buf[0];
+ if (adler >= BASE)
+ adler -= BASE;
+ sum2 += adler;
+ if (sum2 >= BASE)
+ sum2 -= BASE;
+ return adler | (sum2 << 16);
+ }
+
+ /* initial Adler-32 value (deferred check for len == 1 speed) */
+ if (buf == Z_NULL)
+ return 1L;
+
+ /* in case short lengths are provided, keep it somewhat fast */
+ if (len < 16) {
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ if (adler >= BASE)
+ adler -= BASE;
+ MOD4(sum2); /* only added so many BASE's */
+ return adler | (sum2 << 16);
+ }
+
+ /* do length NMAX blocks -- requires just one modulo operation */
+ while (len >= NMAX) {
+ len -= NMAX;
+ n = NMAX / 16; /* NMAX is divisible by 16 */
+ do {
+ DO16(buf); /* 16 sums unrolled */
+ buf += 16;
+ } while (--n);
+ MOD(adler);
+ MOD(sum2);
+ }
+
+ /* do remaining bytes (less than NMAX, still just one modulo) */
+ if (len) { /* avoid modulos if none remaining */
+ while (len >= 16) {
+ len -= 16;
+ DO16(buf);
+ buf += 16;
+ }
+ while (len--) {
+ adler += *buf++;
+ sum2 += adler;
+ }
+ MOD(adler);
+ MOD(sum2);
+ }
+
+ /* return recombined sums */
+ return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(uLong adler1, uLong adler2, long int len2)
+{
+ unsigned long sum1;
+ unsigned long sum2;
+ unsigned rem;
+
+ /* the derivation of this formula is left as an exercise for the reader */
+ rem = (unsigned)((long unsigned)len2 % BASE); /*MAB long unsigned casts */
+ sum1 = adler1 & 0xffff;
+ sum2 = rem * sum1;
+ MOD(sum2);
+ sum1 += (adler2 & 0xffff) + BASE - 1;
+ sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+ if (sum1 > BASE) sum1 -= BASE;
+ if (sum1 > BASE) sum1 -= BASE;
+ if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
+ if (sum2 > BASE) sum2 -= BASE;
+ return sum1 | (sum2 << 16);
+}
diff --git a/DroidFish/jni/gtb/compression/zlib/crc32.c b/DroidFish/jni/gtb/compression/zlib/crc32.c
new file mode 100644
index 0000000..6fba35f
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/crc32.c
@@ -0,0 +1,439 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors. This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+/*
+ Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+ protection on the static variables used to control the first-use generation
+ of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+ first call get_crc_table() to initialize the tables before allowing more than
+ one thread to use crc32().
+ */
+
+#ifdef MAKECRCH
+# include
+# ifndef DYNAMIC_CRC_TABLE
+# define DYNAMIC_CRC_TABLE
+# endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h" /* for STDC and FAR definitions */
+
+#define local static
+
+/* Find a four-byte integer type for crc32_little() and crc32_big(). */
+#ifndef NOBYFOUR
+# ifdef STDC /* need ANSI C limits.h to determine sizes */
+# include
+# define BYFOUR
+# if (UINT_MAX == 0xffffffffUL)
+ typedef unsigned int u4;
+# else
+# if (ULONG_MAX == 0xffffffffUL)
+ typedef unsigned long u4;
+# else
+# if (USHRT_MAX == 0xffffffffUL)
+ typedef unsigned short u4;
+# else
+# undef BYFOUR /* can't find a four-byte integer type! */
+# endif
+# endif
+# endif
+# endif /* STDC */
+#endif /* !NOBYFOUR */
+
+/* Definitions for doing the crc four data bytes at a time. */
+#ifdef BYFOUR
+# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
+ (((w)&0xff00)<<8)+(((w)&0xff)<<24))
+ local unsigned long crc32_little OF((unsigned long,
+ const unsigned char FAR *, unsigned));
+ local unsigned long crc32_big OF((unsigned long,
+ const unsigned char FAR *, unsigned));
+# define TBLS 8
+#else
+# define TBLS 1
+#endif /* BYFOUR */
+
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+ unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local unsigned long FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+ local void write_table OF((FILE *, const unsigned long FAR *));
+#endif /* MAKECRCH */
+/*
+ Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+ x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+ Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ with the lowest powers in the most significant bit. Then adding polynomials
+ is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ one. If we call the above polynomial p, and represent a byte as the
+ polynomial q, also with the lowest power in the most significant bit (so the
+ byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+ where a mod b means the remainder after dividing a by b.
+
+ This calculation is done using the shift-register method of multiplying and
+ taking the remainder. The register is initialized to zero, and for each
+ incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+ x (which is shifting right by one and adding x^32 mod p if the bit shifted
+ out is a one). We start with the highest power (least significant bit) of
+ q and repeat for all eight bits of q.
+
+ The first table is simply the CRC of all possible eight bit values. This is
+ all the information needed to generate CRCs on data a byte at a time for all
+ combinations of CRC register values and incoming bytes. The remaining tables
+ allow for word-at-a-time CRC calculation for both big-endian and little-
+ endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+ unsigned long c;
+ int n, k;
+ unsigned long poly; /* polynomial exclusive-or pattern */
+ /* terms of polynomial defining this crc (except x^32): */
+ static volatile int first = 1; /* flag to limit concurrent making */
+ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+ /* See if another task is already doing this (not thread-safe, but better
+ than nothing -- significantly reduces duration of vulnerability in
+ case the advice about DYNAMIC_CRC_TABLE is ignored) */
+ if (first) {
+ first = 0;
+
+ /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+ poly = 0UL;
+ for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
+ poly |= 1UL << (31 - p[n]);
+
+ /* generate a crc for every 8-bit value */
+ for (n = 0; n < 256; n++) {
+ c = (unsigned long)n;
+ for (k = 0; k < 8; k++)
+ c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+ crc_table[0][n] = c;
+ }
+
+#ifdef BYFOUR
+ /* generate crc for each value followed by one, two, and three zeros,
+ and then the byte reversal of those as well as the first table */
+ for (n = 0; n < 256; n++) {
+ c = crc_table[0][n];
+ crc_table[4][n] = REV(c);
+ for (k = 1; k < 4; k++) {
+ c = crc_table[0][c & 0xff] ^ (c >> 8);
+ crc_table[k][n] = c;
+ crc_table[k + 4][n] = REV(c);
+ }
+ }
+#endif /* BYFOUR */
+
+ crc_table_empty = 0;
+ }
+ else { /* not first */
+ /* wait for the other guy to finish (not efficient, but rare) */
+ while (crc_table_empty)
+ ;
+ }
+
+#ifdef MAKECRCH
+ /* write out CRC tables to crc32.h */
+ {
+ FILE *out;
+
+ out = fopen("crc32.h", "w");
+ if (out == NULL) return;
+ fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+ fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+ fprintf(out, "local const unsigned long FAR ");
+ fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
+ write_table(out, crc_table[0]);
+# ifdef BYFOUR
+ fprintf(out, "#ifdef BYFOUR\n");
+ for (k = 1; k < 8; k++) {
+ fprintf(out, " },\n {\n");
+ write_table(out, crc_table[k]);
+ }
+ fprintf(out, "#endif\n");
+# endif /* BYFOUR */
+ fprintf(out, " }\n};\n");
+ fclose(out);
+ }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+ FILE *out;
+ const unsigned long FAR *table;
+{
+ int n;
+
+ for (n = 0; n < 256; n++)
+ fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
+ n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const unsigned long FAR * ZEXPORT get_crc_table(void)
+{
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+ return (const unsigned long FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(long unsigned int crc, const unsigned char *buf, unsigned int len)
+{
+ if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+
+
+#ifdef _MSC_VER
+#pragma warning(disable:4127)
+#endif
+
+ if (sizeof(void *) == sizeof(ptrdiff_t)) {
+
+#ifdef _MSC_VER
+#pragma warning(default:4127)
+#endif
+ u4 endian;
+
+ endian = 1;
+ if (*((unsigned char *)(&endian)))
+ return crc32_little(crc, buf, len);
+ else
+ return crc32_big(crc, buf, len);
+
+ }
+
+ /*MAB: begin*/
+ else {
+
+ crc = crc ^ 0xffffffffUL;
+ while (len >= 8) {
+ DO8;
+ len -= 8;
+ }
+ if (len) do {
+ DO1;
+ } while (--len);
+ return crc ^ 0xffffffffUL;
+
+ }
+ /*MAB: end addition */
+
+#else /*MAB: Changed from endif */
+
+ crc = crc ^ 0xffffffffUL;
+ while (len >= 8) {
+ DO8;
+ len -= 8;
+ }
+ if (len) do {
+ DO1;
+ } while (--len);
+ return crc ^ 0xffffffffUL;
+
+#endif /*MAB*/
+
+}
+
+#ifdef BYFOUR
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+ c = (u4)(crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]) /*MAB casts */
+
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(long unsigned int crc, const unsigned char *buf, unsigned int len)
+{
+ register u4 c;
+ register const u4 FAR *buf4;
+
+ c = (u4)crc;
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = (u4) (crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8)); /*MAB casts */
+ len--;
+ }
+
+ buf4 = (const u4 FAR *)(const void FAR *)buf;
+ while (len >= 32) {
+ DOLIT32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOLIT4;
+ len -= 4;
+ }
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = (u4)(crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8)); /*MAB casts */
+ } while (--len);
+ c = ~c;
+ return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *++buf4; \
+ c = (u4) (crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]) /*MAB casts */
+
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(long unsigned int crc, const unsigned char *buf, unsigned int len)
+{
+ register u4 c;
+ register const u4 FAR *buf4;
+
+ c = REV((u4)crc);
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = (u4) (crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8)); /*MAB casts */
+ len--;
+ }
+
+ buf4 = (const u4 FAR *)(const void FAR *)buf;
+ buf4--;
+ while (len >= 32) {
+ DOBIG32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOBIG4;
+ len -= 4;
+ }
+ buf4++;
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = (u4) (crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8));
+ } while (--len);
+ c = ~c;
+ return (unsigned long)(REV(c));
+}
+
+#endif /* BYFOUR */
+
+#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(long unsigned int *mat, long unsigned int vec)
+{
+ unsigned long sum;
+
+ sum = 0;
+ while (vec) {
+ if (vec & 1)
+ sum ^= *mat;
+ vec >>= 1;
+ mat++;
+ }
+ return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(long unsigned int *square, long unsigned int *mat)
+{
+ int n;
+
+ for (n = 0; n < GF2_DIM; n++)
+ square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, long int len2)
+{
+ int n;
+ unsigned long row;
+ unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
+ unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
+
+ /* degenerate case */
+ if (len2 == 0)
+ return crc1;
+
+ /* put operator for one zero bit in odd */
+ odd[0] = 0xedb88320L; /* CRC-32 polynomial */
+ row = 1;
+ for (n = 1; n < GF2_DIM; n++) {
+ odd[n] = row;
+ row <<= 1;
+ }
+
+ /* put operator for two zero bits in even */
+ gf2_matrix_square(even, odd);
+
+ /* put operator for four zero bits in odd */
+ gf2_matrix_square(odd, even);
+
+ /* apply len2 zeros to crc1 (first square will put the operator for one
+ zero byte, eight zero bits, in even) */
+ do {
+ /* apply zeros operator for this bit of len2 */
+ gf2_matrix_square(even, odd);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(even, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ if (len2 == 0)
+ break;
+
+ /* another iteration of the loop with odd and even swapped */
+ gf2_matrix_square(odd, even);
+ if (len2 & 1)
+ crc1 = gf2_matrix_times(odd, crc1);
+ len2 >>= 1;
+
+ /* if no more bits set, then done */
+ } while (len2 != 0);
+
+ /* return combined crc */
+ crc1 ^= crc2;
+ return crc1;
+}
diff --git a/DroidFish/jni/gtb/compression/zlib/crc32.h b/DroidFish/jni/gtb/compression/zlib/crc32.h
new file mode 100644
index 0000000..8053b61
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/crc32.h
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const unsigned long FAR crc_table[TBLS][256] =
+{
+ {
+ 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+ 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+ 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+ 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+ 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+ 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+ 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+ 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+ 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+ 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+ 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+ 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+ 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+ 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+ 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+ 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+ 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+ 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+ 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+ 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+ 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+ 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+ 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+ 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+ 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+ 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+ 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+ 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+ 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+ 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+ 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+ 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+ 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+ 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+ 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+ 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+ 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+ 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+ 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+ 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+ 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+ 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+ 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+ 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+ 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+ 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+ 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+ 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+ 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+ 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+ 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+ 0x2d02ef8dUL
+#ifdef BYFOUR
+ },
+ {
+ 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+ 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+ 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+ 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+ 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+ 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+ 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+ 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+ 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+ 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+ 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+ 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+ 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+ 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+ 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+ 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+ 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+ 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+ 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+ 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+ 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+ 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+ 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+ 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+ 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+ 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+ 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+ 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+ 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+ 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+ 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+ 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+ 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+ 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+ 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+ 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+ 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+ 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+ 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+ 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+ 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+ 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+ 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+ 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+ 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+ 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+ 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+ 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+ 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+ 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+ 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+ 0x9324fd72UL
+ },
+ {
+ 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+ 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+ 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+ 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+ 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+ 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+ 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+ 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+ 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+ 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+ 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+ 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+ 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+ 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+ 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+ 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+ 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+ 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+ 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+ 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+ 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+ 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+ 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+ 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+ 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+ 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+ 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+ 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+ 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+ 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+ 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+ 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+ 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+ 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+ 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+ 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+ 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+ 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+ 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+ 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+ 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+ 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+ 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+ 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+ 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+ 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+ 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+ 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+ 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+ 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+ 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+ 0xbe9834edUL
+ },
+ {
+ 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+ 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+ 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+ 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+ 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+ 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+ 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+ 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+ 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+ 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+ 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+ 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+ 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+ 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+ 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+ 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+ 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+ 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+ 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+ 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+ 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+ 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+ 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+ 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+ 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+ 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+ 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+ 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+ 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+ 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+ 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+ 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+ 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+ 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+ 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+ 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+ 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+ 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+ 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+ 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+ 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+ 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+ 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+ 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+ 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+ 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+ 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+ 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+ 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+ 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+ 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+ 0xde0506f1UL
+ },
+ {
+ 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+ 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+ 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+ 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+ 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+ 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+ 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+ 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+ 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+ 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+ 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+ 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+ 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+ 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+ 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+ 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+ 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+ 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+ 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+ 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+ 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+ 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+ 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+ 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+ 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+ 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+ 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+ 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+ 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+ 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+ 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+ 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+ 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+ 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+ 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+ 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+ 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+ 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+ 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+ 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+ 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+ 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+ 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+ 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+ 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+ 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+ 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+ 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+ 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+ 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+ 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+ 0x8def022dUL
+ },
+ {
+ 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+ 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+ 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+ 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+ 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+ 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+ 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+ 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+ 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+ 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+ 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+ 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+ 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+ 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+ 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+ 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+ 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+ 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+ 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+ 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+ 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+ 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+ 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+ 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+ 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+ 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+ 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+ 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+ 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+ 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+ 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+ 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+ 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+ 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+ 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+ 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+ 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+ 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+ 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+ 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+ 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+ 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+ 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+ 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+ 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+ 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+ 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+ 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+ 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+ 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+ 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+ 0x72fd2493UL
+ },
+ {
+ 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+ 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+ 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+ 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+ 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+ 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+ 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+ 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+ 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+ 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+ 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+ 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+ 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+ 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+ 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+ 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+ 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+ 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+ 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+ 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+ 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+ 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+ 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+ 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+ 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+ 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+ 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+ 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+ 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+ 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+ 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+ 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+ 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+ 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+ 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+ 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+ 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+ 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+ 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+ 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+ 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+ 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+ 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+ 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+ 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+ 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+ 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+ 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+ 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+ 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+ 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+ 0xed3498beUL
+ },
+ {
+ 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+ 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+ 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+ 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+ 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+ 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+ 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+ 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+ 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+ 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+ 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+ 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+ 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+ 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+ 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+ 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+ 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+ 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+ 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+ 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+ 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+ 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+ 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+ 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+ 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+ 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+ 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+ 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+ 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+ 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+ 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+ 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+ 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+ 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+ 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+ 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+ 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+ 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+ 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+ 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+ 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+ 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+ 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+ 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+ 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+ 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+ 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+ 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+ 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+ 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+ 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+ 0xf10605deUL
+#endif
+ }
+};
diff --git a/DroidFish/jni/gtb/compression/zlib/deflate.c b/DroidFish/jni/gtb/compression/zlib/deflate.c
new file mode 100644
index 0000000..3e81cc0
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/deflate.c
@@ -0,0 +1,1725 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process depends on being able to identify portions
+ * of the input text which are identical to earlier input (within a
+ * sliding window trailing behind the input currently being processed).
+ *
+ * The most straightforward technique turns out to be the fastest for
+ * most input files: try all possible matches and select the longest.
+ * The key feature of this algorithm is that insertions into the string
+ * dictionary are very simple and thus fast, and deletions are avoided
+ * completely. Insertions are performed at each input character, whereas
+ * string matches are performed only when the previous match ends. So it
+ * is preferable to spend more time in matches to allow very fast string
+ * insertions and avoid deletions. The matching algorithm for small
+ * strings is inspired from that of Rabin & Karp. A brute force approach
+ * is used to find longer strings when a small match has been found.
+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ * (by Leonid Broukhis).
+ * A previous version of this file used a more sophisticated algorithm
+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
+ * time, but has a larger average cost, uses more memory and is patented.
+ * However the F&G algorithm may be faster for some highly redundant
+ * files if the parameter max_chain_length (described below) is too large.
+ *
+ * ACKNOWLEDGEMENTS
+ *
+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ * I found it in 'freeze' written by Leonid Broukhis.
+ * Thanks to many people for bug reports and testing.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ * Available in http://www.ietf.org/rfc/rfc1951.txt
+ *
+ * A description of the Rabin and Karp algorithm is given in the book
+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ * Fiala,E.R., and Greene,D.H.
+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+ " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ * Function prototypes.
+ */
+typedef enum block_state {
+ need_more, /* block not completed, need more input or more output */
+ block_done, /* block flush performed */
+ finish_started, /* finish started, need only more output at next deflate */
+ finish_done /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow OF((deflate_state *s, int flush));
+#endif
+local void lm_init OF((deflate_state *s));
+local void putShortMSB OF((deflate_state *s, uInt b));
+local void flush_pending OF((z_streamp strm));
+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifndef FASTEST
+#ifdef ASMV
+ void match_init OF((void)); /* asm code initialization */
+ uInt longest_match OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match OF((deflate_state *s, IPos cur_match));
+#endif
+#endif
+local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
+
+#ifdef DEBUG
+local void check_match OF((deflate_state *s, IPos start, IPos match,
+ int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+# define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+ ush good_length; /* reduce lazy search above this match length */
+ ush max_lazy; /* do not perform lazy search above this match length */
+ ush nice_length; /* quit search above this match length */
+ ush max_chain;
+ compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4, 5, 16, 8, deflate_fast},
+/* 3 */ {4, 6, 32, 32, deflate_fast},
+
+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
+/* 5 */ {8, 16, 32, 32, deflate_slow},
+/* 6 */ {8, 16, 128, 128, deflate_slow},
+/* 7 */ {8, 32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+#ifndef NO_DUMMY_DECL
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+#endif
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
+ * input characters, so that a running hash key can be computed from the
+ * previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
+ * input characters and the first MIN_MATCH bytes of str are valid
+ * (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+ s->head[s->hash_size-1] = NIL; \
+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(z_streamp strm, int level, const char *version, int stream_size)
+{
+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+ Z_DEFAULT_STRATEGY, version, stream_size);
+ /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, int windowBits, int memLevel, int strategy, const char *version, int stream_size)
+{
+ deflate_state *s;
+ int wrap = 1;
+ static const char my_version[] = ZLIB_VERSION;
+
+ ushf *overlay;
+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
+ * output size for (length,distance) codes is <= 24 bits.
+ */
+
+ if (version == Z_NULL || version[0] != my_version[0] ||
+ stream_size != sizeof(z_stream)) {
+ return Z_VERSION_ERROR;
+ }
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+ strm->msg = Z_NULL;
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+ if (windowBits < 0) { /* suppress zlib wrapper */
+ wrap = 0;
+ windowBits = -windowBits;
+ }
+#ifdef GZIP
+ else if (windowBits > 15) {
+ wrap = 2; /* write gzip wrapper instead */
+ windowBits -= 16;
+ }
+#endif
+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+ windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+ strategy < 0 || strategy > Z_FIXED) {
+ return Z_STREAM_ERROR;
+ }
+ if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+ if (s == Z_NULL) return Z_MEM_ERROR;
+ strm->state = (struct internal_state FAR *)s;
+ s->strm = strm;
+
+ s->wrap = wrap;
+ s->gzhead = Z_NULL;
+ s->w_bits = (z_uInt) windowBits; /*MAB casts */
+ s->w_size = (z_uInt) (1 << s->w_bits); /*MAB casts */
+ s->w_mask = s->w_size - 1;
+
+ s->hash_bits = (z_uInt) (memLevel + 7); /*MAB casts */
+ s->hash_size = (z_uInt) (1 << s->hash_bits); /*MAB casts */
+ s->hash_mask = s->hash_size - 1;
+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+ s->lit_bufsize = (z_uInt)(1 << (memLevel + 6)); /* 16K elements by default */ /*MAB casts */
+
+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+ s->pending_buf = (uchf *) overlay;
+ s->pending_buf_size = (ulg)s->lit_bufsize * (ulg)(sizeof(ush)+2L); /*MAB casts (ulg)(sizeof... */
+
+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+ s->pending_buf == Z_NULL) {
+ s->status = FINISH_STATE;
+ strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+ deflateEnd (strm);
+ return Z_MEM_ERROR;
+ }
+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+ s->level = level;
+ s->strategy = strategy;
+ s->method = (Byte)method;
+
+ return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (z_streamp strm, const Bytef *dictionary, uInt dictLength)
+{
+ deflate_state *s;
+ uInt length = dictLength;
+ uInt n;
+ IPos hash_head = 0;
+
+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+ strm->state->wrap == 2 ||
+ (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
+ return Z_STREAM_ERROR;
+
+ s = strm->state;
+ if (s->wrap)
+ strm->adler = adler32(strm->adler, dictionary, dictLength);
+
+ if (length < MIN_MATCH) return Z_OK;
+ if (length > MAX_DIST(s)) {
+ length = MAX_DIST(s);
+ dictionary += dictLength - length; /* use the tail of the dictionary */
+ }
+ zmemcpy(s->window, dictionary, length);
+ s->strstart = length;
+ s->block_start = (long)length;
+
+ /* Insert all strings in the hash table (except for the last two bytes).
+ * s->lookahead stays null, so s->ins_h will be recomputed at the next
+ * call of fill_window.
+ */
+ s->ins_h = s->window[0];
+ UPDATE_HASH(s, s->ins_h, s->window[1]);
+ for (n = 0; n <= length - MIN_MATCH; n++) {
+ INSERT_STRING(s, n, hash_head);
+ }
+ if (hash_head) hash_head = 0; /* to make compiler happy */
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (z_streamp strm)
+{
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
+ return Z_STREAM_ERROR;
+ }
+
+ strm->total_in = strm->total_out = 0;
+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+ strm->data_type = Z_UNKNOWN;
+
+ s = (deflate_state *)strm->state;
+ s->pending = 0;
+ s->pending_out = s->pending_buf;
+
+ if (s->wrap < 0) {
+ s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+ }
+ s->status = s->wrap ? INIT_STATE : BUSY_STATE;
+ strm->adler =
+#ifdef GZIP
+ s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+ adler32(0L, Z_NULL, 0);
+ s->last_flush = Z_NO_FLUSH;
+
+ _tr_init(s);
+ lm_init(s);
+
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetHeader (z_streamp strm, gz_headerp head)
+{
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (strm->state->wrap != 2) return Z_STREAM_ERROR;
+ strm->state->gzhead = head;
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (z_streamp strm, int bits, int value)
+{
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ strm->state->bi_valid = bits;
+ strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(z_streamp strm, int level, int strategy)
+{
+ deflate_state *s;
+ compress_func func;
+ int err = Z_OK;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ s = strm->state;
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
+ return Z_STREAM_ERROR;
+ }
+ func = configuration_table[s->level].func;
+
+ if (func != configuration_table[level].func && strm->total_in != 0) {
+ /* Flush the last buffer: */
+ err = deflate(strm, Z_PARTIAL_FLUSH);
+ }
+ if (s->level != level) {
+ s->level = level;
+ s->max_lazy_match = configuration_table[level].max_lazy;
+ s->good_match = configuration_table[level].good_length;
+ s->nice_match = configuration_table[level].nice_length;
+ s->max_chain_length = configuration_table[level].max_chain;
+ }
+ s->strategy = strategy;
+ return err;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateTune(z_streamp strm, int good_length, int max_lazy, int nice_length, int max_chain)
+{
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ s = strm->state;
+ s->good_match = (z_uInt) good_length; /*MAB casts */
+ s->max_lazy_match = (z_uInt) max_lazy; /*MAB casts */
+ s->nice_match = nice_length;
+ s->max_chain_length = (z_uInt) max_chain; /*MAB casts */
+ return Z_OK;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well. The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds
+ * for every combination of windowBits and memLevel, as well as wrap.
+ * But even the conservative upper bound of about 14% expansion does not
+ * seem onerous for output buffer allocation.
+ */
+uLong ZEXPORT deflateBound(z_streamp strm, uLong sourceLen)
+{
+ deflate_state *s;
+ uLong destLen;
+
+ /* conservative upper bound */
+ destLen = sourceLen +
+ ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
+
+ /* if can't get parameters, return conservative bound */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ return destLen;
+
+ /* if not default parameters, return conservative bound */
+ s = strm->state;
+ if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+ return destLen;
+
+ /* default settings: return tight bound for that case */
+ return compressBound(sourceLen);
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (deflate_state *s, uInt b)
+{
+ put_byte(s, (Byte)(b >> 8));
+ put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(z_streamp strm)
+{
+ unsigned len = strm->state->pending;
+
+ if (len > strm->avail_out) len = strm->avail_out;
+ if (len == 0) return;
+
+ zmemcpy(strm->next_out, strm->state->pending_out, len);
+ strm->next_out += len;
+ strm->state->pending_out += len;
+ strm->total_out += len;
+ strm->avail_out -= len;
+ strm->state->pending -= len;
+ if (strm->state->pending == 0) {
+ strm->state->pending_out = strm->state->pending_buf;
+ }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (z_streamp strm, int flush)
+{
+ int old_flush; /* value of flush param for previous deflate call */
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ flush > Z_FINISH || flush < 0) {
+ return Z_STREAM_ERROR;
+ }
+ s = strm->state;
+
+ if (strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
+ ERR_RETURN(strm, Z_STREAM_ERROR);
+ }
+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+ s->strm = strm; /* just in case */
+ old_flush = s->last_flush;
+ s->last_flush = flush;
+
+ /* Write the header */
+ if (s->status == INIT_STATE) {
+#ifdef GZIP
+ if (s->wrap == 2) {
+ strm->adler = crc32(0L, Z_NULL, 0);
+ put_byte(s, 31);
+ put_byte(s, 139);
+ put_byte(s, 8);
+ if (s->gzhead == NULL) {
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, OS_CODE);
+ s->status = BUSY_STATE;
+ }
+ else {
+ put_byte(s, (s->gzhead->text ? 1 : 0) +
+ (s->gzhead->hcrc ? 2 : 0) +
+ (s->gzhead->extra == Z_NULL ? 0 : 4) +
+ (s->gzhead->name == Z_NULL ? 0 : 8) +
+ (s->gzhead->comment == Z_NULL ? 0 : 16)
+ );
+ put_byte(s, (Byte)(s->gzhead->time & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+ put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, s->gzhead->os & 0xff);
+ if (s->gzhead->extra != NULL) {
+ put_byte(s, s->gzhead->extra_len & 0xff);
+ put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
+ }
+ if (s->gzhead->hcrc)
+ strm->adler = crc32(strm->adler, s->pending_buf,
+ s->pending);
+ s->gzindex = 0;
+ s->status = EXTRA_STATE;
+ }
+ }
+ else
+#endif
+ {
+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+ uInt level_flags;
+
+ if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+ level_flags = 0;
+ else if (s->level < 6)
+ level_flags = 1;
+ else if (s->level == 6)
+ level_flags = 2;
+ else
+ level_flags = 3;
+ header |= (level_flags << 6);
+ if (s->strstart != 0) header |= PRESET_DICT;
+ header += 31 - (header % 31);
+
+ s->status = BUSY_STATE;
+ putShortMSB(s, header);
+
+ /* Save the adler32 of the preset dictionary: */
+ if (s->strstart != 0) {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ strm->adler = adler32(0L, Z_NULL, 0);
+ }
+ }
+#ifdef GZIP
+ if (s->status == EXTRA_STATE) {
+ if (s->gzhead->extra != NULL) {
+ uInt beg = s->pending; /* start of bytes to update crc */
+
+ while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
+ if (s->pending == s->pending_buf_size) {
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ flush_pending(strm);
+ beg = s->pending;
+ if (s->pending == s->pending_buf_size)
+ break;
+ }
+ put_byte(s, s->gzhead->extra[s->gzindex]);
+ s->gzindex++;
+ }
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ if (s->gzindex == s->gzhead->extra_len) {
+ s->gzindex = 0;
+ s->status = NAME_STATE;
+ }
+ }
+ else
+ s->status = NAME_STATE;
+ }
+ if (s->status == NAME_STATE) {
+ if (s->gzhead->name != NULL) {
+ uInt beg = s->pending; /* start of bytes to update crc */
+ int val;
+
+ do {
+ if (s->pending == s->pending_buf_size) {
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ flush_pending(strm);
+ beg = s->pending;
+ if (s->pending == s->pending_buf_size) {
+ val = 1;
+ break;
+ }
+ }
+ val = s->gzhead->name[s->gzindex++];
+ put_byte(s, val);
+ } while (val != 0);
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ if (val == 0) {
+ s->gzindex = 0;
+ s->status = COMMENT_STATE;
+ }
+ }
+ else
+ s->status = COMMENT_STATE;
+ }
+ if (s->status == COMMENT_STATE) {
+ if (s->gzhead->comment != NULL) {
+ uInt beg = s->pending; /* start of bytes to update crc */
+ int val;
+
+ do {
+ if (s->pending == s->pending_buf_size) {
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ flush_pending(strm);
+ beg = s->pending;
+ if (s->pending == s->pending_buf_size) {
+ val = 1;
+ break;
+ }
+ }
+ val = s->gzhead->comment[s->gzindex++];
+ put_byte(s, val);
+ } while (val != 0);
+ if (s->gzhead->hcrc && s->pending > beg)
+ strm->adler = crc32(strm->adler, s->pending_buf + beg,
+ s->pending - beg);
+ if (val == 0)
+ s->status = HCRC_STATE;
+ }
+ else
+ s->status = HCRC_STATE;
+ }
+ if (s->status == HCRC_STATE) {
+ if (s->gzhead->hcrc) {
+ if (s->pending + 2 > s->pending_buf_size)
+ flush_pending(strm);
+ if (s->pending + 2 <= s->pending_buf_size) {
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ strm->adler = crc32(0L, Z_NULL, 0);
+ s->status = BUSY_STATE;
+ }
+ }
+ else
+ s->status = BUSY_STATE;
+ }
+#endif
+
+ /* Flush as much pending output as possible */
+ if (s->pending != 0) {
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ /* Since avail_out is 0, deflate will be called again with
+ * more output space, but possibly with both pending and
+ * avail_in equal to zero. There won't be anything to do,
+ * but this is not an error situation so make sure we
+ * return OK instead of BUF_ERROR at next call of deflate:
+ */
+ s->last_flush = -1;
+ return Z_OK;
+ }
+
+ /* Make sure there is something to do and avoid duplicate consecutive
+ * flushes. For repeated and useless calls with Z_FINISH, we keep
+ * returning Z_STREAM_END instead of Z_BUF_ERROR.
+ */
+ } else if (strm->avail_in == 0 && flush <= old_flush &&
+ flush != Z_FINISH) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* User must not provide more input after the first FINISH: */
+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* Start a new block or continue the current one.
+ */
+ if (strm->avail_in != 0 || s->lookahead != 0 ||
+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+ block_state bstate;
+
+ bstate = (*(configuration_table[s->level].func))(s, flush);
+
+ if (bstate == finish_started || bstate == finish_done) {
+ s->status = FINISH_STATE;
+ }
+ if (bstate == need_more || bstate == finish_started) {
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+ }
+ return Z_OK;
+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+ * of deflate should use the same flush parameter to make sure
+ * that the flush is complete. So we don't have to output an
+ * empty block here, this will be done at next call. This also
+ * ensures that for a very small output buffer, we emit at most
+ * one empty block.
+ */
+ }
+ if (bstate == block_done) {
+ if (flush == Z_PARTIAL_FLUSH) {
+ _tr_align(s);
+ } else { /* FULL_FLUSH or SYNC_FLUSH */
+ _tr_stored_block(s, (char*)0, 0L, 0);
+ /* For a full flush, this empty block will be recognized
+ * as a special marker by inflate_sync().
+ */
+ if (flush == Z_FULL_FLUSH) {
+ CLEAR_HASH(s); /* forget history */
+ }
+ }
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+ return Z_OK;
+ }
+ }
+ }
+ Assert(strm->avail_out > 0, "bug2");
+
+ if (flush != Z_FINISH) return Z_OK;
+ if (s->wrap <= 0) return Z_STREAM_END;
+
+ /* Write the trailer */
+#ifdef GZIP
+ if (s->wrap == 2) {
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+ put_byte(s, (Byte)(strm->total_in & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+ }
+ else
+#endif
+ {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ flush_pending(strm);
+ /* If avail_out is zero, the application will call deflate again
+ * to flush the rest.
+ */
+ if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (z_streamp strm)
+{
+ int status;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+ status = strm->state->status;
+ if (status != INIT_STATE &&
+ status != EXTRA_STATE &&
+ status != NAME_STATE &&
+ status != COMMENT_STATE &&
+ status != HCRC_STATE &&
+ status != BUSY_STATE &&
+ status != FINISH_STATE) {
+ return Z_STREAM_ERROR;
+ }
+
+ /* Deallocate in reverse order of allocations: */
+ TRY_FREE(strm, strm->state->pending_buf);
+ TRY_FREE(strm, strm->state->head);
+ TRY_FREE(strm, strm->state->prev);
+ TRY_FREE(strm, strm->state->window);
+
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+
+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (z_streamp dest, z_streamp source)
+{
+#ifdef MAXSEG_64K
+ return Z_STREAM_ERROR;
+#else
+ deflate_state *ds;
+ deflate_state *ss;
+ ushf *overlay;
+
+
+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+ return Z_STREAM_ERROR;
+ }
+
+ ss = source->state;
+
+ zmemcpy(dest, source, sizeof(z_stream));
+
+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+ if (ds == Z_NULL) return Z_MEM_ERROR;
+ dest->state = (struct internal_state FAR *) ds;
+ zmemcpy(ds, ss, sizeof(deflate_state));
+ ds->strm = dest;
+
+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+ ds->pending_buf = (uchf *) overlay;
+
+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+ ds->pending_buf == Z_NULL) {
+ deflateEnd (dest);
+ return Z_MEM_ERROR;
+ }
+ /* following zmemcpy do not work for 16-bit MSDOS */
+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+ ds->l_desc.dyn_tree = ds->dyn_ltree;
+ ds->d_desc.dyn_tree = ds->dyn_dtree;
+ ds->bl_desc.dyn_tree = ds->bl_tree;
+
+ return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read. All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(z_streamp strm, Bytef *buf, unsigned int size)
+{
+ unsigned len = strm->avail_in;
+
+ if (len > size) len = size;
+ if (len == 0) return 0;
+
+ strm->avail_in -= len;
+
+ if (strm->state->wrap == 1) {
+ strm->adler = adler32(strm->adler, strm->next_in, len);
+ }
+#ifdef GZIP
+ else if (strm->state->wrap == 2) {
+ strm->adler = crc32(strm->adler, strm->next_in, len);
+ }
+#endif
+ zmemcpy(buf, strm->next_in, len);
+ strm->next_in += len;
+ strm->total_in += len;
+
+ return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (deflate_state *s)
+{
+ s->window_size = (ulg)2L*s->w_size;
+
+ CLEAR_HASH(s);
+
+ /* Set the default configuration parameters:
+ */
+ s->max_lazy_match = configuration_table[s->level].max_lazy;
+ s->good_match = configuration_table[s->level].good_length;
+ s->nice_match = configuration_table[s->level].nice_length;
+ s->max_chain_length = configuration_table[s->level].max_chain;
+
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->lookahead = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ s->ins_h = 0;
+#ifndef FASTEST
+#ifdef ASMV
+ match_init(); /* initialize the asm code */
+#endif
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(deflate_state *s, IPos cur_match)
+
+ /* current match */
+{
+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ int best_len = (int)s->prev_length; /* best match length so far */ /*MAB casts */
+ int nice_match = s->nice_match; /* stop if match long enough */
+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+ s->strstart - (IPos)MAX_DIST(s) : NIL;
+ /* Stop when cur_match becomes <= limit. To simplify the code,
+ * we prevent matches with the string of window index 0.
+ */
+ Posf *prev = s->prev;
+ uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+ /* Compare two bytes at a time. Note: this is not always beneficial.
+ * Try with and without -DUNALIGNED_OK to check.
+ */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+ register ush scan_start = *(ushf*)scan;
+ register ush scan_end = *(ushf*)(scan+best_len-1);
+#else
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+ register Byte scan_end1 = scan[best_len-1];
+ register Byte scan_end = scan[best_len];
+#endif
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ /* Do not waste too much time if we already have a good match: */
+ if (s->prev_length >= s->good_match) {
+ chain_length >>= 2;
+ }
+ /* Do not look for matches beyond the end of the input. This is necessary
+ * to make deflate deterministic.
+ */
+ if ((uInt)nice_match > s->lookahead) nice_match = (int )s->lookahead; /*MAB casts */
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ do {
+ Assert(cur_match < s->strstart, "no future");
+ match = s->window + cur_match;
+
+ /* Skip to next match if the match length cannot increase
+ * or if the match length is less than 2. Note that the checks below
+ * for insufficient lookahead only occur occasionally for performance
+ * reasons. Therefore uninitialized memory will be accessed, and
+ * conditional jumps will be made that depend on those values.
+ * However the length of the match is limited to the lookahead, so
+ * the output of deflate is not affected by the uninitialized values.
+ */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+ /* This code assumes sizeof(unsigned short) == 2. Do not use
+ * UNALIGNED_OK if your compiler uses a different size.
+ */
+ if (*(ushf*)(match+best_len-1) != scan_end ||
+ *(ushf*)match != scan_start) continue;
+
+ /* It is not necessary to compare scan[2] and match[2] since they are
+ * always equal when the other bytes match, given that the hash keys
+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
+ * lookahead only every 4th comparison; the 128th check will be made
+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+ * necessary to put more guard bytes at the end of the window, or
+ * to check more often for insufficient lookahead.
+ */
+ Assert(scan[2] == match[2], "scan[2]?");
+ scan++, match++;
+ do {
+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ scan < strend);
+ /* The funny "do {}" generates better code on most compilers */
+
+ /* Here, scan <= window+strstart+257 */
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+ if (*scan == *match) scan++;
+
+ len = (MAX_MATCH - 1) - (int)(strend-scan);
+ scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+ if (match[best_len] != scan_end ||
+ match[best_len-1] != scan_end1 ||
+ *match != *scan ||
+ *++match != scan[1]) continue;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match++;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+#if 0
+
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+#else
+ /*MAB: to silence compiler warning, intel 981*/
+ do {
+ ++scan; ++match; if (*scan != *match) break;
+ ++scan; ++match; if (*scan != *match) break;
+ ++scan; ++match; if (*scan != *match) break;
+ ++scan; ++match; if (*scan != *match) break;
+
+ ++scan; ++match; if (*scan != *match) break;
+ ++scan; ++match; if (*scan != *match) break;
+ ++scan; ++match; if (*scan != *match) break;
+ ++scan; ++match; if (*scan != *match) break;
+ } while (scan < strend);
+#endif
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+ scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+ if (len > best_len) {
+ s->match_start = cur_match;
+ best_len = len;
+ if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+ scan_end = *(ushf*)(scan+best_len-1);
+#else
+ scan_end1 = scan[best_len-1];
+ scan_end = scan[best_len];
+#endif
+ }
+ } while ((cur_match = prev[cur_match & wmask]) > limit
+ && --chain_length != 0);
+
+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+ return s->lookahead;
+}
+#endif /* ASMV */
+#endif /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for level == 1 or strategy == Z_RLE only
+ */
+local uInt longest_match_fast(deflate_state *s, IPos cur_match)
+
+ /* current match */
+{
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ Assert(cur_match < s->strstart, "no future");
+
+ match = s->window + cur_match;
+
+ /* Return failure if the match length is less than 2:
+ */
+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match += 2;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+#if 0
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+#else
+ /*MAB: to silence compiler warning, intel 981*/
+ do {
+ ++scan; ++match; if (*scan != *match) break;
+ ++scan; ++match; if (*scan != *match) break;
+ ++scan; ++match; if (*scan != *match) break;
+ ++scan; ++match; if (*scan != *match) break;
+
+ ++scan; ++match; if (*scan != *match) break;
+ ++scan; ++match; if (*scan != *match) break;
+ ++scan; ++match; if (*scan != *match) break;
+ ++scan; ++match; if (*scan != *match) break;
+ } while (scan < strend);
+#endif
+
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+
+ if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+ s->match_start = cur_match;
+ return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+ deflate_state *s;
+ IPos start, match;
+ int length;
+{
+ /* check that the match is indeed a match */
+ if (zmemcmp(s->window + match,
+ s->window + start, (size_t)length) != EQUAL) { /*MAB add size_t cast */
+ fprintf(stderr, " start %u, match %u, length %d\n",
+ start, match, length);
+ do {
+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+ } while (--length != 0);
+ z_error("invalid match");
+ }
+ if (z_verbose > 1) {
+ fprintf(stderr,"\\[%d,%d]", start-match, length);
+ do { putc(s->window[start++], stderr); } while (--length != 0);
+ }
+}
+#else
+# define check_match(s, start, match, length)
+#endif /* DEBUG */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ * At least one byte has been read, or avail_in == 0; reads are
+ * performed for at least two bytes (required for the zip translate_eol
+ * option -- not supported here).
+ */
+local void fill_window(deflate_state *s)
+{
+ register unsigned n, m;
+ register Posf *p;
+ unsigned more; /* Amount of free space at the end of the window. */
+ uInt wsize = s->w_size;
+
+ do {
+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+#ifdef _MSC_VER
+#pragma warning(disable:4127)
+#endif
+ /* Deal with !@#$% 64K limit: */
+ if (sizeof(int) <= 2) {
+
+#ifdef _MSC_VER
+#pragma warning(default:4127)
+#endif
+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+ more = wsize;
+
+ } else if (more == (unsigned)(-1)) {
+ /* Very unlikely, but possible on 16 bit machine if
+ * strstart == 0 && lookahead == 1 (input done a byte at time)
+ */
+ more--;
+ }
+ }
+
+ /* If the window is almost full and there is insufficient lookahead,
+ * move the upper half to the lower one to make room in the upper half.
+ */
+ if (s->strstart >= wsize+MAX_DIST(s)) {
+
+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+ s->match_start -= wsize;
+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
+ s->block_start -= (long) wsize;
+
+ /* Slide the hash table (could be avoided with 32 bit values
+ at the expense of memory usage). We slide even when level == 0
+ to keep the hash table consistent if we switch back to level > 0
+ later. (Using level 0 permanently is not an optimal usage of
+ zlib, so we don't care about this pathological case.)
+ */
+ /* %%% avoid this when Z_RLE */
+ n = s->hash_size;
+ p = &s->head[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ } while (--n);
+
+ n = wsize;
+#ifndef FASTEST
+ p = &s->prev[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ /* If n is not on any hash chain, prev[n] is garbage but
+ * its value will never be used.
+ */
+ } while (--n);
+#endif
+ more += wsize;
+ }
+ if (s->strm->avail_in == 0) return;
+
+ /* If there was no sliding:
+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+ * more == window_size - lookahead - strstart
+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+ * => more >= window_size - 2*WSIZE + 2
+ * In the BIG_MEM or MMAP case (not yet supported),
+ * window_size == input_size + MIN_LOOKAHEAD &&
+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+ * Otherwise, window_size == 2*WSIZE so more >= 2.
+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+ */
+ Assert(more >= 2, "more < 2");
+
+ n = (unsigned)read_buf(s->strm, s->window + s->strstart + s->lookahead, more); /*MAB casts */
+ s->lookahead += n;
+
+ /* Initialize the hash value now that we have some input: */
+ if (s->lookahead >= MIN_MATCH) {
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ }
+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+ * but this is not important since only literal bytes will be emitted.
+ */
+
+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+ _tr_flush_block(s, (s->block_start >= 0L ? \
+ (charf *)&s->window[(unsigned)s->block_start] : \
+ (charf *)Z_NULL), \
+ (ulg)((long)s->strstart - s->block_start), \
+ (eof)); \
+ s->block_start = (long)s->strstart; /*MAB casts*/\
+ flush_pending(s->strm); \
+ Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+ FLUSH_BLOCK_ONLY(s, eof); \
+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(deflate_state *s, int flush)
+{
+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+ * to pending_buf_size, and each stored block has a 5 byte header:
+ */
+ ulg max_block_size = 0xffff;
+ ulg max_start;
+
+ if (max_block_size > s->pending_buf_size - 5) {
+ max_block_size = s->pending_buf_size - 5;
+ }
+
+ /* Copy as much as possible from input to output: */
+ for (;;) {
+ /* Fill the window as much as possible: */
+ if (s->lookahead <= 1) {
+
+ Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+ s->block_start >= (long)s->w_size, "slide too late");
+
+ fill_window(s);
+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+ Assert(s->block_start >= 0L, "block gone");
+
+ s->strstart += s->lookahead;
+ s->lookahead = 0;
+
+ /* Emit a stored block if pending_buf will be full: */
+ max_start = (ulg)((ulg)s->block_start + (ulg)max_block_size); /*MAB casts */
+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+ /* strstart == 0 is possible when wraparound on 16-bit machine */
+ s->lookahead = (uInt)(s->strstart - max_start);
+ s->strstart = (uInt)max_start;
+ FLUSH_BLOCK(s, 0);
+ }
+ /* Flush if we may have to slide, otherwise block_start may become
+ * negative and the data will be gone:
+ */
+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+ FLUSH_BLOCK(s, 0);
+ }
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(deflate_state *s, int flush)
+{
+ IPos hash_head = NIL; /* head of the hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ * At this point we have always match_length < MIN_MATCH
+ */
+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+#ifdef FASTEST
+ if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
+ (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+#else
+ if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
+ s->match_length = longest_match (s, hash_head);
+ } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+#endif
+ /* longest_match() or longest_match_fast() sets match_start */
+ }
+ if (s->match_length >= MIN_MATCH) {
+ check_match(s, s->strstart, s->match_start, (int)s->match_length); /*MAB cast with int */
+
+ _tr_tally_dist(s, s->strstart - s->match_start,
+ s->match_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->match_length;
+
+ /* Insert new strings in the hash table only if the match length
+ * is not too large. This saves time but degrades compression.
+ */
+#ifndef FASTEST
+ if (s->match_length <= s->max_insert_length &&
+ s->lookahead >= MIN_MATCH) {
+ s->match_length--; /* string at strstart already in table */
+ do {
+ s->strstart++;
+ INSERT_STRING(s, s->strstart, hash_head);
+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+ * always MIN_MATCH bytes ahead.
+ */
+ } while (--s->match_length != 0);
+ s->strstart++;
+ } else
+#endif
+ {
+ s->strstart += s->match_length;
+ s->match_length = 0;
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+ * matter since it will be recomputed at next deflate call.
+ */
+ }
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(deflate_state *s, int flush)
+{
+ IPos hash_head = NIL; /* head of hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ /* Process the input block. */
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ */
+ s->prev_length = s->match_length, s->prev_match = s->match_start;
+ s->match_length = MIN_MATCH-1;
+
+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+ s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+ if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
+ s->match_length = longest_match (s, hash_head);
+ } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+ /* longest_match() or longest_match_fast() sets match_start */
+
+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+ || (s->match_length == MIN_MATCH &&
+ s->strstart - s->match_start > TOO_FAR)
+#endif
+ )) {
+
+ /* If prev_match is also MIN_MATCH, match_start is garbage
+ * but we will ignore the current match anyway.
+ */
+ s->match_length = MIN_MATCH-1;
+ }
+ }
+ /* If there was a match at the previous step and the current
+ * match is not better, output the previous match:
+ */
+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+ /* Do not insert strings in hash table beyond this. */
+
+ check_match(s, s->strstart-1, s->prev_match, (int)s->prev_length); /*MAB cast with int */
+
+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+ s->prev_length - MIN_MATCH, bflush);
+
+ /* Insert in hash table all strings up to the end of the match.
+ * strstart-1 and strstart are already inserted. If there is not
+ * enough lookahead, the last two strings are not inserted in
+ * the hash table.
+ */
+ s->lookahead -= s->prev_length-1;
+ s->prev_length -= 2;
+ do {
+ if (++s->strstart <= max_insert) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+ } while (--s->prev_length != 0);
+ s->match_available = 0;
+ s->match_length = MIN_MATCH-1;
+ s->strstart++;
+
+ if (bflush) FLUSH_BLOCK(s, 0);
+
+ } else if (s->match_available) {
+ /* If there was no match at the previous position, output a
+ * single literal. If there was a match but the current match
+ * is longer, truncate the previous match to a single literal.
+ */
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ if (bflush) {
+ FLUSH_BLOCK_ONLY(s, 0);
+ }
+ s->strstart++;
+ s->lookahead--;
+ if (s->strm->avail_out == 0) return need_more;
+ } else {
+ /* There is no previous match to compare with, wait for
+ * the next step to decide.
+ */
+ s->match_available = 1;
+ s->strstart++;
+ s->lookahead--;
+ }
+ }
+ Assert (flush != Z_NO_FLUSH, "no flush?");
+ if (s->match_available) {
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ s->match_available = 0;
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+#endif /* FASTEST */
+
+#if 0
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one. Do not maintain a hash table. (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+local block_state deflate_rle(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ int bflush; /* set if current block must be flushed */
+ uInt run; /* length of run */
+ uInt max; /* maximum length of run */
+ uInt prev; /* byte at distance one to match */
+ Bytef *scan; /* scan for end of run */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the longest encodable run.
+ */
+ if (s->lookahead < MAX_MATCH) {
+ fill_window(s);
+ if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* See how many times the previous byte repeats */
+ run = 0;
+ if (s->strstart > 0) { /* if there is a previous byte, that is */
+ max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
+ scan = s->window + s->strstart - 1;
+ prev = *scan++;
+ do {
+ if (*scan++ != prev)
+ break;
+ } while (++run < max);
+ }
+
+ /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+ if (run >= MIN_MATCH) {
+ check_match(s, s->strstart, s->strstart - 1, run);
+ _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
+ s->lookahead -= run;
+ s->strstart += run;
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+#endif
diff --git a/DroidFish/jni/gtb/compression/zlib/deflate.h b/DroidFish/jni/gtb/compression/zlib/deflate.h
new file mode 100644
index 0000000..422340f
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/deflate.h
@@ -0,0 +1,350 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2004 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer creation by deflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip encoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS 256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES 30
+/* number of distance codes */
+
+#define BL_CODES 19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE 42
+#define EXTRA_STATE 69
+#define NAME_STATE 73
+#define COMMENT_STATE 91
+#define HCRC_STATE 103
+#define BUSY_STATE 113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+ union fc {
+ ush freq; /* frequency count */
+ ush code; /* bit string */
+ } fc;
+ union dl {
+ ush dad; /* father node in Huffman tree */
+ ush len; /* length of bit string */
+ } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad dl.dad
+#define Len dl.len
+
+typedef struct static_tree_desc_s static_tree_desc;
+
+typedef struct tree_desc_s {
+ ct_data *dyn_tree; /* the dynamic tree */
+ int max_code; /* largest code with non zero frequency */
+ static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+ z_streamp strm; /* pointer back to this zlib stream */
+ int status; /* as the name implies */
+ Bytef *pending_buf; /* output still pending */
+ ulg pending_buf_size; /* size of pending_buf */
+ Bytef *pending_out; /* next pending byte to output to the stream */
+ uInt pending; /* nb of bytes in the pending buffer */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ gz_headerp gzhead; /* gzip header information to write */
+ uInt gzindex; /* where in extra, name, or comment */
+ Byte method; /* STORED (for zip only) or DEFLATED */
+ int last_flush; /* value of flush param for previous deflate call */
+
+ /* used by deflate.c: */
+
+ uInt w_size; /* LZ77 window size (32K by default) */
+ uInt w_bits; /* log2(w_size) (8..16) */
+ uInt w_mask; /* w_size - 1 */
+
+ Bytef *window;
+ /* Sliding window. Input bytes are read into the second half of the window,
+ * and move to the first half later to keep a dictionary of at least wSize
+ * bytes. With this organization, matches are limited to a distance of
+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
+ * performed with a length multiple of the block size. Also, it limits
+ * the window size to 64K, which is quite useful on MSDOS.
+ * To do: use the user input buffer as sliding window.
+ */
+
+ ulg window_size;
+ /* Actual size of window: 2*wSize, except when the user input buffer
+ * is directly used as sliding window.
+ */
+
+ Posf *prev;
+ /* Link to older string with same hash index. To limit the size of this
+ * array to 64K, this link is maintained only for the last 32K strings.
+ * An index in this array is thus a window index modulo 32K.
+ */
+
+ Posf *head; /* Heads of the hash chains or NIL. */
+
+ uInt ins_h; /* hash index of string to be inserted */
+ uInt hash_size; /* number of elements in hash table */
+ uInt hash_bits; /* log2(hash_size) */
+ uInt hash_mask; /* hash_size-1 */
+
+ uInt hash_shift;
+ /* Number of bits by which ins_h must be shifted at each input
+ * step. It must be such that after MIN_MATCH steps, the oldest
+ * byte no longer takes part in the hash key, that is:
+ * hash_shift * MIN_MATCH >= hash_bits
+ */
+
+ long block_start;
+ /* Window position at the beginning of the current output block. Gets
+ * negative when the window is moved backwards.
+ */
+
+ uInt match_length; /* length of best match */
+ IPos prev_match; /* previous match */
+ int match_available; /* set if previous match exists */
+ uInt strstart; /* start of string to insert */
+ uInt match_start; /* start of matching string */
+ uInt lookahead; /* number of valid bytes ahead in window */
+
+ uInt prev_length;
+ /* Length of the best match at previous step. Matches not greater than this
+ * are discarded. This is used in the lazy match evaluation.
+ */
+
+ uInt max_chain_length;
+ /* To speed up deflation, hash chains are never searched beyond this
+ * length. A higher limit improves compression ratio but degrades the
+ * speed.
+ */
+
+ uInt max_lazy_match;
+ /* Attempt to find a better match only when the current match is strictly
+ * smaller than this value. This mechanism is used only for compression
+ * levels >= 4.
+ */
+# define max_insert_length max_lazy_match
+ /* Insert new strings in the hash table only if the match length is not
+ * greater than this length. This saves time but degrades compression.
+ * max_insert_length is used only for compression levels <= 3.
+ */
+
+ int level; /* compression level (1..9) */
+ int strategy; /* favor or force Huffman coding*/
+
+ uInt good_match;
+ /* Use a faster search when the previous match is longer than this */
+
+ int nice_match; /* Stop searching when current match exceeds this */
+
+ /* used by trees.c: */
+ /* Didn't use ct_data typedef below to supress compiler warning */
+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
+
+ struct tree_desc_s l_desc; /* desc. for literal tree */
+ struct tree_desc_s d_desc; /* desc. for distance tree */
+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
+
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
+ int heap_len; /* number of elements in the heap */
+ int heap_max; /* element of largest frequency */
+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+ * The same heap array is used to build all trees.
+ */
+
+ uch depth[2*L_CODES+1];
+ /* Depth of each subtree used as tie breaker for trees of equal frequency
+ */
+
+ uchf *l_buf; /* buffer for literals or lengths */
+
+ uInt lit_bufsize;
+ /* Size of match buffer for literals/lengths. There are 4 reasons for
+ * limiting lit_bufsize to 64K:
+ * - frequencies can be kept in 16 bit counters
+ * - if compression is not successful for the first block, all input
+ * data is still in the window so we can still emit a stored block even
+ * when input comes from standard input. (This can also be done for
+ * all blocks if lit_bufsize is not greater than 32K.)
+ * - if compression is not successful for a file smaller than 64K, we can
+ * even emit a stored file instead of a stored block (saving 5 bytes).
+ * This is applicable only for zip (not gzip or zlib).
+ * - creating new Huffman trees less frequently may not provide fast
+ * adaptation to changes in the input data statistics. (Take for
+ * example a binary file with poorly compressible code followed by
+ * a highly compressible string table.) Smaller buffer sizes give
+ * fast adaptation but have of course the overhead of transmitting
+ * trees more frequently.
+ * - I can't count above 4
+ */
+
+ uInt last_lit; /* running index in l_buf */
+
+ ushf *d_buf;
+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
+ * the same number of elements. To use different lengths, an extra flag
+ * array would be necessary.
+ */
+
+ ulg opt_len; /* bit length of current block with optimal trees */
+ ulg static_len; /* bit length of current block with static trees */
+ uInt matches; /* number of string matches in current block */
+ int last_eob_len; /* bit length of EOB code for last block */
+
+#ifdef DEBUG
+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
+#endif
+
+ ush bi_buf;
+ /* Output buffer. bits are inserted starting at the bottom (least
+ * significant bits).
+ */
+ int bi_valid;
+ /* Number of valid bits in bi_buf. All bits above the last valid bit
+ * are always zero.
+ */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+/*MAB: Cast (z_Bytef) to silence compiler */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (z_Bytef)(c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+ /* in trees.c */
+void _tr_init OF((deflate_state *s));
+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+void _tr_align OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+
+#define d_code(dist) \
+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+ extern uch _length_code[];
+ extern uch _dist_code[];
+#else
+ extern const uch _length_code[];
+ extern const uch _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+ { uch cc = (c); \
+ s->d_buf[s->last_lit] = 0; \
+ s->l_buf[s->last_lit++] = cc; \
+ s->dyn_ltree[cc].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+/*
+# define _tr_tally_dist(s, distance, length, flush) \
+ { uch len = (length); \
+ ush dist = (distance); \
+ s->d_buf[s->last_lit] = dist; \
+ s->l_buf[s->last_lit++] = len; \
+ dist--; \
+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+ s->dyn_dtree[d_code(dist)].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+*/
+/*MAB: Modify the top function to silence compiler with (uch) and (ush) casts */
+# define _tr_tally_dist(s, distance, length, flush) \
+ { uch len = (uch )(length); \
+ ush dist = (ush) (distance); \
+ s->d_buf[s->last_lit] = dist; \
+ s->l_buf[s->last_lit++] = len; \
+ dist--; \
+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+ s->dyn_dtree[d_code(dist)].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+
+
+
+
+
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+ flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */
diff --git a/DroidFish/jni/gtb/compression/zlib/infback.c b/DroidFish/jni/gtb/compression/zlib/infback.c
new file mode 100644
index 0000000..e571d51
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/infback.c
@@ -0,0 +1,620 @@
+/* infback.c -- inflate using a call-back interface
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ This code is largely copied from inflate.c. Normally either infback.o or
+ inflate.o would be linked into an application--not both. The interface
+ with inffast.c is retained so that optimized assembler-coded versions of
+ inflate_fast() can be used with either inflate.c or infback.c.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+
+/*
+ strm provides memory allocation functions in zalloc and zfree, or
+ Z_NULL to use the library memory allocation functions.
+
+ windowBits is in the range 8..15, and window is a user-supplied
+ window and output buffer that is 2**windowBits bytes.
+ */
+int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, unsigned char *window, const char *version, int stream_size)
+{
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL || window == Z_NULL ||
+ windowBits < 8 || windowBits > 15)
+ return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+ sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (struct internal_state FAR *)state;
+ state->dmax = 32768U;
+ state->wbits = (unsigned)windowBits; /*MAB casts */
+ state->wsize = 1U << windowBits;
+ state->window = window;
+ state->write = 0;
+ state->whave = 0;
+ return Z_OK;
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(struct inflate_state *state)
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+/* Macros for inflateBack(): */
+
+/* Load returned state from inflate_fast() */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Set state from registers for inflate_fast() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Assure that some input is available. If input is requested, but denied,
+ then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+ do { \
+ if (have == 0) { \
+ have = in(in_desc, &next); \
+ if (have == 0) { \
+ next = Z_NULL; \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+ with an error if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ PULL(); \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflateBack() with
+ an error. */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/* Assure that some output space is available, by writing out the window
+ if it's full. If the write fails, return from inflateBack() with a
+ Z_BUF_ERROR. */
+#define ROOM() \
+ do { \
+ if (left == 0) { \
+ put = state->window; \
+ left = state->wsize; \
+ state->whave = left; \
+ if (out(out_desc, put, left)) { \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/*
+ strm provides the memory allocation functions and window buffer on input,
+ and provides information on the unused input on return. For Z_DATA_ERROR
+ returns, strm will also provide an error message.
+
+ in() and out() are the call-back input and output functions. When
+ inflateBack() needs more input, it calls in(). When inflateBack() has
+ filled the window with output, or when it completes with data in the
+ window, it calls out() to write out the data. The application must not
+ change the provided input until in() is called again or inflateBack()
+ returns. The application must not change the window/output buffer until
+ inflateBack() returns.
+
+ in() and out() are called with a descriptor parameter provided in the
+ inflateBack() call. This parameter can be a structure that provides the
+ information required to do the read or write, as well as accumulated
+ information on the input and output such as totals and check values.
+
+ in() should return zero on failure. out() should return non-zero on
+ failure. If either in() or out() fails, than inflateBack() returns a
+ Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
+ was in() or out() that caused in the error. Otherwise, inflateBack()
+ returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+ error, or Z_MEM_ERROR if it could not allocate memory for the state.
+ inflateBack() can also return Z_STREAM_ERROR if the input parameters
+ are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+
+#ifdef _MSC_VER
+#pragma warning(disable:4127)
+#endif
+
+int ZEXPORT inflateBack(z_streamp strm, in_func in, void *in_desc, out_func out, void *out_desc)
+{
+ struct inflate_state FAR *state;
+ unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code this; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ /* Check that the strm exists and that the state was initialized */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* Reset the state */
+ strm->msg = Z_NULL;
+ state->mode = TYPE;
+ state->last = 0;
+ state->whave = 0;
+ next = strm->next_in;
+ have = next != Z_NULL ? strm->avail_in : 0;
+ hold = 0;
+ bits = 0;
+ put = state->window;
+ left = state->wsize;
+
+ /* Inflate until end of block marked as last */
+ for (;;)
+ switch (state->mode) {
+ case TYPE:
+ /* determine and dispatch block type */
+ if (state->last) {
+ BYTEBITS();
+ state->mode = DONE;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN; /* decode codes */
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+
+ case STORED:
+ /* get and verify stored block length */
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+
+ /* copy stored block from input to output */
+ while (state->length != 0) {
+ copy = state->length;
+ PULL();
+ ROOM();
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+
+ case TABLE:
+ /* get dynamic table entries descriptor */
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+
+ /* get code length code lengths (not a typo) */
+ state->have = 0;
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+
+ /* get length and distance code code lengths */
+ state->have = 0;
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.val < 16) {
+ NEEDBITS(this.bits);
+ DROPBITS(this.bits);
+ state->lens[state->have++] = this.val;
+ }
+ else {
+ if (this.val == 16) {
+ NEEDBITS(this.bits + 2);
+ DROPBITS(this.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = (unsigned)(state->lens[state->have - 1]);
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (this.val == 17) {
+ NEEDBITS(this.bits + 3);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(this.bits + 7);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state->mode == BAD) break;
+
+ /* build code tables */
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (code const FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN;
+
+ case LEN:
+ /* use inflate_fast() if we have enough input and output */
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ if (state->whave < state->wsize)
+ state->whave = state->wsize - left;
+ inflate_fast(strm, state->wsize);
+ LOAD();
+ break;
+ }
+
+ /* get a literal, length, or end-of-block code */
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.op && (this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ state->length = (unsigned)this.val;
+
+ /* process literal */
+ if (this.op == 0) {
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ ROOM();
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ }
+
+ /* process end of block */
+ if (this.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+
+ /* invalid code */
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+
+ /* length code -- get extra bits, if any */
+ state->extra = (unsigned)(this.op) & 15;
+ if (state->extra != 0) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+
+ /* get distance code */
+ for (;;) {
+ this = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)this.val;
+
+ /* get distance extra bits, if any */
+ state->extra = (unsigned)(this.op) & 15;
+ if (state->extra != 0) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ if (state->offset > state->wsize - (state->whave < state->wsize ?
+ left : 0)) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+
+ /* copy match from window to output */
+ do {
+ ROOM();
+ copy = state->wsize - state->offset;
+ if (copy < left) {
+ from = put + copy;
+ copy = left - copy;
+ }
+ else {
+ from = put - state->offset;
+ copy = left;
+ }
+ if (copy > state->length) copy = state->length;
+ state->length -= copy;
+ left -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ } while (state->length != 0);
+ break;
+
+ case DONE:
+ /* inflate stream terminated properly -- write leftover output */
+ ret = Z_STREAM_END;
+ if (left < state->wsize) {
+ if (out(out_desc, state->window, state->wsize - left))
+ ret = Z_BUF_ERROR;
+ }
+ goto inf_leave;
+
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+
+ default: /* can't happen, but makes compilers happy */
+ ret = Z_STREAM_ERROR;
+ goto inf_leave;
+ }
+
+ /* Return unused input */
+ inf_leave:
+ strm->next_in = next;
+ strm->avail_in = have;
+ return ret;
+}
+
+#ifdef _MSC_VER
+#pragma warning(default:4127)
+#endif
+
+int ZEXPORT inflateBackEnd(z_streamp strm)
+{
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
diff --git a/DroidFish/jni/gtb/compression/zlib/inffast.c b/DroidFish/jni/gtb/compression/zlib/inffast.c
new file mode 100644
index 0000000..e9400eb
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/inffast.c
@@ -0,0 +1,318 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifndef ASMINF
+
+/* Allow machine dependent optimization for post-increment or pre-increment.
+ Based on testing to date,
+ Pre-increment preferred for:
+ - PowerPC G3 (Adler)
+ - MIPS R5000 (Randers-Pehrson)
+ Post-increment preferred for:
+ - none
+ No measurable difference:
+ - Pentium III (Anderson)
+ - M68060 (Nikl)
+ */
+#ifdef POSTINC
+# define OFF 0
+# define PUP(a) *(a)++
+#else
+# define OFF 1
+# define PUP(a) *++(a)
+#endif
+
+/*
+ Decode literal, length, and distance codes and write out the resulting
+ literal and match bytes until either not enough input or output is
+ available, an end-of-block is encountered, or a data error is encountered.
+ When large enough input and output buffers are supplied to inflate(), for
+ example, a 16K input buffer and a 64K output buffer, more than 95% of the
+ inflate execution time is spent in this routine.
+
+ Entry assumptions:
+
+ state->mode == LEN
+ strm->avail_in >= 6
+ strm->avail_out >= 258
+ start >= strm->avail_out
+ state->bits < 8
+
+ On return, state->mode is one of:
+
+ LEN -- ran out of enough output space or enough available input
+ TYPE -- reached end of block code, inflate() to interpret next block
+ BAD -- error in block data
+
+ Notes:
+
+ - The maximum input bits used by a length/distance pair is 15 bits for the
+ length code, 5 bits for the length extra, 15 bits for the distance code,
+ and 13 bits for the distance extra. This totals 48 bits, or six bytes.
+ Therefore if strm->avail_in >= 6, then there is enough input to avoid
+ checking for available input while decoding.
+
+ - The maximum bytes that a single length/distance pair can output is 258
+ bytes, which is the maximum length that can be coded. inflate_fast()
+ requires strm->avail_out >= 258 for each loop to avoid checking for
+ output space.
+ */
+void inflate_fast(z_streamp strm, unsigned int start)
+
+ /* inflate()'s starting value for strm->avail_out */
+{
+ struct inflate_state FAR *state;
+ unsigned char FAR *in; /* local strm->next_in */
+ unsigned char FAR *last; /* while in < last, enough input available */
+ unsigned char FAR *out; /* local strm->next_out */
+ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
+ unsigned char FAR *end; /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+ unsigned dmax; /* maximum distance from zlib header */
+#endif
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned write; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
+ unsigned long hold; /* local strm->hold */
+ unsigned bits; /* local strm->bits */
+ code const FAR *lcode; /* local strm->lencode */
+ code const FAR *dcode; /* local strm->distcode */
+ unsigned lmask; /* mask for first level of length codes */
+ unsigned dmask; /* mask for first level of distance codes */
+ code this; /* retrieved table entry */
+ unsigned op; /* code bits, operation, extra bits, or */
+ /* window position, window bytes to copy */
+ unsigned len; /* match length, unused bytes */
+ unsigned dist; /* match distance */
+ unsigned char FAR *from; /* where to copy match from */
+
+ /* copy state to local variables */
+ state = (struct inflate_state FAR *)strm->state;
+ in = strm->next_in - OFF;
+ last = in + (strm->avail_in - 5);
+ out = strm->next_out - OFF;
+ beg = out - (start - strm->avail_out);
+ end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+ dmax = state->dmax;
+#endif
+ wsize = state->wsize;
+ whave = state->whave;
+ write = state->write;
+ window = state->window;
+ hold = state->hold;
+ bits = state->bits;
+ lcode = state->lencode;
+ dcode = state->distcode;
+ lmask = (1U << state->lenbits) - 1;
+ dmask = (1U << state->distbits) - 1;
+
+ /* decode literals and length/distances until end-of-block or not enough
+ input data or output space */
+ do {
+ if (bits < 15) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ this = lcode[hold & lmask];
+ dolen:
+ op = (unsigned)(this.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(this.op);
+ if (op == 0) { /* literal */
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ PUP(out) = (unsigned char)(this.val);
+ }
+ else if (op & 16) { /* length base */
+ len = (unsigned)(this.val);
+ op &= 15; /* number of extra bits */
+ if (op) {
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ len += (unsigned)hold & ((1U << op) - 1);
+ hold >>= op;
+ bits -= op;
+ }
+ Tracevv((stderr, "inflate: length %u\n", len));
+ if (bits < 15) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ this = dcode[hold & dmask];
+ dodist:
+ op = (unsigned)(this.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(this.op);
+ if (op & 16) { /* distance base */
+ dist = (unsigned)(this.val);
+ op &= 15; /* number of extra bits */
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ }
+ dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+ if (dist > dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ hold >>= op;
+ bits -= op;
+ Tracevv((stderr, "inflate: distance %u\n", dist));
+ op = (unsigned)(out - beg); /* max distance in output */
+ if (dist > op) { /* see if copy from window */
+ op = dist - op; /* distance back in window */
+ if (op > whave) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ from = window - OFF;
+ if (write == 0) { /* very common case */
+ from += wsize - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ else if (write < op) { /* wrap around window */
+ from += wsize + write - op;
+ op -= write;
+ if (op < len) { /* some from end of window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = window - OFF;
+ if (write < len) { /* some from start of window */
+ op = write;
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ }
+ else { /* contiguous in window */
+ from += write - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ while (len > 2) {
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ len -= 3;
+ }
+ if (len) {
+ PUP(out) = PUP(from);
+ if (len > 1)
+ PUP(out) = PUP(from);
+ }
+ }
+ else {
+ from = out - dist; /* copy direct from output */
+ do { /* minimum length is three */
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ len -= 3;
+ } while (len > 2);
+ if (len) {
+ PUP(out) = PUP(from);
+ if (len > 1)
+ PUP(out) = PUP(from);
+ }
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level distance code */
+ this = dcode[this.val + (hold & ((1U << op) - 1))];
+ goto dodist;
+ }
+ else {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level length code */
+ this = lcode[this.val + (hold & ((1U << op) - 1))];
+ goto dolen;
+ }
+ else if (op & 32) { /* end-of-block */
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+ else {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ } while (in < last && out < end);
+
+ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+ len = bits >> 3;
+ in -= len;
+ bits -= len << 3;
+ hold &= (1U << bits) - 1;
+
+ /* update state and return */
+ strm->next_in = in + OFF;
+ strm->next_out = out + OFF;
+ strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+ strm->avail_out = (unsigned)(out < end ?
+ 257 + (end - out) : 257 - (out - end));
+ state->hold = hold;
+ state->bits = bits;
+ return;
+}
+
+/*
+ inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+ - Using bit fields for code structure
+ - Different op definition to avoid & for extra bits (do & for table bits)
+ - Three separate decoding do-loops for direct, window, and write == 0
+ - Special case for distance > 1 copies to do overlapped load and store copy
+ - Explicit branch predictions (based on measured branch probabilities)
+ - Deferring match copy and interspersed it with decoding subsequent codes
+ - Swapping literal/length else
+ - Swapping window/direct else
+ - Larger unrolled copy loops (three is about right)
+ - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
diff --git a/DroidFish/jni/gtb/compression/zlib/inffast.h b/DroidFish/jni/gtb/compression/zlib/inffast.h
new file mode 100644
index 0000000..1e88d2d
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/inffast.h
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+void inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/DroidFish/jni/gtb/compression/zlib/inffixed.h b/DroidFish/jni/gtb/compression/zlib/inffixed.h
new file mode 100644
index 0000000..75ed4b5
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/inffixed.h
@@ -0,0 +1,94 @@
+ /* inffixed.h -- table for decoding fixed codes
+ * Generated automatically by makefixed().
+ */
+
+ /* WARNING: this file should *not* be used by applications. It
+ is part of the implementation of the compression library and
+ is subject to change. Applications should only use zlib.h.
+ */
+
+ static const code lenfix[512] = {
+ {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+ {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+ {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+ {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+ {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+ {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+ {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+ {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+ {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+ {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+ {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+ {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+ {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+ {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+ {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+ {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+ {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+ {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+ {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+ {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+ {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+ {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+ {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+ {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+ {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+ {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+ {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+ {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+ {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+ {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+ {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+ {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+ {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+ {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+ {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+ {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+ {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+ {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+ {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+ {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+ {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+ {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+ {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+ {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+ {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+ {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+ {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+ {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+ {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+ {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+ {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+ {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+ {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+ {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+ {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+ {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+ {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+ {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+ {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+ {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+ {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+ {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+ {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+ {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+ {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+ {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+ {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+ {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+ {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+ {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+ {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+ {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+ {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+ {0,9,255}
+ };
+
+ static const code distfix[32] = {
+ {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+ {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+ {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+ {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+ {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+ {22,5,193},{64,5,0}
+ };
diff --git a/DroidFish/jni/gtb/compression/zlib/inflate.c b/DroidFish/jni/gtb/compression/zlib/inflate.c
new file mode 100644
index 0000000..16b95d0
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/inflate.c
@@ -0,0 +1,1348 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0 24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ * creation of window when not needed, minimize use of window when it is
+ * needed, make inffast.c even faster, implement gzip decoding, and to
+ * improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1 25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2 4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ * to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3 22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ * buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4 1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common write == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ * source file infback.c to provide a call-back interface to inflate for
+ * programs like gzip and unzip -- uses window as output buffer to avoid
+ * window copying
+ *
+ * 1.2.beta5 1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ * input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6 4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ * make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7 27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0 9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ * for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ * and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+# ifndef BUILDFIXED
+# define BUILDFIXED
+# endif
+#endif
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, unsigned out));
+#ifdef BUILDFIXED
+ void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
+ unsigned len));
+
+int ZEXPORT inflateReset(z_streamp strm)
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ strm->total_in = strm->total_out = state->total = 0;
+ strm->msg = Z_NULL;
+ strm->adler = 1; /* to support ill-conceived Java test suite */
+ state->mode = HEAD;
+ state->last = 0;
+ state->havedict = 0;
+ state->dmax = 32768U;
+ state->head = Z_NULL;
+ state->wsize = 0;
+ state->whave = 0;
+ state->write = 0;
+ state->hold = 0;
+ state->bits = 0;
+ state->lencode = state->distcode = state->next = state->codes;
+ Tracev((stderr, "inflate: reset\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflatePrime(z_streamp strm, int bits, int value)
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (bits > 16 || state->bits + (unsigned)bits > 32) return Z_STREAM_ERROR; /*MAB casts */
+ value &= (int) ((1L << bits) - 1); /*MAB casts */
+ state->hold += ((long unsigned)value << state->bits); /*MAB casts */
+ state->bits += (unsigned) bits; /*MAB casts */
+ return Z_OK;
+}
+
+int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, const char *version, int stream_size)
+{
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ state = (struct inflate_state FAR *)
+ ZALLOC(strm, 1, sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (struct internal_state FAR *)state;
+ if (windowBits < 0) {
+ state->wrap = 0;
+ windowBits = -windowBits;
+ }
+ else {
+ state->wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+ if (windowBits < 48) windowBits &= 15;
+#endif
+ }
+ if (windowBits < 8 || windowBits > 15) {
+ ZFREE(strm, state);
+ strm->state = Z_NULL;
+ return Z_STREAM_ERROR;
+ }
+ state->wbits = (unsigned)windowBits;
+ state->window = Z_NULL;
+ return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit_(z_streamp strm, const char *version, int stream_size)
+{
+ return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(struct inflate_state *state)
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include
+
+/*
+ Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
+ defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
+ those tables to stdout, which would be piped to inffixed.h. A small program
+ can simply call makefixed to do this:
+
+ void makefixed(void);
+
+ int main(void)
+ {
+ makefixed();
+ return 0;
+ }
+
+ Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+ a.out > inffixed.h
+ */
+void makefixed()
+{
+ unsigned low, size;
+ struct inflate_state state;
+
+ fixedtables(&state);
+ puts(" /* inffixed.h -- table for decoding fixed codes");
+ puts(" * Generated automatically by makefixed().");
+ puts(" */");
+ puts("");
+ puts(" /* WARNING: this file should *not* be used by applications.");
+ puts(" It is part of the implementation of this library and is");
+ puts(" subject to change. Applications should only use zlib.h.");
+ puts(" */");
+ puts("");
+ size = 1U << 9;
+ printf(" static const code lenfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 7) == 0) printf("\n ");
+ printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
+ state.lencode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+ size = 1U << 5;
+ printf("\n static const code distfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 6) == 0) printf("\n ");
+ printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+ state.distcode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+}
+#endif /* MAKEFIXED */
+
+/*
+ Update the window with the last wsize (normally 32K) bytes written before
+ returning. If window does not exist yet, create it. This is only called
+ when a window is already in use, or when output has been written during this
+ inflate call, but the end of the deflate stream has not been reached yet.
+ It is also called to create a window for dictionary data when a dictionary
+ is loaded.
+
+ Providing output buffers larger than 32K to inflate() should provide a speed
+ advantage, since only the last 32K of output is copied to the sliding window
+ upon return from inflate(), and since all distances after the first 32K of
+ output will fall in the output data, making match copies simpler and faster.
+ The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(z_streamp strm, unsigned int out)
+{
+ struct inflate_state FAR *state;
+ unsigned copy, dist;
+
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* if it hasn't been done already, allocate space for the window */
+ if (state->window == Z_NULL) {
+ state->window = (unsigned char FAR *)
+ ZALLOC(strm, 1U << state->wbits,
+ sizeof(unsigned char));
+ if (state->window == Z_NULL) return 1;
+ }
+
+ /* if window not in use yet, initialize */
+ if (state->wsize == 0) {
+ state->wsize = 1U << state->wbits;
+ state->write = 0;
+ state->whave = 0;
+ }
+
+ /* copy state->wsize or less output bytes into the circular window */
+ copy = out - strm->avail_out;
+ if (copy >= state->wsize) {
+ zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
+ state->write = 0;
+ state->whave = state->wsize;
+ }
+ else {
+ dist = state->wsize - state->write;
+ if (dist > copy) dist = copy;
+ zmemcpy(state->window + state->write, strm->next_out - copy, dist);
+ copy -= dist;
+ if (copy) {
+ zmemcpy(state->window, strm->next_out - copy, copy);
+ state->write = copy;
+ state->whave = state->wsize;
+ }
+ else {
+ state->write += dist;
+ if (state->write == state->wsize) state->write = 0;
+ if (state->whave < state->wsize) state->whave += dist;
+ }
+ }
+ return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+# define UPDATE(check, buf, len) \
+ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+# define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+# define CRC2(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ check = crc32(check, hbuf, 2); \
+ } while (0)
+
+# define CRC4(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ hbuf[2] = (unsigned char)((word) >> 16); \
+ hbuf[3] = (unsigned char)((word) >> 24); \
+ check = crc32(check, hbuf, 4); \
+ } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+ if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ if (have == 0) goto inf_leave; \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/* Reverse the bytes in a 32-bit value */
+#define REVERSE(q) \
+ ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+/*
+ inflate() uses a state machine to process as much input data and generate as
+ much output data as possible before returning. The state machine is
+ structured roughly as follows:
+
+ for (;;) switch (state) {
+ ...
+ case STATEn:
+ if (not enough input data or output space to make progress)
+ return;
+ ... make progress ...
+ state = STATEm;
+ break;
+ ...
+ }
+
+ so when inflate() is called again, the same case is attempted again, and
+ if the appropriate resources are provided, the machine proceeds to the
+ next state. The NEEDBITS() macro is usually the way the state evaluates
+ whether it can proceed or should return. NEEDBITS() does the return if
+ the requested bits are not available. The typical use of the BITS macros
+ is:
+
+ NEEDBITS(n);
+ ... do something with BITS(n) ...
+ DROPBITS(n);
+
+ where NEEDBITS(n) either returns from inflate() if there isn't enough
+ input left to load n bits into the accumulator, or it continues. BITS(n)
+ gives the low n bits in the accumulator. When done, DROPBITS(n) drops
+ the low n bits off the accumulator. INITBITS() clears the accumulator
+ and sets the number of available bits to zero. BYTEBITS() discards just
+ enough bits to put the accumulator on a byte boundary. After BYTEBITS()
+ and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+ NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+ if there is no input available. The decoding of variable length codes uses
+ PULLBYTE() directly in order to pull just enough bytes to decode the next
+ code, and no more.
+
+ Some states loop until they get enough input, making sure that enough
+ state information is maintained to continue the loop where it left off
+ if NEEDBITS() returns in the loop. For example, want, need, and keep
+ would all have to actually be part of the saved state in case NEEDBITS()
+ returns:
+
+ case STATEw:
+ while (want < need) {
+ NEEDBITS(n);
+ keep[want++] = BITS(n);
+ DROPBITS(n);
+ }
+ state = STATEx;
+ case STATEx:
+
+ As shown above, if the next state is also the next case, then the break
+ is omitted.
+
+ A state may also return if there is not enough output space available to
+ complete that state. Those states are copying stored data, writing a
+ literal byte, and copying a matching string.
+
+ When returning, a "goto inf_leave" is used to update the total counters,
+ update the check value, and determine whether any progress has been made
+ during that inflate() call in order to return the proper return code.
+ Progress is defined as a change in either strm->avail_in or strm->avail_out.
+ When there is a window, goto inf_leave will update the window with the last
+ output written. If a goto inf_leave occurs in the middle of decompression
+ and there is no window currently, goto inf_leave will create one and copy
+ output to the window for the next call of inflate().
+
+ In this implementation, the flush parameter of inflate() only affects the
+ return code (per zlib.h). inflate() always writes as much as possible to
+ strm->next_out, given the space available and the provided input--the effect
+ documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
+ the allocation of and copying into a sliding window until necessary, which
+ provides the effect documented in zlib.h for Z_FINISH when the entire input
+ stream available. So the only thing the flush parameter actually does is:
+ when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
+ will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+
+#ifdef _MSC_VER
+#pragma warning(disable:4127)
+#endif
+
+int ZEXPORT inflate(z_streamp strm, int flush)
+{
+ struct inflate_state FAR *state;
+ unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned in, out; /* save starting available input and output */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code this; /* current decoding table entry */
+ code last; /* parent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+#ifdef GUNZIP
+ unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
+#endif
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0))
+ return Z_STREAM_ERROR;
+
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
+ LOAD();
+ in = have;
+ out = left;
+ ret = Z_OK;
+ for (;;)
+ switch (state->mode) {
+ case HEAD:
+ if (state->wrap == 0) {
+ state->mode = TYPEDO;
+ break;
+ }
+ NEEDBITS(16);
+#ifdef GUNZIP
+ if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
+ state->check = crc32(0L, Z_NULL, 0);
+ CRC2(state->check, hold);
+ INITBITS();
+ state->mode = FLAGS;
+ break;
+ }
+ state->flags = 0; /* expect zlib header */
+ if (state->head != Z_NULL)
+ state->head->done = -1;
+ if (!(state->wrap & 1) || /* check if zlib header allowed */
+#else
+ if (
+#endif
+ ((BITS(8) << 8) + (hold >> 8)) % 31) {
+ strm->msg = (char *)"incorrect header check";
+ state->mode = BAD;
+ break;
+ }
+ if (BITS(4) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ DROPBITS(4);
+ len = BITS(4) + 8;
+ if (len > state->wbits) {
+ strm->msg = (char *)"invalid window size";
+ state->mode = BAD;
+ break;
+ }
+ state->dmax = 1U << len;
+ Tracev((stderr, "inflate: zlib header ok\n"));
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = hold & 0x200 ? DICTID : TYPE;
+ INITBITS();
+ break;
+#ifdef GUNZIP
+ case FLAGS:
+ NEEDBITS(16);
+ state->flags = (int)(hold);
+ if ((state->flags & 0xff) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ if (state->flags & 0xe000) {
+ strm->msg = (char *)"unknown header flags set";
+ state->mode = BAD;
+ break;
+ }
+ if (state->head != Z_NULL)
+ state->head->text = (int)((hold >> 8) & 1);
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ state->mode = TIME;
+ case TIME:
+ NEEDBITS(32);
+ if (state->head != Z_NULL)
+ state->head->time = hold;
+ if (state->flags & 0x0200) CRC4(state->check, hold);
+ INITBITS();
+ state->mode = OS;
+ case OS:
+ NEEDBITS(16);
+ if (state->head != Z_NULL) {
+ state->head->xflags = (int)(hold & 0xff);
+ state->head->os = (int)(hold >> 8);
+ }
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ state->mode = EXLEN;
+ case EXLEN:
+ if (state->flags & 0x0400) {
+ NEEDBITS(16);
+ state->length = (unsigned)(hold);
+ if (state->head != Z_NULL)
+ state->head->extra_len = (unsigned)hold;
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ }
+ else if (state->head != Z_NULL)
+ state->head->extra = Z_NULL;
+ state->mode = EXTRA;
+ case EXTRA:
+ if (state->flags & 0x0400) {
+ copy = state->length;
+ if (copy > have) copy = have;
+ if (copy) {
+ if (state->head != Z_NULL &&
+ state->head->extra != Z_NULL) {
+ len = state->head->extra_len - state->length;
+ zmemcpy(state->head->extra + len, next,
+ len + copy > state->head->extra_max ?
+ state->head->extra_max - len : copy);
+ }
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ state->length -= copy;
+ }
+ if (state->length) goto inf_leave;
+ }
+ state->length = 0;
+ state->mode = NAME;
+ case NAME:
+ if (state->flags & 0x0800) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->name != Z_NULL &&
+ state->length < state->head->name_max)
+ state->head->name[state->length++] = (Bytef) len; /*MAB: Cast to silence compiler */
+ } while (len && copy < have);
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ else if (state->head != Z_NULL)
+ state->head->name = Z_NULL;
+ state->length = 0;
+ state->mode = COMMENT;
+ case COMMENT:
+ if (state->flags & 0x1000) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ if (state->head != Z_NULL &&
+ state->head->comment != Z_NULL &&
+ state->length < state->head->comm_max)
+ state->head->comment[state->length++] = (Bytef) len; /*MAB: Cast to silence compiler */
+ } while (len && copy < have);
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ else if (state->head != Z_NULL)
+ state->head->comment = Z_NULL;
+ state->mode = HCRC;
+ case HCRC:
+ if (state->flags & 0x0200) {
+ NEEDBITS(16);
+ if (hold != (state->check & 0xffff)) {
+ strm->msg = (char *)"header crc mismatch";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ }
+ if (state->head != Z_NULL) {
+ state->head->hcrc = (int)((state->flags >> 9) & 1);
+ state->head->done = 1;
+ }
+ strm->adler = state->check = crc32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ break;
+#endif
+ case DICTID:
+ NEEDBITS(32);
+ strm->adler = state->check = REVERSE(hold);
+ INITBITS();
+ state->mode = DICT;
+ case DICT:
+ if (state->havedict == 0) {
+ RESTORE();
+ return Z_NEED_DICT;
+ }
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ case TYPE:
+ if (flush == Z_BLOCK) goto inf_leave;
+ case TYPEDO:
+ if (state->last) {
+ BYTEBITS();
+ state->mode = CHECK;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN; /* decode codes */
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+ case STORED:
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+ state->mode = COPY;
+ case COPY:
+ copy = state->length;
+ if (copy) {
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ if (copy == 0) goto inf_leave;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ break;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+ case TABLE:
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+ state->have = 0;
+ state->mode = LENLENS;
+ case LENLENS:
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+ state->have = 0;
+ state->mode = CODELENS;
+ case CODELENS:
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.val < 16) {
+ NEEDBITS(this.bits);
+ DROPBITS(this.bits);
+ state->lens[state->have++] = this.val;
+ }
+ else {
+ if (this.val == 16) {
+ NEEDBITS(this.bits + 2);
+ DROPBITS(this.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = state->lens[state->have - 1];
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (this.val == 17) {
+ NEEDBITS(this.bits + 3);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(this.bits + 7);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state->mode == BAD) break;
+
+ /* build code tables */
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (code const FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN;
+ case LEN:
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ inflate_fast(strm, out);
+ LOAD();
+ break;
+ }
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.op && (this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ state->length = (unsigned)this.val;
+ if ((int)(this.op) == 0) {
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ state->mode = LIT;
+ break;
+ }
+ if (this.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ state->extra = (unsigned)(this.op) & 15;
+ state->mode = LENEXT;
+ case LENEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+ state->mode = DIST;
+ case DIST:
+ for (;;) {
+ this = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)this.val;
+ state->extra = (unsigned)(this.op) & 15;
+ state->mode = DISTEXT;
+ case DISTEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+#ifdef INFLATE_STRICT
+ if (state->offset > state->dmax) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ if (state->offset > state->whave + out - left) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+ state->mode = MATCH;
+ case MATCH:
+ if (left == 0) goto inf_leave;
+ copy = out - left;
+ if (state->offset > copy) { /* copy from window */
+ copy = state->offset - copy;
+ if (copy > state->write) {
+ copy -= state->write;
+ from = state->window + (state->wsize - copy);
+ }
+ else
+ from = state->window + (state->write - copy);
+ if (copy > state->length) copy = state->length;
+ }
+ else { /* copy from output */
+ from = put - state->offset;
+ copy = state->length;
+ }
+ if (copy > left) copy = left;
+ left -= copy;
+ state->length -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ if (state->length == 0) state->mode = LEN;
+ break;
+ case LIT:
+ if (left == 0) goto inf_leave;
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ case CHECK:
+ if (state->wrap) {
+ NEEDBITS(32);
+ out -= left;
+ strm->total_out += out;
+ state->total += out;
+ if (out)
+ strm->adler = state->check =
+ UPDATE(state->check, put - out, out);
+ out = left;
+ if ((
+#ifdef GUNZIP
+ state->flags ? hold :
+#endif
+ REVERSE(hold)) != state->check) {
+ strm->msg = (char *)"incorrect data check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: check matches trailer\n"));
+ }
+#ifdef GUNZIP
+ state->mode = LENGTH;
+ case LENGTH:
+ if (state->wrap && state->flags) {
+ NEEDBITS(32);
+ if (hold != (state->total & 0xffffffffUL)) {
+ strm->msg = (char *)"incorrect length check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: length matches trailer\n"));
+ }
+#endif
+ state->mode = DONE;
+ case DONE:
+ ret = Z_STREAM_END;
+ goto inf_leave;
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+ case MEM:
+ return Z_MEM_ERROR;
+ case SYNC:
+ default:
+ return Z_STREAM_ERROR;
+ }
+
+ /*
+ Return from inflate(), updating the total counts and the check value.
+ If there was no progress during the inflate() call, return a buffer
+ error. Call updatewindow() to create and/or update the window state.
+ Note: a memory error from inflate() is non-recoverable.
+ */
+ inf_leave:
+ RESTORE();
+ if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
+ if (updatewindow(strm, out)) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ in -= strm->avail_in;
+ out -= strm->avail_out;
+ strm->total_in += in;
+ strm->total_out += out;
+ state->total += out;
+ if (state->wrap && out)
+ strm->adler = state->check =
+ UPDATE(state->check, strm->next_out - out, out);
+ strm->data_type = (int)(state->bits + (state->last ? 64 : 0) + (state->mode == TYPE ? 128 : 0)); /*MAB casts */
+
+ if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+ ret = Z_BUF_ERROR;
+ return ret;
+}
+
+#ifdef _MSC_VER
+#pragma warning(default:4127)
+#endif
+
+int ZEXPORT inflateEnd(z_streamp strm)
+{
+ struct inflate_state FAR *state;
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->window != Z_NULL) ZFREE(strm, state->window);
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, uInt dictLength)
+{
+ struct inflate_state FAR *state;
+ unsigned long id;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->wrap != 0 && state->mode != DICT)
+ return Z_STREAM_ERROR;
+
+ /* check for correct dictionary id */
+ if (state->mode == DICT) {
+ id = adler32(0L, Z_NULL, 0);
+ id = adler32(id, dictionary, dictLength);
+ if (id != state->check)
+ return Z_DATA_ERROR;
+ }
+
+ /* copy dictionary to window */
+ if (updatewindow(strm, strm->avail_out)) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ if (dictLength > state->wsize) {
+ zmemcpy(state->window, dictionary + dictLength - state->wsize,
+ state->wsize);
+ state->whave = state->wsize;
+ }
+ else {
+ zmemcpy(state->window + state->wsize - dictLength, dictionary,
+ dictLength);
+ state->whave = dictLength;
+ }
+ state->havedict = 1;
+ Tracev((stderr, "inflate: dictionary set\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head)
+{
+ struct inflate_state FAR *state;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+ /* save header structure */
+ state->head = head;
+ head->done = 0;
+ return Z_OK;
+}
+
+/*
+ Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
+ or when out of input. When called, *have is the number of pattern bytes
+ found in order so far, in 0..3. On return *have is updated to the new
+ state. If on return *have equals four, then the pattern was found and the
+ return value is how many bytes were read including the last byte of the
+ pattern. If *have is less than four, then the pattern has not been found
+ yet and the return value is len. In the latter case, syncsearch() can be
+ called again with more data and the *have state. *have is initialized to
+ zero for the first call.
+ */
+local unsigned syncsearch(unsigned int *have, unsigned char *buf, unsigned int len)
+{
+ unsigned got;
+ unsigned next;
+
+ got = *have;
+ next = 0;
+ while (next < len && got < 4) {
+ if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+ got++;
+ else if (buf[next])
+ got = 0;
+ else
+ got = 4 - got;
+ next++;
+ }
+ *have = got;
+ return next;
+}
+
+int ZEXPORT inflateSync(z_streamp strm)
+{
+ unsigned len; /* number of bytes to look at or looked at */
+ unsigned long in, out; /* temporary to save total_in and total_out */
+ unsigned char buf[4]; /* to restore bit buffer to byte string */
+ struct inflate_state FAR *state;
+
+ /* check parameters */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+ /* if first time, start search in bit buffer */
+ if (state->mode != SYNC) {
+ state->mode = SYNC;
+ state->hold <<= state->bits & 7;
+ state->bits -= state->bits & 7;
+ len = 0;
+ while (state->bits >= 8) {
+ buf[len++] = (unsigned char)(state->hold);
+ state->hold >>= 8;
+ state->bits -= 8;
+ }
+ state->have = 0;
+ syncsearch(&(state->have), buf, len);
+ }
+
+ /* search available input */
+ len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+ strm->avail_in -= len;
+ strm->next_in += len;
+ strm->total_in += len;
+
+ /* return no joy or set up to restart inflate() on a new block */
+ if (state->have != 4) return Z_DATA_ERROR;
+ in = strm->total_in; out = strm->total_out;
+ inflateReset(strm);
+ strm->total_in = in; strm->total_out = out;
+ state->mode = TYPE;
+ return Z_OK;
+}
+
+/*
+ Returns true if inflate is currently at the end of a block generated by
+ Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ implementation to provide an additional safety check. PPP uses
+ Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+ block. When decompressing, PPP checks that at the end of input packet,
+ inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(z_streamp strm)
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(z_streamp dest, z_streamp source)
+{
+ struct inflate_state FAR *state;
+ struct inflate_state FAR *copy;
+ unsigned char FAR *window;
+ unsigned wsize;
+
+ /* check input */
+ if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
+ source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)source->state;
+
+ /* allocate space */
+ copy = (struct inflate_state FAR *)
+ ZALLOC(source, 1, sizeof(struct inflate_state));
+ if (copy == Z_NULL) return Z_MEM_ERROR;
+ window = Z_NULL;
+ if (state->window != Z_NULL) {
+ window = (unsigned char FAR *)
+ ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+ if (window == Z_NULL) {
+ ZFREE(source, copy);
+ return Z_MEM_ERROR;
+ }
+ }
+
+ /* copy state */
+ zmemcpy(dest, source, sizeof(z_stream));
+ zmemcpy(copy, state, sizeof(struct inflate_state));
+ if (state->lencode >= state->codes &&
+ state->lencode <= state->codes + ENOUGH - 1) {
+ copy->lencode = copy->codes + (state->lencode - state->codes);
+ copy->distcode = copy->codes + (state->distcode - state->codes);
+ }
+ copy->next = copy->codes + (state->next - state->codes);
+ if (window != Z_NULL) {
+ wsize = 1U << state->wbits;
+ zmemcpy(window, state->window, wsize);
+ }
+ copy->window = window;
+ dest->state = (struct internal_state FAR *)copy;
+ return Z_OK;
+}
diff --git a/DroidFish/jni/gtb/compression/zlib/inflate.h b/DroidFish/jni/gtb/compression/zlib/inflate.h
new file mode 100644
index 0000000..85db032
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/inflate.h
@@ -0,0 +1,115 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip decoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum inflate_mode {
+ HEAD, /* i: waiting for magic header */
+ FLAGS, /* i: waiting for method and flags (gzip) */
+ TIME, /* i: waiting for modification time (gzip) */
+ OS, /* i: waiting for extra flags and operating system (gzip) */
+ EXLEN, /* i: waiting for extra length (gzip) */
+ EXTRA, /* i: waiting for extra bytes (gzip) */
+ NAME, /* i: waiting for end of file name (gzip) */
+ COMMENT, /* i: waiting for end of comment (gzip) */
+ HCRC, /* i: waiting for header crc (gzip) */
+ DICTID, /* i: waiting for dictionary check value */
+ DICT, /* waiting for inflateSetDictionary() call */
+ TYPE, /* i: waiting for type bits, including last-flag bit */
+ TYPEDO, /* i: same, but skip check to exit inflate on new block */
+ STORED, /* i: waiting for stored size (length and complement) */
+ COPY, /* i/o: waiting for input or output to copy stored block */
+ TABLE, /* i: waiting for dynamic block table lengths */
+ LENLENS, /* i: waiting for code length code lengths */
+ CODELENS, /* i: waiting for length/lit and distance code lengths */
+ LEN, /* i: waiting for length/lit code */
+ LENEXT, /* i: waiting for length extra bits */
+ DIST, /* i: waiting for distance code */
+ DISTEXT, /* i: waiting for distance extra bits */
+ MATCH, /* o: waiting for output space to copy string */
+ LIT, /* o: waiting for output space to write literal */
+ CHECK, /* i: waiting for 32-bit check value */
+ LENGTH, /* i: waiting for 32-bit length (gzip) */
+ DONE, /* finished check, done -- remain here until reset */
+ BAD, /* got a data error -- remain here until reset */
+ MEM, /* got an inflate() memory error -- remain here until reset */
+ SYNC /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+ State transitions between above modes -
+
+ (most modes can go to the BAD or MEM mode -- not shown for clarity)
+
+ Process header:
+ HEAD -> (gzip) or (zlib)
+ (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
+ NAME -> COMMENT -> HCRC -> TYPE
+ (zlib) -> DICTID or TYPE
+ DICTID -> DICT -> TYPE
+ Read deflate blocks:
+ TYPE -> STORED or TABLE or LEN or CHECK
+ STORED -> COPY -> TYPE
+ TABLE -> LENLENS -> CODELENS -> LEN
+ Read deflate codes:
+ LEN -> LENEXT or LIT or TYPE
+ LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+ LIT -> LEN
+ Process trailer:
+ CHECK -> LENGTH -> DONE
+ */
+
+/* state maintained between inflate() calls. Approximately 7K bytes. */
+struct inflate_state {
+ inflate_mode mode; /* current inflate mode */
+ int last; /* true if processing last block */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ int havedict; /* true if dictionary provided */
+ int flags; /* gzip header method and flags (0 if zlib) */
+ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
+ unsigned long check; /* protected copy of check value */
+ unsigned long total; /* protected copy of output count */
+ gz_headerp head; /* where to save gzip header information */
+ /* sliding window */
+ unsigned wbits; /* log base 2 of requested window size */
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned write; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if needed */
+ /* bit accumulator */
+ unsigned long hold; /* input bit accumulator */
+ unsigned bits; /* number of bits in "in" */
+ /* for string and stored block copying */
+ unsigned length; /* literal or length of data to copy */
+ unsigned offset; /* distance back to copy string from */
+ /* for table and code decoding */
+ unsigned extra; /* extra bits needed */
+ /* fixed and dynamic code tables */
+ code const FAR *lencode; /* starting table for length/literal codes */
+ code const FAR *distcode; /* starting table for distance codes */
+ unsigned lenbits; /* index bits for lencode */
+ unsigned distbits; /* index bits for distcode */
+ /* dynamic table building */
+ unsigned ncode; /* number of code length code lengths */
+ unsigned nlen; /* number of length code lengths */
+ unsigned ndist; /* number of distance code lengths */
+ unsigned have; /* number of code lengths in lens[] */
+ code FAR *next; /* next available space in codes[] */
+ unsigned short lens[320]; /* temporary storage for code lengths */
+ unsigned short work[288]; /* work area for code table building */
+ code codes[ENOUGH]; /* space for code tables */
+};
diff --git a/DroidFish/jni/gtb/compression/zlib/inftrees.c b/DroidFish/jni/gtb/compression/zlib/inftrees.c
new file mode 100644
index 0000000..a8d23db
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/inftrees.c
@@ -0,0 +1,323 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+ " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/*
+ Build a set of tables to decode the provided canonical Huffman code.
+ The code lengths are lens[0..codes-1]. The result starts at *table,
+ whose indices are 0..2^bits-1. work is a writable array of at least
+ lens shorts, which is used as a work area. type is the type of code
+ to be generated, CODES, LENS, or DISTS. On return, zero is success,
+ -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
+ on return points to the next available entry's address. bits is the
+ requested root table index bits, and on return it is the actual root
+ table index bits. It will differ if the request is greater than the
+ longest code or if it is less than the shortest code.
+ */
+int inflate_table(codetype type, short unsigned int *lens, unsigned int codes, code **table, unsigned int *bits, short unsigned int *work)
+{
+ unsigned len; /* a code's length in bits */
+ unsigned sym; /* index of code symbols */
+ unsigned min, max; /* minimum and maximum code lengths */
+ unsigned root; /* number of index bits for root table */
+ unsigned curr; /* number of index bits for current table */
+ unsigned drop; /* code bits to drop for sub-table */
+ int left; /* number of prefix codes available */
+ unsigned used; /* code entries in table used */
+ unsigned huff; /* Huffman code */
+ unsigned incr; /* for incrementing code, index */
+ unsigned fill; /* index for replicating entries */
+ unsigned low; /* low bits for current root entry */
+ unsigned mask; /* mask for low root bits */
+ code this; /* table entry for duplication */
+ code FAR *next; /* next available space in table */
+ const unsigned short FAR *base; /* base value table to use */
+ const unsigned short FAR *extra; /* extra bits table to use */
+ int end; /* use base and extra for symbol > end */
+ unsigned short count[MAXBITS+1]; /* number of codes of each length */
+ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
+ static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
+ static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577, 0, 0};
+ static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+ 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+ 28, 28, 29, 29, 64, 64};
+
+ /*
+ Process a set of code lengths to create a canonical Huffman code. The
+ code lengths are lens[0..codes-1]. Each length corresponds to the
+ symbols 0..codes-1. The Huffman code is generated by first sorting the
+ symbols by length from short to long, and retaining the symbol order
+ for codes with equal lengths. Then the code starts with all zero bits
+ for the first code of the shortest length, and the codes are integer
+ increments for the same length, and zeros are appended as the length
+ increases. For the deflate format, these bits are stored backwards
+ from their more natural integer increment ordering, and so when the
+ decoding tables are built in the large loop below, the integer codes
+ are incremented backwards.
+
+ This routine assumes, but does not check, that all of the entries in
+ lens[] are in the range 0..MAXBITS. The caller must assure this.
+ 1..MAXBITS is interpreted as that code length. zero means that that
+ symbol does not occur in this code.
+
+ The codes are sorted by computing a count of codes for each length,
+ creating from that a table of starting indices for each length in the
+ sorted table, and then entering the symbols in order in the sorted
+ table. The sorted table is work[], with that space being provided by
+ the caller.
+
+ The length counts are used for other purposes as well, i.e. finding
+ the minimum and maximum length codes, determining if there are any
+ codes at all, checking for a valid set of lengths, and looking ahead
+ at length counts to determine sub-table sizes when building the
+ decoding tables.
+ */
+
+ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+ for (len = 0; len <= MAXBITS; len++)
+ count[len] = 0;
+ for (sym = 0; sym < codes; sym++)
+ count[lens[sym]]++;
+
+ /* bound code lengths, force root to be within code lengths */
+ root = *bits;
+ for (max = MAXBITS; max >= 1; max--)
+ if (count[max] != 0) break;
+ if (root > max) root = max;
+ if (max == 0) { /* no symbols to code at all */
+ this.op = (unsigned char)64; /* invalid code marker */
+ this.bits = (unsigned char)1;
+ this.val = (unsigned short)0;
+ *(*table)++ = this; /* make a table to force an error */
+ *(*table)++ = this;
+ *bits = 1;
+ return 0; /* no symbols, but wait for decoding to report error */
+ }
+ for (min = 1; min <= MAXBITS; min++)
+ if (count[min] != 0) break;
+ if (root < min) root = min;
+
+ /* check for an over-subscribed or incomplete set of lengths */
+ left = 1;
+ for (len = 1; len <= MAXBITS; len++) {
+ left <<= 1;
+ left -= count[len];
+ if (left < 0) return -1; /* over-subscribed */
+ }
+ if (left > 0 && (type == CODES || max != 1))
+ return -1; /* incomplete set */
+
+ /* generate offsets into symbol table for each length for sorting */
+ offs[1] = 0;
+ for (len = 1; len < MAXBITS; len++)
+ offs[len + 1] = (unsigned short) (offs[len] + count[len]); /*MAB: Cast to unsigned short to silence compiler */
+
+ /* sort symbols by length, by symbol order within each length */
+ for (sym = 0; sym < codes; sym++)
+ if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+ /*
+ Create and fill in decoding tables. In this loop, the table being
+ filled is at next and has curr index bits. The code being used is huff
+ with length len. That code is converted to an index by dropping drop
+ bits off of the bottom. For codes where len is less than drop + curr,
+ those top drop + curr - len bits are incremented through all values to
+ fill the table with replicated entries.
+
+ root is the number of index bits for the root table. When len exceeds
+ root, sub-tables are created pointed to by the root entry with an index
+ of the low root bits of huff. This is saved in low to check for when a
+ new sub-table should be started. drop is zero when the root table is
+ being filled, and drop is root when sub-tables are being filled.
+
+ When a new sub-table is needed, it is necessary to look ahead in the
+ code lengths to determine what size sub-table is needed. The length
+ counts are used for this, and so count[] is decremented as codes are
+ entered in the tables.
+
+ used keeps track of how many table entries have been allocated from the
+ provided *table space. It is checked when a LENS table is being made
+ against the space in *table, ENOUGH, minus the maximum space needed by
+ the worst case distance code, MAXD. This should never happen, but the
+ sufficiency of ENOUGH has not been proven exhaustively, hence the check.
+ This assumes that when type == LENS, bits == 9.
+
+ sym increments through all symbols, and the loop terminates when
+ all codes of length max, i.e. all codes, have been processed. This
+ routine permits incomplete codes, so another loop after this one fills
+ in the rest of the decoding tables with invalid code markers.
+ */
+
+ /* set up for code type */
+ switch (type) {
+ case CODES:
+ base = extra = work; /* dummy value--not used */
+ end = 19;
+ break;
+ case LENS:
+ base = lbase;
+ base -= 257;
+ extra = lext;
+ extra -= 257;
+ end = 256;
+ break;
+ default: /* DISTS */
+ base = dbase;
+ extra = dext;
+ end = -1;
+ }
+
+ /* initialize state for loop */
+ huff = 0; /* starting code */
+ sym = 0; /* starting code symbol */
+ len = min; /* starting code length */
+ next = *table; /* current table to fill in */
+ curr = root; /* current table index bits */
+ drop = 0; /* current bits to drop from code for index */
+ low = (unsigned)(-1); /* trigger new sub-table when len > root */
+ used = 1U << root; /* use root table entries */
+ mask = used - 1; /* mask for comparing low */
+
+ /* check available table space */
+ if (type == LENS && used >= ENOUGH - MAXD)
+ return 1;
+
+ /* process all codes and make table entries */
+ for (;;) {
+ /* create table entry */
+ this.bits = (unsigned char)(len - drop);
+ if ((int)(work[sym]) < end) {
+ this.op = (unsigned char)0;
+ this.val = work[sym];
+ }
+ else if ((int)(work[sym]) > end) {
+ this.op = (unsigned char)(extra[work[sym]]);
+ this.val = base[work[sym]];
+ }
+ else {
+ this.op = (unsigned char)(32 + 64); /* end of block */
+ this.val = 0;
+ }
+
+ /* replicate for those indices with low len bits equal to huff */
+ incr = 1U << (len - drop);
+ fill = 1U << curr;
+ min = fill; /* save offset to next table */
+ do {
+ fill -= incr;
+ next[(huff >> drop) + fill] = this;
+ } while (fill != 0);
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+
+ /* go to next symbol, update count, len */
+ sym++;
+ if (--(count[len]) == 0) {
+ if (len == max) break;
+ len = lens[work[sym]];
+ }
+
+ /* create new sub-table if needed */
+ if (len > root && (huff & mask) != low) {
+ /* if first time, transition to sub-tables */
+ if (drop == 0)
+ drop = root;
+
+ /* increment past last table */
+ next += min; /* here min is 1 << curr */
+
+ /* determine length of next table */
+ curr = len - drop;
+ left = (int)(1 << curr);
+ while (curr + drop < max) {
+ left -= count[curr + drop];
+ if (left <= 0) break;
+ curr++;
+ left <<= 1;
+ }
+
+ /* check for enough space */
+ used += 1U << curr;
+ if (type == LENS && used >= ENOUGH - MAXD)
+ return 1;
+
+ /* point entry in root table to sub-table */
+ low = huff & mask;
+ (*table)[low].op = (unsigned char)curr;
+ (*table)[low].bits = (unsigned char)root;
+ (*table)[low].val = (unsigned short)(next - *table);
+ }
+ }
+
+ /*
+ Fill in rest of table for incomplete codes. This loop is similar to the
+ loop above in incrementing huff for table indices. It is assumed that
+ len is equal to curr + drop, so there is no loop needed to increment
+ through high index bits. When the current sub-table is filled, the loop
+ drops back to the root table to fill in any remaining entries there.
+ */
+ this.op = (unsigned char)64; /* invalid code marker */
+ this.bits = (unsigned char)(len - drop);
+ this.val = (unsigned short)0;
+ while (huff != 0) {
+ /* when done with sub-table, drop back to root table */
+ if (drop != 0 && (huff & mask) != low) {
+ drop = 0;
+ len = root;
+ next = *table;
+ this.bits = (unsigned char)len;
+ }
+
+ /* put invalid code marker in table */
+ next[huff >> drop] = this;
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+ }
+
+ /* set return parameters */
+ *table += used;
+ *bits = root;
+ return 0;
+}
diff --git a/DroidFish/jni/gtb/compression/zlib/inftrees.h b/DroidFish/jni/gtb/compression/zlib/inftrees.h
new file mode 100644
index 0000000..9b4bd19
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/inftrees.h
@@ -0,0 +1,55 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables. Each entry provides either the
+ information needed to do the operation requested by the code that
+ indexed that table entry, or it provides a pointer to another
+ table that indexes more bits of the code. op indicates whether
+ the entry is a pointer to another table, a literal, a length or
+ distance, an end-of-block, or an invalid code. For a table
+ pointer, the low four bits of op is the number of index bits of
+ that table. For a length or distance, the low four bits of op
+ is the number of extra bits to get after the code. bits is
+ the number of bits in this code or part of the code to drop off
+ of the bit buffer. val is the actual byte to output in the case
+ of a literal, the base length or distance, or the offset from
+ the current table to the next table. Each entry is four bytes. */
+typedef struct code {
+ unsigned char op; /* operation, extra bits, table bits */
+ unsigned char bits; /* bits in this part of the code */
+ unsigned short val; /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+ 00000000 - literal
+ 0000tttt - table link, tttt != 0 is the number of table index bits
+ 0001eeee - length or distance, eeee is the number of extra bits
+ 01100000 - end of block
+ 01000000 - invalid code
+ */
+
+/* Maximum size of dynamic tree. The maximum found in a long but non-
+ exhaustive search was 1444 code structures (852 for length/literals
+ and 592 for distances, the latter actually the result of an
+ exhaustive search). The true maximum is not known, but the value
+ below is more than safe. */
+#define ENOUGH 2048
+#define MAXD 592
+
+/* Type of code to build for inftable() */
+typedef enum codetype {
+ CODES,
+ LENS,
+ DISTS
+} codetype;
+
+extern int inflate_table OF((codetype type, unsigned short FAR *lens,
+ unsigned codes, code FAR * FAR *table,
+ unsigned FAR *bits, unsigned short FAR *work));
diff --git a/DroidFish/jni/gtb/compression/zlib/trees.c b/DroidFish/jni/gtb/compression/zlib/trees.c
new file mode 100644
index 0000000..214f693
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/trees.c
@@ -0,0 +1,1267 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2005 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process uses several Huffman trees. The more
+ * common source values are represented by shorter bit sequences.
+ *
+ * Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values). The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ * Storer, James A.
+ * Data Compression: Methods and Theory, pp. 49-50.
+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
+ *
+ * Sedgewick, R.
+ * Algorithms, p290.
+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+# include
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6 16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10 17
+/* repeat a zero length 3-10 times (3 bits of repeat count) */
+
+#define REPZ_11_138 18
+/* repeat a zero length 11-138 times (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+# include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+ const ct_data *static_tree; /* static tree or NULL */
+ const intf *extra_bits; /* extra bits for each code or NULL */
+ int extra_base; /* base index for extra_bits */
+ int elems; /* max number of elements in the tree */
+ int max_length; /* max bit length for the codes */
+};
+
+local static_tree_desc static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc static_d_desc =
+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
+
+local static_tree_desc static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block OF((deflate_state *s));
+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree OF((deflate_state *s, tree_desc *desc));
+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local int build_bl_tree OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+ int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+ ct_data *dtree));
+local void set_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup OF((deflate_state *s));
+local void bi_flush OF((deflate_state *s));
+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
+ int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+ /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+# define send_code(s, c, tree) \
+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+ send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+ put_byte(s, (uch)((w) & 0xff)); \
+ put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+ deflate_state *s;
+ int value; /* value to send */
+ int length; /* number of bits */
+{
+ Tracevv((stderr," l %2d v %4x ", length, value));
+ Assert(length > 0 && length <= 15, "invalid length");
+ s->bits_sent += (ulg)length;
+
+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+ * unused bits in value.
+ */
+ if (s->bi_valid > (int)Buf_size - length) {
+ s->bi_buf |= (ush)(value << s->bi_valid); /*MAB cast to ush */
+ put_short(s, s->bi_buf);
+ s->bi_buf = (ush)((ush)value >> ((int)Buf_size - s->bi_valid)); /*MAB cast to int */
+ s->bi_valid += length - (int)Buf_size; /*MAB cast to int */
+ } else {
+ s->bi_buf |= (ush)(value << s->bi_valid); /*MAB cast to ush */
+ s->bi_valid += length;
+ }
+}
+#else /* !DEBUG */
+
+/*MAB: ORIGINAL, with warnings demanding castings.
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+ if (s->bi_valid > (int)Buf_size - len) {\
+ int val = value;\
+ s->bi_buf |= (val << s->bi_valid);\
+ put_short(s, s->bi_buf);\
+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+ s->bi_valid += len - Buf_size;\
+ } else {\
+ s->bi_buf |= (value) << s->bi_valid;\
+ s->bi_valid += len;\
+ }\
+}
+*/
+
+
+/*MAB: modified */
+#define send_bits(s, value, length) \
+{ int len = (int)length;/*MAB casts*/\
+ if (s->bi_valid > (int)Buf_size - len) {\
+ int val = (int)value;/*MAB casts*/\
+ s->bi_buf = (ush)(s->bi_buf | (val << s->bi_valid));/*MAB: Cast to silence compiler, see [1] above */\
+ put_short(s, s->bi_buf);\
+ s->bi_buf = (ush) ((ush)val >> ((int)Buf_size - s->bi_valid));/*MAB: Cast to silence compiler */\
+ s->bi_valid += (int)(len - (int)Buf_size);/*MAB casts*/\
+ } else {\
+ s->bi_buf = (ush) (s->bi_buf | ((value) << s->bi_valid));/*MAB: Cast to silence compiler, see [2] above */\
+ s->bi_valid += len;\
+ }\
+}
+
+#endif /* DEBUG */
+
+/*MAB:
+
+FUNCTION USED TO TEST THE CHANGES ABOVE
+
+[1] original:
+ s->bi_buf |= (ush)(val << s->bi_valid);\
+
+[2] original:
+ s->bi_buf |= (ush) ((value) << s->bi_valid);\
+*/
+
+#if 0
+static void send_bits(deflate_state *s, int value, int length)
+{ int len = length;\
+ if (s->bi_valid > (int)Buf_size - len) {\
+ int val = value;\
+ s->bi_buf = (ush)(s->bi_buf | (val << s->bi_valid));/*MAB: Cast to silence compiler, see [1] above */\
+ put_short(s, s->bi_buf);\
+ s->bi_buf = (ush) ((ush)val >> (Buf_size - s->bi_valid));/*MAB: Cast to silence compiler */\
+ s->bi_valid += len - Buf_size;\
+ } else {\
+ s->bi_buf = (ush) (s->bi_buf | ((value) << s->bi_valid));/*MAB: Cast to silence compiler, see [2] above */\
+ s->bi_valid += len;\
+ }\
+}
+#endif
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init(void)
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+ static int static_init_done = 0;
+ int n; /* iterates over tree elements */
+ int bits; /* bit counter */
+ int length; /* length value */
+ int code; /* code value */
+ int dist; /* distance index */
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ if (static_init_done) return;
+
+ /* For some embedded targets, global variables are not initialized: */
+ static_l_desc.static_tree = static_ltree;
+ static_l_desc.extra_bits = extra_lbits;
+ static_d_desc.static_tree = static_dtree;
+ static_d_desc.extra_bits = extra_dbits;
+ static_bl_desc.extra_bits = extra_blbits;
+
+ /* Initialize the mapping length (0..255) -> length code (0..28) */
+ length = 0;
+ for (code = 0; code < LENGTH_CODES-1; code++) {
+ base_length[code] = length;
+ for (n = 0; n < (1< dist code (0..29) */
+ dist = 0;
+ for (code = 0 ; code < 16; code++) {
+ base_dist[code] = dist;
+ for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */
+ for ( ; code < D_CODES; code++) {
+ base_dist[code] = dist << 7;
+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+ _dist_code[256 + dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+ /* Construct the codes of the static literal tree */
+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+ n = 0;
+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+ /* Codes 286 and 287 do not exist, but we must include them in the
+ * tree construction to get a canonical Huffman tree (longest code
+ * all ones)
+ */
+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+ /* The static distance tree is trivial: */
+ for (n = 0; n < D_CODES; n++) {
+ static_dtree[n].Len = 5;
+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+ }
+ static_init_done = 1;
+
+# ifdef GEN_TREES_H
+ gen_trees_header();
+# endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+# ifndef DEBUG
+# include
+# endif
+
+# define SEPARATOR(i, last, width) \
+ ((i) == (last)? "\n};\n\n" : \
+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+ FILE *header = fopen("trees.h", "w");
+ int i;
+
+ Assert (header != NULL, "Can't open trees.h");
+ fprintf(header,
+ "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+ for (i = 0; i < L_CODES+2; i++) {
+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+ }
+
+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+ }
+
+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
+ for (i = 0; i < DIST_CODE_LEN; i++) {
+ fprintf(header, "%2u%s", _dist_code[i],
+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
+ }
+
+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+ fprintf(header, "%2u%s", _length_code[i],
+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+ }
+
+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+ for (i = 0; i < LENGTH_CODES; i++) {
+ fprintf(header, "%1u%s", base_length[i],
+ SEPARATOR(i, LENGTH_CODES-1, 20));
+ }
+
+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "%5u%s", base_dist[i],
+ SEPARATOR(i, D_CODES-1, 10));
+ }
+
+ fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void _tr_init(deflate_state *s)
+{
+ tr_static_init();
+
+ s->l_desc.dyn_tree = s->dyn_ltree;
+ s->l_desc.stat_desc = &static_l_desc;
+
+ s->d_desc.dyn_tree = s->dyn_dtree;
+ s->d_desc.stat_desc = &static_d_desc;
+
+ s->bl_desc.dyn_tree = s->bl_tree;
+ s->bl_desc.stat_desc = &static_bl_desc;
+
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG
+ s->compressed_len = 0L;
+ s->bits_sent = 0L;
+#endif
+
+ /* Initialize the first block of the first file: */
+ init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(deflate_state *s)
+{
+ int n; /* iterates over tree elements */
+
+ /* Initialize the trees. */
+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+ s->dyn_ltree[END_BLOCK].Freq = 1;
+ s->opt_len = s->static_len = 0L;
+ s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+ top = s->heap[SMALLEST]; \
+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+ pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+ (tree[n].Freq < tree[m].Freq || \
+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(deflate_state *s, ct_data *tree, int k)
+
+ /* the tree to restore */
+ /* node to move down */
+{
+ int v = s->heap[k];
+ int j = k << 1; /* left son of k */
+ while (j <= s->heap_len) {
+ /* Set j to the smallest of the two sons: */
+ if (j < s->heap_len &&
+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+ j++;
+ }
+ /* Exit if v is smaller than both sons */
+ if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+ /* Exchange v with the smallest son */
+ s->heap[k] = s->heap[j]; k = j;
+
+ /* And continue down the tree, setting j to the left son of k */
+ j <<= 1;
+ }
+ s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ * above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ * array bl_count contains the frequencies for each bit length.
+ * The length opt_len is updated; static_len is also updated if stree is
+ * not null.
+ */
+local void gen_bitlen(deflate_state *s, tree_desc *desc)
+
+ /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ int max_code = desc->max_code;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ const intf *extra = desc->stat_desc->extra_bits;
+ int base = desc->stat_desc->extra_base;
+ int max_length = desc->stat_desc->max_length;
+ int h; /* heap index */
+ int n, m; /* iterate over the tree elements */
+ int bits; /* bit length */
+ int xbits; /* extra bits */
+ ush f; /* frequency */
+ int overflow = 0; /* number of elements with bit length too large */
+
+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+ /* In a first pass, compute the optimal bit lengths (which may
+ * overflow in the case of the bit length tree).
+ */
+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+ n = s->heap[h];
+ bits = tree[tree[n].Dad].Len + 1;
+ if (bits > max_length) bits = max_length, overflow++;
+ tree[n].Len = (ush)bits;
+ /* We overwrite tree[n].Dad which is no longer needed */
+
+ if (n > max_code) continue; /* not a leaf node */
+
+ s->bl_count[bits]++;
+ xbits = 0;
+ if (n >= base) xbits = extra[n-base];
+ f = tree[n].Freq;
+ s->opt_len += (ulg)f * (ulg)(bits + xbits); /*MAB cast, (ulg)(bits + xbits) */
+ if (stree) s->static_len += (ulg)f * (ulg)(stree[n].Len + xbits); /*MAB cast */
+ }
+ if (overflow == 0) return;
+
+ Trace((stderr,"\nbit length overflow\n"));
+ /* This happens for example on obj2 and pic of the Calgary corpus */
+
+ /* Find the first bit length which could increase: */
+ do {
+ bits = max_length-1;
+ while (s->bl_count[bits] == 0) bits--;
+ s->bl_count[bits]--; /* move one leaf down the tree */
+ s->bl_count[bits+1] = (ush)(s->bl_count[bits+1] + 2); /* move one overflow item as its brother */ /*MAB cast and expand += */
+ s->bl_count[max_length]--;
+ /* The brother of the overflow item also moves one step up,
+ * but this does not affect bl_count[max_length]
+ */
+ overflow -= 2;
+ } while (overflow > 0);
+
+ /* Now recompute all bit lengths, scanning in increasing frequency.
+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+ * lengths instead of fixing only the wrong ones. This idea is taken
+ * from 'ar' written by Haruhiko Okumura.)
+ */
+ for (bits = max_length; bits != 0; bits--) {
+ n = s->bl_count[bits];
+ while (n != 0) {
+ m = s->heap[--h];
+ if (m > max_code) continue;
+ if ((unsigned) tree[m].Len != (unsigned) bits) {
+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+ s->opt_len += (long unsigned)( /*MAB cast */
+ ((long)bits - (long)tree[m].Len)
+ *(long)tree[m].Freq
+ );
+ tree[m].Len = (ush)bits;
+ }
+ n--;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ * zero code length.
+ */
+local void gen_codes (ct_data *tree, int max_code, ushf *bl_count)
+ /* the tree to decorate */
+ /* largest code with non zero frequency */
+ /* number of codes at each bit length */
+{
+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+ ush code = 0; /* running code value */
+ int bits; /* bit index */
+ int n; /* code index */
+
+ /* The distribution counts are first used to generate the code values
+ * without bit reversal.
+ */
+ for (bits = 1; bits <= MAX_BITS; bits++) {
+ next_code[bits] = code = (ush) ((code + bl_count[bits-1]) << 1); /*MAB: Casting to silence compiler */
+ }
+ /* Check that the bit counts in bl_count are consistent. The last code
+ * must be all ones.
+ */
+ Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ int elems = desc->stat_desc->elems;
+ int n, m; /* iterate over heap elements */
+ int max_code = -1; /* largest code with non zero frequency */
+ int node; /* new node being created */
+
+ /* Construct the initial heap, with least frequent element in
+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+ * heap[0] is not used.
+ */
+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+ for (n = 0; n < elems; n++) {
+ if (tree[n].Freq != 0) {
+ s->heap[++(s->heap_len)] = max_code = n;
+ s->depth[n] = 0;
+ } else {
+ tree[n].Len = 0;
+ }
+ }
+
+ /* The pkzip format requires that at least one distance code exists,
+ * and that at least one bit should be sent even if there is only one
+ * possible code. So to avoid special checks later on we force at least
+ * two codes of non zero frequency.
+ */
+ while (s->heap_len < 2) {
+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+ tree[node].Freq = 1;
+ s->depth[node] = 0;
+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+ /* node is 0 or 1 so it does not have extra bits */
+ }
+ desc->max_code = max_code;
+
+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+ * establish sub-heaps of increasing lengths:
+ */
+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+ /* Construct the Huffman tree by repeatedly combining the least two
+ * frequent nodes.
+ */
+ node = elems; /* next internal node of the tree */
+ do {
+ pqremove(s, tree, n); /* n = node of least frequency */
+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+ s->heap[--(s->heap_max)] = m;
+
+ /* Create a new node father of n and m */
+ tree[node].Freq = (ush) (tree[n].Freq + tree[m].Freq); /*MAB: Casting to silence compiler */
+ s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+ s->depth[n] : s->depth[m]) + 1);
+ tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+ if (tree == s->bl_tree) {
+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+ }
+#endif
+ /* and insert the new node in the heap */
+ s->heap[SMALLEST] = node++;
+ pqdownheap(s, tree, SMALLEST);
+
+ } while (s->heap_len >= 2);
+
+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+ /* At this point, the fields freq and dad are set. We can now
+ * generate the bit lengths.
+ */
+ gen_bitlen(s, (tree_desc *)desc);
+
+ /* The field len is now set, we can generate the bit codes */
+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (deflate_state *s, ct_data *tree, int max_code)
+
+ /* the tree to be scanned */
+ /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ if (nextlen == 0) max_count = 138, min_count = 3;
+ tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ #if 0
+ s->bl_tree[curlen].Freq += count;
+ #else
+ /*MAB: This modification and casting to silence compiler */
+ s->bl_tree[curlen].Freq = (ush) (s->bl_tree[curlen].Freq + count);
+ #endif
+
+ } else if (curlen != 0) {
+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+ s->bl_tree[REP_3_6].Freq++;
+ } else if (count <= 10) {
+ s->bl_tree[REPZ_3_10].Freq++;
+ } else {
+ s->bl_tree[REPZ_11_138].Freq++;
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (deflate_state *s, ct_data *tree, int max_code)
+
+ /* the tree to be scanned */
+ /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ /* tree[max_code+1].Len = -1; */ /* guard already set */
+ if (nextlen == 0) max_count = 138, min_count = 3;
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+ } else if (curlen != 0) {
+ if (curlen != prevlen) {
+ send_code(s, curlen, s->bl_tree); count--;
+ }
+ Assert(count >= 3 && count <= 6, " 3_6?");
+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+ } else if (count <= 10) {
+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+ } else {
+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(deflate_state *s)
+{
+ int max_blindex; /* index of last bit length code of non zero freq */
+
+ /* Determine the bit length frequencies for literal and distance trees */
+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+ /* Build the bit length tree: */
+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
+ /* opt_len now includes the length of the tree representations, except
+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+ */
+
+ /* Determine the number of bit length codes to send. The pkzip format
+ * requires that at least 4 bit length codes be sent. (appnote.txt says
+ * 3 but the actual value used is 4.)
+ */
+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+ }
+ /* Update opt_len to include the bit length tree and counts */
+ s->opt_len += (long unsigned)(3*(max_blindex+1) + 5 + 5 + 4); /*MAB casts */
+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+ s->opt_len, s->static_len));
+
+ return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(deflate_state *s, int lcodes, int dcodes, int blcodes)
+
+ /* number of codes for each tree */
+{
+ int rank; /* index in bl_order */
+
+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+ "too many codes");
+ Tracev((stderr, "\nbl counts: "));
+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+ send_bits(s, dcodes-1, 5);
+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
+ for (rank = 0; rank < blcodes; rank++) {
+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+ }
+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void _tr_stored_block(deflate_state *s, charf *buf, ulg stored_len, int eof)
+
+ /* input block */
+ /* length of input block */
+ /* true if this is the last block for a file */
+{
+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
+#ifdef DEBUG
+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+ s->compressed_len += (stored_len + 4) << 3;
+#endif
+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void _tr_align(deflate_state *s)
+{
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+ bi_flush(s);
+ /* Of the 10 bits for the empty block, we have already sent
+ * (10 - bi_valid) bits. The lookahead for the last real code (before
+ * the EOB of the previous block) was thus at least one plus the length
+ * of the EOB plus what we have just sent of the empty static block.
+ */
+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L;
+#endif
+ bi_flush(s);
+ }
+ s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void _tr_flush_block(deflate_state *s, charf *buf, ulg stored_len, int eof)
+
+ /* input block, or NULL if too old */
+ /* length of input block */
+ /* true if this is the last block for a file */
+{
+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+ int max_blindex = 0; /* index of last bit length code of non zero freq */
+
+ /* Build the Huffman trees unless a stored block is forced */
+ if (s->level > 0) {
+
+ /* Check if the file is binary or text */
+ if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
+ set_data_type(s);
+
+ /* Construct the literal and distance trees */
+ build_tree(s, (tree_desc *)(&(s->l_desc)));
+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+
+ build_tree(s, (tree_desc *)(&(s->d_desc)));
+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+ /* At this point, opt_len and static_len are the total bit lengths of
+ * the compressed block data, excluding the tree representations.
+ */
+
+ /* Build the bit length tree for the above two trees, and get the index
+ * in bl_order of the last bit length code to send.
+ */
+ max_blindex = build_bl_tree(s);
+
+ /* Determine the best encoding. Compute the block lengths in bytes. */
+ opt_lenb = (s->opt_len+3+7)>>3;
+ static_lenb = (s->static_len+3+7)>>3;
+
+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+ s->last_lit));
+
+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+ } else {
+ Assert(buf != (char*)0, "lost buf");
+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+ }
+
+#ifdef FORCE_STORED
+ if (buf != (char*)0) { /* force stored block */
+#else
+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+ /* 4: two words for the lengths */
+#endif
+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+ * Otherwise we can't have processed more than WSIZE input bytes since
+ * the last block flush, because compression would have been
+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+ * transform a block into a stored block.
+ */
+ _tr_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+ } else if (static_lenb >= 0) { /* force static trees */
+#else
+ } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
+#endif
+ send_bits(s, (STATIC_TREES<<1)+eof, 3);
+ compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->static_len;
+#endif
+ } else {
+ send_bits(s, (DYN_TREES<<1)+eof, 3);
+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+ max_blindex+1);
+ compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->opt_len;
+#endif
+ }
+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+ /* The above check is made mod 2^32, for files larger than 512 MB
+ * and uLong implemented on 32 bits.
+ */
+ init_block(s);
+
+ if (eof) {
+ bi_windup(s);
+#ifdef DEBUG
+ s->compressed_len += 7; /* align on byte boundary */
+#endif
+ }
+ Tracev((stderr,"\ncomprlen %lu(%lu) ", (unsigned long) (s->compressed_len>>3), /*MAB casts to ul */
+ (unsigned long) (s->compressed_len-7ul*(unsigned long)eof))); /*MAB casts to ul */
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int _tr_tally (deflate_state *s, unsigned int dist, unsigned int lc)
+
+ /* distance of matched string */
+ /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+ s->d_buf[s->last_lit] = (ush)dist;
+ s->l_buf[s->last_lit++] = (uch)lc;
+ if (dist == 0) {
+ /* lc is the unmatched char */
+ s->dyn_ltree[lc].Freq++;
+ } else {
+ s->matches++;
+ /* Here, lc is the match length - MIN_MATCH */
+ dist--; /* dist = match distance - 1 */
+ Assert((ush)dist < (ush)MAX_DIST(s) &&
+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
+
+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+ s->dyn_dtree[d_code(dist)].Freq++;
+ }
+
+#ifdef TRUNCATE_BLOCK
+ /* Try to guess if it is profitable to stop the current block here */
+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+ /* Compute an upper bound for the compressed length */
+ ulg out_length = (ulg)s->last_lit*8L;
+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
+ int dcode;
+ for (dcode = 0; dcode < D_CODES; dcode++) {
+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
+ (5L+extra_dbits[dcode]);
+ }
+ out_length >>= 3;
+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+ s->last_lit, in_length, out_length,
+ 100L - out_length*100L/in_length));
+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+ }
+#endif
+ return (s->last_lit == s->lit_bufsize-1);
+ /* We avoid equality with lit_bufsize because of wraparound at 64K
+ * on 16 bit machines and because stored blocks are restricted to
+ * 64K-1 bytes.
+ */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(deflate_state *s, ct_data *ltree, ct_data *dtree)
+
+ /* literal tree */
+ /* distance tree */
+{
+ unsigned dist; /* distance of matched string */
+ int lc; /* match length or unmatched char (if dist == 0) */
+ unsigned lx = 0; /* running index in l_buf */
+ unsigned code; /* the code to send */
+ int extra; /* number of extra bits to send */
+
+ if (s->last_lit != 0) do {
+ dist = s->d_buf[lx];
+ lc = s->l_buf[lx++];
+ if (dist == 0) {
+ send_code(s, lc, ltree); /* send a literal byte */
+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+ } else {
+ /* Here, lc is the match length - MIN_MATCH */
+ code = _length_code[lc];
+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
+ extra = extra_lbits[code];
+ if (extra != 0) {
+ lc -= base_length[code];
+ send_bits(s, lc, extra); /* send the extra length bits */
+ }
+ dist--; /* dist is now the match distance - 1 */
+ code = (unsigned)(d_code(dist)); /*MAB casts */
+ Assert (code < D_CODES, "bad d_code");
+
+ send_code(s, code, dtree); /* send the distance code */
+ extra = extra_dbits[code];
+ if (extra != 0) {
+ dist -= (unsigned)(base_dist[code]); /*MAB casts */
+ send_bits(s, (int)dist, extra); /* send the extra distance bits */ /*MAB cast with int for debug */
+ }
+ } /* literal or match pair ? */
+
+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+ Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+ "pendingBuf overflow");
+
+ } while (lx < s->last_lit);
+
+ send_code(s, END_BLOCK, ltree);
+ s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Set the data type to BINARY or TEXT, using a crude approximation:
+ * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
+ * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+local void set_data_type(deflate_state *s)
+{
+ int n;
+
+ for (n = 0; n < 9; n++)
+ if (s->dyn_ltree[n].Freq != 0)
+ break;
+ if (n == 9)
+ for (n = 14; n < 32; n++)
+ if (s->dyn_ltree[n].Freq != 0)
+ break;
+ s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(unsigned int code, int len)
+ /* the value to invert */
+ /* its bit length */
+{
+ register unsigned res = 0;
+ do {
+ res |= code & 1;
+ code >>= 1, res <<= 1;
+ } while (--len > 0);
+ return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(deflate_state *s)
+{
+ if (s->bi_valid == 16) {
+ put_short(s, s->bi_buf);
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ } else if (s->bi_valid >= 8) {
+ put_byte(s, (Byte)s->bi_buf);
+ s->bi_buf >>= 8;
+ s->bi_valid -= 8;
+ }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(deflate_state *s)
+{
+ if (s->bi_valid > 8) {
+ put_short(s, s->bi_buf);
+ } else if (s->bi_valid > 0) {
+ put_byte(s, (Byte)s->bi_buf);
+ }
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+#ifdef DEBUG
+ s->bits_sent = (s->bits_sent+7ul) & ~7ul; /*MAB add ul */
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(deflate_state *s, charf *buf, unsigned int len, int header)
+
+ /* the input data */
+ /* its length */
+ /* true if block header must be written */
+{
+ bi_windup(s); /* align on byte boundary */
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+
+ if (header) {
+ put_short(s, (ush)len);
+ put_short(s, (ush)~len);
+#ifdef DEBUG
+ s->bits_sent += 2*16;
+#endif
+ }
+#ifdef DEBUG
+ s->bits_sent += (ulg)len<<3;
+#endif
+ while (len--) {
+ put_byte(s, *buf++);
+ }
+}
diff --git a/DroidFish/jni/gtb/compression/zlib/trees.h b/DroidFish/jni/gtb/compression/zlib/trees.h
new file mode 100644
index 0000000..72facf9
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/trees.h
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch _dist_code[DIST_CODE_LEN] = {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
+};
+
diff --git a/DroidFish/jni/gtb/compression/zlib/uncompr.c b/DroidFish/jni/gtb/compression/zlib/uncompr.c
new file mode 100644
index 0000000..953fbd6
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/uncompr.c
@@ -0,0 +1,57 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int ZEXPORT uncompress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+
+ err = inflateInit(&stream);
+ if (err != Z_OK) return err;
+
+ err = inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ inflateEnd(&stream);
+ if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
+ return Z_DATA_ERROR;
+ return err;
+ }
+ *destLen = stream.total_out;
+
+ err = inflateEnd(&stream);
+ return err;
+}
diff --git a/DroidFish/jni/gtb/compression/zlib/zcompress.c b/DroidFish/jni/gtb/compression/zlib/zcompress.c
new file mode 100644
index 0000000..425c56a
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/zcompress.c
@@ -0,0 +1,69 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least 0.1% larger than sourceLen plus
+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level)
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+
+ err = deflateInit(&stream, level);
+ if (err != Z_OK) return err;
+
+ err = deflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ deflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *destLen = stream.total_out;
+
+ err = deflateEnd(&stream);
+ return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
+{
+ return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
+
+/* ===========================================================================
+ If the default memLevel or windowBits for deflateInit() is changed, then
+ this function needs to be updated.
+ */
+uLong ZEXPORT compressBound (uLong sourceLen)
+{
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
+}
diff --git a/DroidFish/jni/gtb/compression/zlib/zconf.h b/DroidFish/jni/gtb/compression/zlib/zconf.h
new file mode 100644
index 0000000..03a9431
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/zconf.h
@@ -0,0 +1,332 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+# define deflateInit_ z_deflateInit_
+# define deflate z_deflate
+# define deflateEnd z_deflateEnd
+# define inflateInit_ z_inflateInit_
+# define inflate z_inflate
+# define inflateEnd z_inflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateCopy z_deflateCopy
+# define deflateReset z_deflateReset
+# define deflateParams z_deflateParams
+# define deflateBound z_deflateBound
+# define deflatePrime z_deflatePrime
+# define inflateInit2_ z_inflateInit2_
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateCopy z_inflateCopy
+# define inflateReset z_inflateReset
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# define uncompress z_uncompress
+# define adler32 z_adler32
+# define crc32 z_crc32
+# define get_crc_table z_get_crc_table
+# define zError z_zError
+
+# define alloc_func z_alloc_func
+# define free_func z_free_func
+# define in_func z_in_func
+# define out_func z_out_func
+# define Byte z_Byte
+# define uInt z_uInt
+# define uLong z_uLong
+# define Bytef z_Bytef
+# define charf z_charf
+# define intf z_intf
+# define uIntf z_uIntf
+# define uLongf z_uLongf
+# define voidpf z_voidpf
+# define voidp z_voidp
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
+# include /* for off_t */
+# include /* for SEEK_* and off_t */
+# ifdef VMS
+# include /* for off_t */
+# endif
+# define z_off_t off_t
+#endif
+#ifndef SEEK_SET
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if defined(__OS400__)
+# define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+# define NO_vsnprintf
+# ifdef FAR
+# undef FAR
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+# pragma map(deflateInit_,"DEIN")
+# pragma map(deflateInit2_,"DEIN2")
+# pragma map(deflateEnd,"DEEND")
+# pragma map(deflateBound,"DEBND")
+# pragma map(inflateInit_,"ININ")
+# pragma map(inflateInit2_,"ININ2")
+# pragma map(inflateEnd,"INEND")
+# pragma map(inflateSync,"INSY")
+# pragma map(inflateSetDictionary,"INSEDI")
+# pragma map(compressBound,"CMBND")
+# pragma map(inflate_table,"INTABL")
+# pragma map(inflate_fast,"INFA")
+# pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/DroidFish/jni/gtb/compression/zlib/zconf.in.h b/DroidFish/jni/gtb/compression/zlib/zconf.in.h
new file mode 100644
index 0000000..03a9431
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/zconf.in.h
@@ -0,0 +1,332 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+# define deflateInit_ z_deflateInit_
+# define deflate z_deflate
+# define deflateEnd z_deflateEnd
+# define inflateInit_ z_inflateInit_
+# define inflate z_inflate
+# define inflateEnd z_inflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateCopy z_deflateCopy
+# define deflateReset z_deflateReset
+# define deflateParams z_deflateParams
+# define deflateBound z_deflateBound
+# define deflatePrime z_deflatePrime
+# define inflateInit2_ z_inflateInit2_
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateCopy z_inflateCopy
+# define inflateReset z_inflateReset
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# define uncompress z_uncompress
+# define adler32 z_adler32
+# define crc32 z_crc32
+# define get_crc_table z_get_crc_table
+# define zError z_zError
+
+# define alloc_func z_alloc_func
+# define free_func z_free_func
+# define in_func z_in_func
+# define out_func z_out_func
+# define Byte z_Byte
+# define uInt z_uInt
+# define uLong z_uLong
+# define Bytef z_Bytef
+# define charf z_charf
+# define intf z_intf
+# define uIntf z_uIntf
+# define uLongf z_uLongf
+# define voidpf z_voidpf
+# define voidp z_voidp
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+# ifndef WIN32
+# define WIN32
+# endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
+# include /* for off_t */
+# include /* for SEEK_* and off_t */
+# ifdef VMS
+# include /* for off_t */
+# endif
+# define z_off_t off_t
+#endif
+#ifndef SEEK_SET
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if defined(__OS400__)
+# define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+# define NO_vsnprintf
+# ifdef FAR
+# undef FAR
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+# pragma map(deflateInit_,"DEIN")
+# pragma map(deflateInit2_,"DEIN2")
+# pragma map(deflateEnd,"DEEND")
+# pragma map(deflateBound,"DEBND")
+# pragma map(inflateInit_,"ININ")
+# pragma map(inflateInit2_,"ININ2")
+# pragma map(inflateEnd,"INEND")
+# pragma map(inflateSync,"INSY")
+# pragma map(inflateSetDictionary,"INSEDI")
+# pragma map(compressBound,"CMBND")
+# pragma map(inflate_table,"INTABL")
+# pragma map(inflate_fast,"INFA")
+# pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/DroidFish/jni/gtb/compression/zlib/zlib.h b/DroidFish/jni/gtb/compression/zlib/zlib.h
new file mode 100644
index 0000000..0228179
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/zlib.h
@@ -0,0 +1,1357 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.3, July 18th, 2005
+
+ Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.3"
+#define ZLIB_VERNUM 0x1230
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed
+ data. This version of the library supports only one compression method
+ (deflation) but other algorithms will be added later and will have the same
+ stream interface.
+
+ Compression can be done in a single step if the buffers are large
+ enough (for example if an input file is mmap'ed), or can be done by
+ repeated calls of the compression function. In the latter case, the
+ application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The compressed data format used by default by the in-memory functions is
+ the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+ around a deflate stream, which is itself documented in RFC 1951.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio using the functions that start
+ with "gz". The gzip format is different from the zlib format. gzip is a
+ gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+ This library can optionally read and write gzip streams in memory as well.
+
+ The zlib format was designed to be compact and fast for use in memory
+ and on communications channels. The gzip format was designed for single-
+ file compression on file systems, has a larger header than zlib to maintain
+ directory information, and uses a different, slower check method than zlib.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never
+ crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total nb of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total nb of bytes output so far */
+
+ char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: binary or text */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ gzip header information passed to and from zlib routines. See RFC 1952
+ for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+ int text; /* true if compressed data believed to be text */
+ uLong time; /* modification time */
+ int xflags; /* extra flags (not used when writing a gzip file) */
+ int os; /* operating system */
+ Bytef *extra; /* pointer to extra field or Z_NULL if none */
+ uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
+ uInt extra_max; /* space at extra (only when reading header) */
+ Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
+ uInt name_max; /* space at name (only when reading header) */
+ Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
+ uInt comm_max; /* space at comment (only when reading header) */
+ int hcrc; /* true if there was or will be a header crc */
+ int done; /* true when done reading gzip header (not used
+ when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+ The application must update next_in and avail_in when avail_in has
+ dropped to zero. It must update next_out and avail_out when avail_out
+ has dropped to zero. The application must initialize zalloc, zfree and
+ opaque before calling the init function. All other fields are set by the
+ compression library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this
+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
+ have their offset normalized to zero. The default allocation function
+ provided by this library ensures this (see zutil.c). To reduce memory
+ requirements and avoid any allocation of 64K objects, at the expense of
+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or
+ progress reports. After compression, total_in holds the total size of
+ the uncompressed data and may be saved for use in the decompressor
+ (particularly if the decompressor wants to decompress everything in
+ a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+#define Z_BLOCK 5
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_RLE 3
+#define Z_FIXED 4
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_TEXT 1
+#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+ /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is
+ not compatible with the zlib.h header file used by the application.
+ This check is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller.
+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+ use default allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
+ all (the input data is simply copied a block at a time).
+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+ compression (currently equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION).
+ msg is set to null if there is no error message. deflateInit does not
+ perform any compression: this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce some
+ output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications).
+ Some output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating avail_in or avail_out accordingly; avail_out
+ should never be zero before the call. The application can consume the
+ compressed output when it wants, for example when the output buffer is full
+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+ and with zero avail_out, it must be called again after making room in the
+ output buffer because there might be more output pending.
+
+ Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+ decide how much data to accumualte before producing output, in order to
+ maximize compression.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In particular
+ avail_in is zero after the call if enough output space has been provided
+ before the call.) Flushing may degrade compression for some compression
+ algorithms and so it should be used only when necessary.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out is greater than six to avoid repeated flush markers due to
+ avail_out == 0 on return.
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there
+ was enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the
+ stream are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least
+ the value returned by deflateBound (see below). If deflate does not return
+ Z_STREAM_END, then it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update strm->data_type if it can make a good guess about
+ the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect
+ the compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+ fatal, and deflate() can be called again with more input and more output
+ space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case,
+ msg may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+ value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller. msg is set to null if there is no error
+ message. inflateInit does not perform any decompression apart from reading
+ the zlib header if present: this will be done by inflate(). (So next_in and
+ avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing
+ will resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there
+ is no more input data or no more space in the output buffer (see below
+ about the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating the next_* and avail_* values accordingly.
+ The application can consume the uncompressed output when it wants, for
+ example when the output buffer is full (avail_out == 0), or after each
+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+ must be called again after making room in the output buffer because there
+ might be more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
+ Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate() stop
+ if and when it gets to the next deflate block boundary. When decoding the
+ zlib or gzip format, this will cause inflate() to return immediately after
+ the header and before the first block. When doing a raw inflate, inflate()
+ will go ahead and process the first block, and will return when it gets to
+ the end of that block, or when it runs out of data.
+
+ The Z_BLOCK option assists in appending to or combining deflate streams.
+ Also to assist in this, on return inflate() will set strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64
+ if inflate() is currently decoding the last block in the deflate stream,
+ plus 128 if inflate() returned immediately after decoding an end-of-block
+ code or decoding the complete header up to just before the first byte of the
+ deflate stream. The end-of-block will not be indicated until all of the
+ uncompressed data from that block has been written to strm->next_out. The
+ number of unused bits may in general be greater than seven, except when
+ bit 7 of data_type is set, in which case the number of unused bits will be
+ less than eight.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step
+ (a single call of inflate), the parameter flush should be set to
+ Z_FINISH. In this case all pending input is processed and all pending
+ output is flushed; avail_out must be large enough to hold all the
+ uncompressed data. (The size of the uncompressed data may have been saved
+ by the compressor for this purpose.) The next operation on this stream must
+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+ is never required, but can be used to inform inflate that a faster approach
+ may be used for the single inflate() call.
+
+ In this implementation, inflate() always flushes as much output as
+ possible to the output buffer, and always uses the faster approach on the
+ first call. So the only effect of the flush parameter in this implementation
+ is on the return value of inflate(), as noted below, or when it returns early
+ because Z_BLOCK is used.
+
+ If a preset dictionary is needed after this call (see inflateSetDictionary
+ below), inflate sets strm->adler to the adler32 checksum of the dictionary
+ chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+ strm->adler to the adler32 checksum of all output produced so far (that is,
+ total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+ below. At the end of the stream, inflate() checks that its computed adler32
+ checksum is equal to that saved by the compressor and returns Z_STREAM_END
+ only if the checksum is correct.
+
+ inflate() will decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically. Any information
+ contained in the gzip header is not retained, so applications that need that
+ information should instead use raw inflate, see inflateInit2() below, or
+ inflateBack() and perform their own processing of the gzip header and
+ trailer.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect check
+ value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
+ Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+ output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ inflate() can be called again with more input and more output space to
+ continue decompressing. If Z_DATA_ERROR is returned, the application may then
+ call inflateSync() to look for a good compression block if a partial recovery
+ of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by
+ the caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
+ with no zlib header or trailer, and will not compute an adler32 check value.
+
+ windowBits can also be greater than 15 for optional gzip encoding. Add
+ 16 to windowBits to write a simple gzip header and trailer around the
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero),
+ no header crc, and the operating system will be set to 255 (unknown). If a
+ gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but
+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
+ for optimal speed. The default value is 8. See zconf.h for total memory
+ usage as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match), or Z_RLE to limit match distances to one (run-length
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
+ coding and less string matching; it is somewhat intermediate between
+ Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
+ Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
+ parameter only affects the compression ratio but not the correctness of the
+ compressed output even if it is not set appropriately. Z_FIXED prevents the
+ use of dynamic Huffman codes, allowing for a simpler decoder for special
+ applications.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+ method). msg is set to null if there is no error message. deflateInit2 does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. This function must be called
+ immediately after deflateInit, deflateInit2 or deflateReset, before any
+ call of deflate. The compressor and decompressor must use exactly the same
+ dictionary (see inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size in
+ deflate or deflate2. Thus the strings most likely to be useful should be
+ put at the end of the dictionary, not at the front. In addition, the
+ current implementation of deflate will use at most the window size minus
+ 262 bytes of the provided dictionary.
+
+ Upon return of this function, strm->adler is set to the adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.) If a raw deflate was requested, then the
+ adler32 value is not computed and strm->adler is not set.
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if the compression method is bsort). deflateSetDictionary does not
+ perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and
+ can consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state.
+ The stream will keep the same compression level and any other attributes
+ that may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different
+ strategy. If the compression level is changed, the input available so far
+ is compressed with the old level (and may be flushed); the new level will
+ take effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to
+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+ if strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+ int good_length,
+ int max_lazy,
+ int nice_length,
+ int max_chain));
+/*
+ Fine tune deflate's internal compression parameters. This should only be
+ used by someone who understands the algorithm used by zlib's deflate for
+ searching for the best matching string, and even then only by the most
+ fanatic optimizer trying to squeeze out the last compressed bit for their
+ specific input data. Read the deflate.c source code for the meaning of the
+ max_lazy, good_length, nice_length, and max_chain parameters.
+
+ deflateTune() can be called after deflateInit() or deflateInit2(), and
+ returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+ uLong sourceLen));
+/*
+ deflateBound() returns an upper bound on the compressed size after
+ deflation of sourceLen bytes. It must be called after deflateInit()
+ or deflateInit2(). This would be used to allocate an output buffer
+ for deflation in a single pass, and so would be called before deflate().
+*/
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ deflatePrime() inserts bits in the deflate output stream. The intent
+ is that this function is used to start off the deflate output with the
+ bits leftover from a previous deflate stream when appending to it. As such,
+ this function can only be used for raw deflate, and must be used before the
+ first deflate() call after a deflateInit2() or deflateReset(). bits must be
+ less than or equal to 16, and that many of the least significant bits of
+ value will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ deflateSetHeader() provides gzip header information for when a gzip
+ stream is requested by deflateInit2(). deflateSetHeader() may be called
+ after deflateInit2() or deflateReset() and before the first call of
+ deflate(). The text, time, os, extra field, name, and comment information
+ in the provided gz_header structure are written to the gzip header (xflag is
+ ignored -- the extra flags are set according to the compression level). The
+ caller must assure that, if not Z_NULL, name and comment are terminated with
+ a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+ available there. If hcrc is true, a gzip header crc is included. Note that
+ the current versions of the command-line version of gzip (up through version
+ 1.3.x) do not support header crc's, and will report that it is a "multi-part
+ gzip file" and give up.
+
+ If deflateSetHeader is not used, the default gzip header has text false,
+ the time set to zero, and os set to 255, with no extra, name, or comment
+ fields. The gzip header is returned to the default state by deflateReset().
+
+ deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
+ provided to deflateInit2() while compressing, or it must be equal to 15 if
+ deflateInit2() was not used. If a compressed stream with a larger window
+ size is given as input, inflate() will return with the error code
+ Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
+ not looking for a zlib or gzip header, not generating a check value, and not
+ looking for any check values for comparison at the end of the stream. This
+ is for use with other formats that use the deflate compressed data format
+ such as zip. Those formats provide their own check values. If a custom
+ format is developed using the raw deflate format for compressed data, it is
+ recommended that a check value such as an adler32 or a crc32 be applied to
+ the uncompressed data as is done in the zlib, gzip, and zip formats. For
+ most applications, the zlib format should be used as is. Note that comments
+ above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+ windowBits can also be greater than 15 for optional gzip decoding. Add
+ 32 to windowBits to enable zlib and gzip decoding with automatic header
+ detection, or add 16 to decode only the gzip format (the zlib format will
+ return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
+ a crc32 instead of an adler32.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
+ is set to null if there is no error message. inflateInit2 does not perform
+ any decompression apart from reading the zlib header if present: this will
+ be done by inflate(). (So next_in and avail_in may be modified, but next_out
+ and avail_out are unchanged.)
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate,
+ if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the adler32 value returned by that call of inflate.
+ The compressor and decompressor must use exactly the same dictionary (see
+ deflateSetDictionary). For raw inflate, this function can be called
+ immediately after inflateInit2() or inflateReset() and before any call of
+ inflate() to set the dictionary. The application must insure that the
+ dictionary that was used for compression is provided.
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a full flush point (see above the
+ description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+ case, the application may save the current current value of total_in which
+ indicates where valid compressed data was found. In the error case, the
+ application may repeatedly call inflateSync, providing more input each time,
+ until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when randomly accessing a large stream. The
+ first pass through the stream can periodically record the inflate state,
+ allowing restarting inflate at those points when randomly accessing the
+ stream.
+
+ inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state.
+ The stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ This function inserts bits in the inflate input stream. The intent is
+ that this function is used to start inflating at a bit position in the
+ middle of a byte. The provided bits will be used before any bytes are used
+ from next_in. This function should only be used with raw inflate, and
+ should be used before the first inflate() call after inflateInit2() or
+ inflateReset(). bits must be less than or equal to 16, and that many of the
+ least significant bits of value will be inserted in the input.
+
+ inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+ gz_headerp head));
+/*
+ inflateGetHeader() requests that gzip header information be stored in the
+ provided gz_header structure. inflateGetHeader() may be called after
+ inflateInit2() or inflateReset(), and before the first call of inflate().
+ As inflate() processes the gzip stream, head->done is zero until the header
+ is completed, at which time head->done is set to one. If a zlib stream is
+ being decoded, then head->done is set to -1 to indicate that there will be
+ no gzip header information forthcoming. Note that Z_BLOCK can be used to
+ force inflate() to return immediately after header processing is complete
+ and before any actual data is decompressed.
+
+ The text, time, xflags, and os fields are filled in with the gzip header
+ contents. hcrc is set to true if there is a header CRC. (The header CRC
+ was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+ contains the maximum number of bytes to write to extra. Once done is true,
+ extra_len contains the actual extra field length, and extra contains the
+ extra field, or that field truncated if extra_max is less than extra_len.
+ If name is not Z_NULL, then up to name_max characters are written there,
+ terminated with a zero unless the length is greater than name_max. If
+ comment is not Z_NULL, then up to comm_max characters are written there,
+ terminated with a zero unless the length is greater than comm_max. When
+ any of extra, name, or comment are not Z_NULL and the respective field is
+ not present in the header, then that field is set to Z_NULL to signal its
+ absence. This allows the use of deflateSetHeader() with the returned
+ structure to duplicate the header. However if those fields are set to
+ allocated memory, then the application will need to save those pointers
+ elsewhere so that they can be eventually freed.
+
+ If inflateGetHeader is not used, then the header information is simply
+ discarded. The header is always checked for validity, including the header
+ CRC if present. inflateReset() will reset the process to discard the header
+ information. The application would need to call inflateGetHeader() again to
+ retrieve the header from the next gzip stream.
+
+ inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window));
+
+ Initialize the internal stream state for decompression using inflateBack()
+ calls. The fields zalloc, zfree and opaque in strm must be initialized
+ before the call. If zalloc and zfree are Z_NULL, then the default library-
+ derived memory allocation routines are used. windowBits is the base two
+ logarithm of the window size, in the range 8..15. window is a caller
+ supplied buffer of that size. Except for special applications where it is
+ assured that deflate was used with small window sizes, windowBits must be 15
+ and a 32K byte window must be supplied to be able to decompress general
+ deflate streams.
+
+ See inflateBack() for the usage of these routines.
+
+ inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+ the paramaters are invalid, Z_MEM_ERROR if the internal state could not
+ be allocated, or Z_VERSION_ERROR if the version of the library does not
+ match the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+/*
+ inflateBack() does a raw inflate with a single call using a call-back
+ interface for input and output. This is more efficient than inflate() for
+ file i/o applications in that it avoids copying between the output and the
+ sliding window by simply making the window itself the output buffer. This
+ function trusts the application to not change the output buffer passed by
+ the output function, at least until inflateBack() returns.
+
+ inflateBackInit() must be called first to allocate the internal state
+ and to initialize the state with the user-provided window buffer.
+ inflateBack() may then be used multiple times to inflate a complete, raw
+ deflate stream with each call. inflateBackEnd() is then called to free
+ the allocated state.
+
+ A raw deflate stream is one with no zlib or gzip header or trailer.
+ This routine would normally be used in a utility that reads zip or gzip
+ files and writes out uncompressed files. The utility would decode the
+ header and process the trailer on its own, hence this routine expects
+ only the raw deflate stream to decompress. This is different from the
+ normal behavior of inflate(), which expects either a zlib or gzip header and
+ trailer around the deflate stream.
+
+ inflateBack() uses two subroutines supplied by the caller that are then
+ called by inflateBack() for input and output. inflateBack() calls those
+ routines until it reads a complete deflate stream and writes out all of the
+ uncompressed data, or until it encounters an error. The function's
+ parameters and return types are defined above in the in_func and out_func
+ typedefs. inflateBack() will call in(in_desc, &buf) which should return the
+ number of bytes of provided input, and a pointer to that input in buf. If
+ there is no input available, in() must return zero--buf is ignored in that
+ case--and inflateBack() will return a buffer error. inflateBack() will call
+ out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
+ should return zero on success, or non-zero on failure. If out() returns
+ non-zero, inflateBack() will return with an error. Neither in() nor out()
+ are permitted to change the contents of the window provided to
+ inflateBackInit(), which is also the buffer that out() uses to write from.
+ The length written by out() will be at most the window size. Any non-zero
+ amount of input may be provided by in().
+
+ For convenience, inflateBack() can be provided input on the first call by
+ setting strm->next_in and strm->avail_in. If that input is exhausted, then
+ in() will be called. Therefore strm->next_in must be initialized before
+ calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
+ immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
+ must also be initialized, and then if strm->avail_in is not zero, input will
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+ The in_desc and out_desc parameters of inflateBack() is passed as the
+ first parameter of in() and out() respectively when they are called. These
+ descriptors can be optionally used to pass any information that the caller-
+ supplied in() and out() functions need to do their job.
+
+ On return, inflateBack() will set strm->next_in and strm->avail_in to
+ pass back any unused input that was provided by the last in() call. The
+ return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format
+ error in the deflate stream (in which case strm->msg is set to indicate the
+ nature of the error), or Z_STREAM_ERROR if the stream was not properly
+ initialized. In the case of Z_BUF_ERROR, an input or output error can be
+ distinguished using strm->next_in which will be Z_NULL only if in() returned
+ an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
+ out() returning non-zero. (in() will always be called before out(), so
+ strm->next_in is assured to be defined if out() returns non-zero.) Note
+ that inflateBack() cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+ All memory allocated by inflateBackInit() is freed.
+
+ inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+ state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+ Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+ 1.0: size of uInt
+ 3.2: size of uLong
+ 5.4: size of voidpf (pointer)
+ 7.6: size of z_off_t
+
+ Compiler, assembler, and debug options:
+ 8: DEBUG
+ 9: ASMV or ASMINF -- use ASM code
+ 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+ 11: 0 (reserved)
+
+ One-time table building (smaller code, but not thread-safe if true):
+ 12: BUILDFIXED -- build static block decoding tables when needed
+ 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+ 14,15: 0 (reserved)
+
+ Library content (indicates missing functionality):
+ 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+ deflate code when not needed)
+ 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+ and decode gzip streams (to avoid linking crc code)
+ 18-19: 0 (reserved)
+
+ Operation variations (changes in library functionality):
+ 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+ 21: FASTEST -- deflate algorithm with only one, lowest compression level
+ 22,23: 0 (reserved)
+
+ The sprintf variant used by gzprintf (zero is best):
+ 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+ 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+ 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+ Remainder:
+ 27-31: 0 (reserved)
+ */
+
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the
+ basic stream-oriented functions. To simplify the interface, some
+ default options are assumed (compression level and memory usage,
+ standard memory allocation functions). The source code of these
+ utility functions can easily be modified if you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be at least the value returned
+ by compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+ This function can be used to compress a whole file at once if the
+ input file is mmap'ed.
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+ compressBound() returns an upper bound on the compressed size after
+ compress() or compress2() on sourceLen bytes. It would be used before
+ a compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+*/
+
+
+typedef voidp gzFile;
+
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+/*
+ Opens a gzip (.gz) file for reading or writing. The mode parameter
+ is as in fopen ("rb" or "wb") but can also include a compression level
+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
+ Huffman only compression as in "wb1h", or 'R' for run-length encoding
+ as in "wb1R". (See the description of deflateInit2 for more information
+ about the strategy parameter.)
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression.
+
+ gzopen returns NULL if the file could not be opened or if there was
+ insufficient memory to allocate the (de)compression state; errno
+ can be checked to distinguish the two cases (if errno is zero, the
+ zlib error is Z_MEM_ERROR). */
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen() associates a gzFile with the file descriptor fd. File
+ descriptors are obtained from calls like open, dup, creat, pipe or
+ fileno (in the file has been previously opened with fopen).
+ The mode parameter is as in gzopen.
+ The next call of gzclose on the returned gzFile will also close the
+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+ gzdopen returns NULL if there was insufficient memory to allocate
+ the (de)compression state.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters.
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+ opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file.
+ If the input file was not in gzip format, gzread copies the given number
+ of bytes into the buffer.
+ gzread returns the number of uncompressed bytes actually read (0 for
+ end of file, -1 for error). */
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes actually written
+ (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the args to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written (0 in case of error). The number of
+ uncompressed bytes written is limited to 4095. The caller should assure that
+ this limit is not exceeded. If it is exceeded, then gzprintf() will return
+ return an error (0) with nothing written. In this case, there may also be a
+ buffer overflow with unpredictable consequences, which is possible only if
+ zlib was compiled with the insecure functions sprintf() or vsprintf()
+ because the secure snprintf() or vsnprintf() functions were not available.
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or
+ a newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. The string is then terminated with a null
+ character.
+ gzgets returns buf, or Z_NULL in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file.
+ gzputc returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte
+ or -1 in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+ Push one character back onto the stream to be read again later.
+ Only one character of push-back is allowed. gzungetc() returns the
+ character pushed, or -1 on failure. gzungetc() will fail if a
+ character has been pushed but not read yet, or if c is -1. The pushed
+ character will be discarded if the stream is repositioned with gzseek()
+ or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter
+ flush is as in the deflate() function. The return value is the zlib
+ error number (see function gzerror below). gzflush returns Z_OK if
+ the flush parameter is Z_FINISH and all output could be flushed.
+ gzflush should be called only when strictly necessary because it can
+ degrade compression.
+*/
+
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+/*
+ Sets the starting position for the next gzread or gzwrite on the
+ given compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
+/*
+ Returns the starting position for the next gzread or gzwrite on the
+ given compressed file. This position represents a number of bytes in the
+ uncompressed data stream.
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns 1 when EOF has previously been detected reading the given
+ input stream, otherwise zero.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+ Returns 1 if file is being read directly without decompression, otherwise
+ zero.
+*/
+
+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file
+ and deallocates all the (de)compression state. The return value is the zlib
+ error number (see function gzerror below).
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the
+ given compressed file. errnum is set to zlib error number. If an
+ error occurred in the file system and not in the compression library,
+ errnum is set to Z_ERRNO and the application may consult errno
+ to get the exact error code.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
+ file that is being written concurrently.
+*/
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the
+ compression library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is NULL, this function returns
+ the required initial value for the checksum.
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster. Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+ z_off_t len2));
+/*
+ Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
+ and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+ each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
+ seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
+*/
+
+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running CRC-32 with the bytes buf[0..len-1] and return the
+ updated CRC-32. If buf is NULL, this function returns the required initial
+ value for the for the crc. Pre- and post-conditioning (one's complement) is
+ performed within this function so it shouldn't be done by the application.
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+/*
+ Combine two CRC-32 check values into one. For two sequences of bytes,
+ seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+ calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
+ check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+ len2.
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN const char * ZEXPORT zError OF((int));
+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/DroidFish/jni/gtb/compression/zlib/zutil.c b/DroidFish/jni/gtb/compression/zlib/zutil.c
new file mode 100644
index 0000000..ff4d75c
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/zutil.c
@@ -0,0 +1,354 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#ifndef NO_DUMMY_DECL
+struct internal_state {int dummy;}; /* for buggy compilers */
+#endif
+
+const char * const z_errmsg[10] = {
+"need dictionary", /* Z_NEED_DICT 2 */
+"stream end", /* Z_STREAM_END 1 */
+"", /* Z_OK 0 */
+"file error", /* Z_ERRNO (-1) */
+"stream error", /* Z_STREAM_ERROR (-2) */
+"data error", /* Z_DATA_ERROR (-3) */
+"insufficient memory", /* Z_MEM_ERROR (-4) */
+"buffer error", /* Z_BUF_ERROR (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion(void)
+{
+ return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags(void)
+{
+ #if 1
+ size_t uInt_size;
+ size_t uLong_size;
+ size_t voidpf_size;
+ size_t z_off_t_size;
+ #endif
+
+ uLong flags;
+ flags = 0;
+
+/*MAB: The following #if was introduced to silence intel compiler */
+#if 1
+ uInt_size = sizeof(uInt);
+ uLong_size = sizeof(uLong);
+ voidpf_size = sizeof(voidpf);
+ z_off_t_size = sizeof(z_off_t);
+
+ switch (uInt_size) {
+ case 2: break;
+ case 4: flags += 1; break;
+ case 8: flags += 2; break;
+ default: flags += 3;
+ }
+ switch (uLong_size) {
+ case 2: break;
+ case 4: flags += 1 << 2; break;
+ case 8: flags += 2 << 2; break;
+ default: flags += 3 << 2;
+ }
+ switch (voidpf_size) {
+ case 2: break;
+ case 4: flags += 1 << 4; break;
+ case 8: flags += 2 << 4; break;
+ default: flags += 3 << 4;
+ }
+ switch (z_off_t_size) {
+ case 2: break;
+ case 4: flags += 1 << 6; break;
+ case 8: flags += 2 << 6; break;
+ default: flags += 3 << 6;
+ }
+#else
+ switch (sizeof(uInt)) {
+ case 2: break;
+ case 4: flags += 1; break;
+ case 8: flags += 2; break;
+ default: flags += 3;
+ }
+
+ switch (sizeof(uLong)) {
+ case 2: break;
+ case 4: flags += 1 << 2; break;
+ case 8: flags += 2 << 2; break;
+ default: flags += 3 << 2;
+ }
+ switch (sizeof(voidpf)) {
+ case 2: break;
+ case 4: flags += 1 << 4; break;
+ case 8: flags += 2 << 4; break;
+ default: flags += 3 << 4;
+ }
+ switch (sizeof(z_off_t)) {
+ case 2: break;
+ case 4: flags += 1 << 6; break;
+ case 8: flags += 2 << 6; break;
+ default: flags += 3 << 6;
+ }
+#endif
+
+#ifdef DEBUG
+ flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+ flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+ flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+ flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+ flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+ flags += 1L << 16;
+#endif
+#ifdef NO_GZIP
+ flags += 1L << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+ flags += 1L << 20;
+#endif
+#ifdef FASTEST
+ flags += 1L << 21;
+#endif
+#ifdef STDC
+# ifdef NO_vsnprintf
+ flags += 1L << 25;
+# ifdef HAS_vsprintf_void
+ flags += 1L << 26;
+# endif
+# else
+# ifdef HAS_vsnprintf_void
+ flags += 1L << 26;
+# endif
+# endif
+#else
+ flags += 1L << 24;
+# ifdef NO_snprintf
+ flags += 1L << 25;
+# ifdef HAS_sprintf_void
+ flags += 1L << 26;
+# endif
+# else
+# ifdef HAS_snprintf_void
+ flags += 1L << 26;
+# endif
+# endif
+#endif
+ return flags;
+}
+
+#ifdef DEBUG
+
+# ifndef verbose
+# define verbose 0
+# endif
+int z_verbose = verbose;
+
+void z_error (m)
+ const char *m; /*MAB add const */
+{
+ fprintf(stderr, "%s\n", m);
+ exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(int err)
+{
+ return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+ /* The Microsoft C Run-Time Library for Windows CE doesn't have
+ * errno. We define it as a global variable to simplify porting.
+ * Its value is always 0 and should not be used.
+ */
+ int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void zmemcpy(dest, source, len)
+ Bytef* dest;
+ const Bytef* source;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = *source++; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+
+int zmemcmp(s1, s2, len)
+ const Bytef* s1;
+ const Bytef* s2;
+ uInt len;
+{
+ uInt j;
+
+ for (j = 0; j < len; j++) {
+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+ }
+ return 0;
+}
+
+void zmemzero(dest, len)
+ Bytef* dest;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = 0; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+#endif
+
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+ voidpf org_ptr;
+ voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ voidpf buf = opaque; /* just to make some compilers happy */
+ ulg bsize = (ulg)items*size;
+
+ /* If we allocate less than 65520 bytes, we assume that farmalloc
+ * will return a usable pointer which doesn't have to be normalized.
+ */
+ if (bsize < 65520L) {
+ buf = farmalloc(bsize);
+ if (*(ush*)&buf != 0) return buf;
+ } else {
+ buf = farmalloc(bsize + 16L);
+ }
+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+ table[next_ptr].org_ptr = buf;
+
+ /* Normalize the pointer to seg:0 */
+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+ *(ush*)&buf = 0;
+ table[next_ptr++].new_ptr = buf;
+ return buf;
+}
+
+void zcfree (voidpf opaque, voidpf ptr)
+{
+ int n;
+ if (*(ush*)&ptr != 0) { /* object < 64K */
+ farfree(ptr);
+ return;
+ }
+ /* Find the original pointer */
+ for (n = 0; n < next_ptr; n++) {
+ if (ptr != table[n].new_ptr) continue;
+
+ farfree(table[n].org_ptr);
+ while (++n < next_ptr) {
+ table[n-1] = table[n];
+ }
+ next_ptr--;
+ return;
+ }
+ ptr = opaque; /* just to make some compilers happy */
+ Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+# define _halloc halloc
+# define _hfree hfree
+#endif
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ return _halloc((long)items, size);
+}
+
+void zcfree (voidpf opaque, voidpf ptr)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp malloc OF((uInt size));
+extern voidp calloc OF((uInt items, uInt size));
+extern void free OF((voidpf ptr));
+#endif
+
+voidpf zcalloc (voidpf opaque, unsigned int items, unsigned int size)
+{
+ if (opaque) items += size - size; /* make compiler happy */
+ return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+ (voidpf)calloc(items, size);
+}
+
+void zcfree (voidpf opaque, voidpf ptr)
+{
+ free(ptr);
+ if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
diff --git a/DroidFish/jni/gtb/compression/zlib/zutil.h b/DroidFish/jni/gtb/compression/zlib/zutil.h
new file mode 100644
index 0000000..53dc6cd
--- /dev/null
+++ b/DroidFish/jni/gtb/compression/zlib/zutil.h
@@ -0,0 +1,269 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#ifdef STDC
+# ifndef _WIN32_WCE
+# include
+# endif
+# include
+# include
+#endif
+#ifdef NO_ERRNO_H
+# ifdef _WIN32_WCE
+ /* The Microsoft C Run-Time Library for Windows CE doesn't have
+ * errno. We define it as a global variable to simplify porting.
+ * Its value is always 0 and should not be used. We rename it to
+ * avoid conflict with other libraries that use the same workaround.
+ */
+# define errno z_errno
+# endif
+ extern int errno;
+#else
+# ifndef _WIN32_WCE
+# include
+# endif
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long ulg;
+
+extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+ return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+ /* common constants */
+
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+ /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+# define OS_CODE 0x00
+# if defined(__TURBOC__) || defined(__BORLANDC__)
+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+ /* Allow compilation with ANSI keywords only enabled */
+ void _Cdecl farfree( void *block );
+ void *_Cdecl farmalloc( unsigned long nbytes );
+# else
+# include
+# endif
+# else /* MSC or DJGPP */
+# include
+# endif
+#endif
+
+#ifdef AMIGA
+# define OS_CODE 0x01
+#endif
+
+#if defined(VAXC) || defined(VMS)
+# define OS_CODE 0x02
+# define F_OPEN(name, mode) \
+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#if defined(ATARI) || defined(atarist)
+# define OS_CODE 0x05
+#endif
+
+#ifdef OS2
+# define OS_CODE 0x06
+# ifdef M_I86
+ #include
+# endif
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+# define OS_CODE 0x07
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include /* for fdopen */
+# else
+# ifndef fdopen
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# endif
+# endif
+#endif
+
+#ifdef TOPS20
+# define OS_CODE 0x0a
+#endif
+
+#ifdef WIN32
+# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
+# define OS_CODE 0x0b
+# endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+# define OS_CODE 0x0f
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600))
+# if defined(_WIN32_WCE)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# ifndef _PTRDIFF_T_DEFINED
+ typedef int ptrdiff_t;
+# define _PTRDIFF_T_DEFINED
+# endif
+# else
+# define fdopen(fd,type) _fdopen(fd,type)
+# endif
+#endif
+
+ /* common defaults */
+
+#ifndef OS_CODE
+# define OS_CODE 0x03 /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+# define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+ /* functions */
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+#if defined(__CYGWIN__)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+#ifndef HAVE_VSNPRINTF
+# ifdef MSDOS
+ /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+ but for now we just assume it doesn't. */
+# define NO_vsnprintf
+# endif
+# ifdef __TURBOC__
+# define NO_vsnprintf
+# endif
+# ifdef WIN32
+ /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+# if !defined(vsnprintf) && !defined(NO_vsnprintf)
+# define vsnprintf _vsnprintf
+# endif
+# endif
+# ifdef __SASC
+# define NO_vsnprintf
+# endif
+#endif
+#ifdef VMS
+# define NO_vsnprintf
+#endif
+
+#if defined(pyr)
+# define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+ * You may have to use the same strategy for Borland C (untested).
+ * The __SC__ check is for Symantec.
+ */
+# define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+# define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+# define zmemcpy _fmemcpy
+# define zmemcmp _fmemcmp
+# define zmemzero(dest, len) _fmemset(dest, 0, len)
+# else
+# define zmemcpy memcpy
+# define zmemcmp memcmp
+# define zmemzero(dest, len) memset(dest, 0, len)
+# endif
+#else
+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+ extern void zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# include
+ extern int z_verbose;
+ extern void z_error OF((const char *m)); /*MAB add const*/
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+
+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+void zcfree OF((voidpf opaque, voidpf ptr));
+
+#define ZALLOC(strm, items, size) \
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* ZUTIL_H */
diff --git a/DroidFish/jni/gtb/gtb-att.c b/DroidFish/jni/gtb/gtb-att.c
new file mode 100644
index 0000000..6200164
--- /dev/null
+++ b/DroidFish/jni/gtb/gtb-att.c
@@ -0,0 +1,390 @@
+/*
+This Software is distributed with the following X11 License,
+sometimes also known as MIT license.
+
+Copyright (c) 2010 Miguel A. Ballicora
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include
+#include
+#include "gtb-att.h"
+
+#if 0
+
+#include "mtypes.h"
+#include "bool_t.h"
+#include "maindef.h"
+
+#else
+
+/* mtypes.h */
+
+typedef unsigned int SQUARE;
+typedef unsigned char SQ_CONTENT;
+
+/* bool_t.h */
+
+#if !defined(bool_t)
+typedef int bool_t;
+#endif
+
+#if !defined(TRUE)
+#define TRUE ((bool_t)1)
+#endif
+
+#if !defined(FALSE)
+#define FALSE ((bool_t)0)
+#endif
+
+/* maindef.h */
+
+#define NOPIECE 0u
+#define PAWN 1u
+#define KNIGHT 2u
+#define BISHOP 3u
+#define ROOK 4u
+#define QUEEN 5u
+#define KING 6u
+#define PIECE_MASK (KING|PAWN|KNIGHT|BISHOP|ROOK|QUEEN)
+
+/*Whites*/
+#define wK (KING | WHITES)
+#define wP (PAWN | WHITES)
+#define wN (KNIGHT | WHITES)
+#define wB (BISHOP | WHITES)
+#define wR (ROOK | WHITES)
+#define wQ (QUEEN | WHITES)
+
+/*Blacks*/
+#define bK (KING | BLACKS)
+#define bP (PAWN | BLACKS)
+#define bN (KNIGHT | BLACKS)
+#define bB (BISHOP | BLACKS)
+#define bR (ROOK | BLACKS)
+#define bQ (QUEEN | BLACKS)
+
+/*Bits that define color */
+
+#define WHITES (1u<<6)
+#define BLACKS (1u<<7)
+
+/*squares*/
+enum SQUARES {
+ A1,B1,C1,D1,E1,F1,G1,H1,
+ A2,B2,C2,D2,E2,F2,G2,H2,
+ A3,B3,C3,D3,E3,F3,G3,H3,
+ A4,B4,C4,D4,E4,F4,G4,H4,
+ A5,B5,C5,D5,E5,F5,G5,H5,
+ A6,B6,C6,D6,E6,F6,G6,H6,
+ A7,B7,C7,D7,E7,F7,G7,H7,
+ A8,B8,C8,D8,E8,F8,G8,H8,
+ NOSQUARE,
+ ERRSQUARE = 128
+};
+#endif
+
+/*----------------------------------------------------------------------*/
+
+#ifndef NDEBUG
+#define NDEBUG
+#endif
+#ifdef DEBUG
+#undef NDEBUG
+#endif
+#include "assert.h"
+
+/*----------------------------------------------------------------------*/
+
+/* global variables */
+uint64_t Reach [7] [64];
+
+/* static variables */
+static unsigned char attmap [64] [64];
+static unsigned int attmsk [256];
+
+/* static functions */
+static unsigned int mapx88 (unsigned int x);
+
+/* macros */
+#define BB_ISBITON(bb,bit) (0 != (((bb)>>(bit)) & U64(1)))
+
+#define map88(x) ( (x) + ((x)&070) )
+#define unmap88(x) ( ( (x) + ((x)& 07) ) >> 1 )
+
+/*----------------------------------------------------------------------*/
+
+static unsigned int
+mapx88 (unsigned int x)
+{
+ return ((x & 070) << 1) | (x & 07);
+}
+
+
+void
+attack_maps_init(void)
+{
+ int i;
+ unsigned int m, from, to;
+ unsigned int to88, fr88;
+ int diff;
+
+ uint64_t rook, bishop, queen, knight, king;
+
+ if (!reach_was_initialized()) {
+ printf ("Wrong initialization order of data\n");
+ exit(EXIT_FAILURE);
+ }
+
+ for (i = 0; i < 256; ++i) {
+ attmsk [i] = 0;
+ }
+ attmsk[wP] = 1 << 0;
+ attmsk[bP] = 1 << 1;
+
+ attmsk[KNIGHT] = 1 << 2;
+ attmsk[wN] = 1 << 2;
+ attmsk[bN] = 1 << 2;
+
+ attmsk[BISHOP] = 1 << 3;
+ attmsk[wB] = 1 << 3;
+ attmsk[bB] = 1 << 3;
+
+ attmsk[ROOK ] = 1 << 4;
+ attmsk[wR] = 1 << 4;
+ attmsk[bR] = 1 << 4;
+
+ attmsk[QUEEN ] = 1 << 5;
+ attmsk[wQ] = 1 << 5;
+ attmsk[bQ] = 1 << 5;
+
+ attmsk[KING ] = 1 << 6;
+ attmsk[wK] = 1 << 6;
+ attmsk[bK] = 1 << 6;
+
+ for (to = 0; to < 64; ++to) {
+ for (from = 0; from < 64; ++from) {
+ m = 0;
+ rook = Reach [ROOK] [from];
+ bishop = Reach [BISHOP] [from];
+ queen = Reach [QUEEN] [from];
+ knight = Reach [KNIGHT] [from];
+ king = Reach [KING] [from];
+
+ if (BB_ISBITON (knight, to)) {
+ m |= attmsk[wN];
+ }
+ if (BB_ISBITON (king, to)) {
+ m |= attmsk[wK];
+ }
+ if (BB_ISBITON (rook, to)) {
+ m |= attmsk[wR];
+ }
+ if (BB_ISBITON (bishop, to)) {
+ m |= attmsk[wB];
+ }
+ if (BB_ISBITON (queen, to)) {
+ m |= attmsk[wQ];
+ }
+
+ to88 = mapx88(to);
+ fr88 = mapx88(from);
+ diff = (int)to88 - (int)fr88;
+
+ if (diff == 17 || diff == 15) {
+ m |= attmsk[wP];
+ }
+ if (diff == -17 || diff == -15) {
+ m |= attmsk[bP];
+ }
+
+ attmap [to] [from] = (unsigned char) m;
+ }
+ }
+
+}
+
+bool_t
+possible_attack(unsigned int from, unsigned int to, unsigned int piece)
+{
+
+ assert (piece < 256);
+ assert (from < 64 && to < 64);
+ assert (reach_was_initialized());
+ assert (attmsk [piece] != 0 || 0==fprintf(stderr, "PIECE=%d\n",piece) ); /* means piece has been considered */
+
+ return 0 != (attmap [to] [from] & attmsk [piece]);
+}
+
+/*
+|
+| REACH ROUTINES
+|
+\*----------------------------------------------*/
+
+
+enum Key {REACH_INITIALIZED_KEY = 0x1313};
+static int reach_initialized_key = 0;
+
+bool_t
+reach_was_initialized (void)
+{
+ return reach_initialized_key == REACH_INITIALIZED_KEY;
+}
+
+void
+reach_init (void)
+{
+ SQUARE buflist[64+1], *list;
+ SQ_CONTENT pc;
+ int stp_a [] = {15, -15 };
+ int stp_b [] = {17, -17 };
+ int STEP_A, STEP_B;
+ unsigned int side;
+ unsigned int index;
+ SQUARE sq, us;
+
+ int s;
+
+ for (pc = KNIGHT; pc < (KING+1); pc++) {
+ for (sq = 0; sq < 64; sq++) {
+ uint64_t bb = U64(0x0);
+ tolist_rev (U64(0x0), pc, sq, buflist);
+ for (list = buflist; *list != NOSQUARE; list++) {
+ bb |= U64(1) << *list;
+ }
+ Reach [pc] [sq] = bb;
+ }
+ }
+
+ for (side = 0; side < 2; side++) {
+ index = 1u ^ side;
+ STEP_A = stp_a[side];
+ STEP_B = stp_b[side];
+ for (sq = 0; sq < 64; sq++) {
+
+ int sq88 = (int)map88(sq);
+ uint64_t bb = U64(0x0);
+
+ list = buflist;
+
+
+ s = sq88 + STEP_A;
+ if (0 == (s & 0x88)) {
+ us = (SQUARE)unmap88(s);
+ *list++ = us;
+ }
+ s = sq88 + STEP_B;
+ if (0 == (s & 0x88)) {
+ us = (SQUARE)unmap88(s);
+ *list++ = us;
+ }
+ *list = NOSQUARE;
+
+ for (list = buflist; *list != NOSQUARE; list++) {
+ bb |= U64(1) << *list;
+ }
+ Reach [index] [sq] = bb;
+ }
+ }
+ reach_initialized_key = REACH_INITIALIZED_KEY;
+}
+
+/*--------------------------------------------------------------------------------*/
+
+static const int bstep[] = { 17, 15, -15, -17, 0};
+static const int rstep[] = { 1, 16, -1, -16, 0};
+static const int nstep[] = { 18, 33, 31, 14, -18, -33, -31, -14, 0};
+static const int kstep[] = { 1, 17, 16, 15, -1, -17, -16, -15, 0};
+
+static const
+int *psteparr[] = {NULL, NULL, /* NOPIECE & PAWN */
+ nstep, bstep, rstep, kstep, kstep /* same for Q & K*/
+ };
+static const
+int pslider[] = {FALSE, FALSE,
+ FALSE, TRUE, TRUE, TRUE, FALSE
+ };
+
+void
+tolist_rev (uint64_t occ, SQ_CONTENT input_piece, SQUARE sq, SQUARE *list)
+/* reversible moves from pieces. Output is a list of squares */
+{
+ int direction;
+ unsigned int pc;
+ int s;
+ int from;
+ int step;
+ const int *steparr;
+ bool_t slider;
+ SQUARE us;
+
+ assert (sq < 64);
+
+ /* i.e. no pawn allowed as input */
+ assert (input_piece == KNIGHT || input_piece == BISHOP ||
+ input_piece == ROOK || input_piece == QUEEN ||
+ input_piece == KING);
+
+ from = (int)map88(sq);
+
+ pc = input_piece & (PAWN|KNIGHT|BISHOP|ROOK|QUEEN|KING);
+
+ steparr = psteparr [pc];
+ slider = pslider [pc];
+
+ if (slider) {
+
+ for (direction = 0; steparr[direction] != 0; direction++) {
+ step = steparr[direction];
+ s = from + step;
+ while (0 == (s & 0x88)) {
+ us = (SQUARE)unmap88(s);
+ if (0 != (0x1u & (unsigned int)(occ >> us)))
+ break;
+ *list++ = us;
+ s += step;
+ }
+ }
+
+ } else {
+
+ for (direction = 0; steparr[direction] != 0; direction++) {
+ step = steparr[direction];
+ s = from + step;
+ if (0 == (s & 0x88)) {
+ us = (SQUARE)unmap88(s);
+ if (0 == (0x1u & (unsigned int)(occ >> us))) {
+ *list++ = us;
+ }
+ }
+ }
+ }
+
+ *list = NOSQUARE;
+
+ return;
+}
+
+
+
diff --git a/DroidFish/jni/gtb/gtb-att.h b/DroidFish/jni/gtb/gtb-att.h
new file mode 100644
index 0000000..c89dbca
--- /dev/null
+++ b/DroidFish/jni/gtb/gtb-att.h
@@ -0,0 +1,43 @@
+/*
+This Software is distributed with the following X11 License,
+sometimes also known as MIT license.
+
+Copyright (c) 2010 Miguel A. Ballicora
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#if !defined(H_PROBATT)
+#define H_PROBATT
+/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
+#include "sysport.h"
+
+extern uint64_t Reach [7] [64];
+
+extern void attack_maps_init (void);
+extern int /*bool*/ possible_attack(unsigned int from, unsigned int to, unsigned int piece);
+extern void reach_init (void);
+extern int /*bool*/ reach_was_initialized (void);
+extern void tolist_rev (uint64_t occ, unsigned char input_piece, unsigned int sq, unsigned int *list);
+
+/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+#endif
diff --git a/DroidFish/jni/gtb/gtb-dec.c b/DroidFish/jni/gtb/gtb-dec.c
new file mode 100644
index 0000000..be87aea
--- /dev/null
+++ b/DroidFish/jni/gtb/gtb-dec.c
@@ -0,0 +1,133 @@
+/*
+This Software is distributed with the following X11 License,
+sometimes also known as MIT license.
+
+Copyright (c) 2010 Miguel A. Ballicora
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+/*--------------------------------------------------------------------------*\
+|
+| Compressing wrapper functions
+|
+*---------------------------------------------------------------------------*/
+#define MAXBLOCK (1 << 16)
+
+#include
+#include "gtb-dec.h"
+#include "hzip.h"
+#include "wrap.h"
+
+typedef int bool_t;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0;
+#endif
+
+/*static unsigned char intermediate_block[MAXBLOCK] ;*/
+
+static int DECODE_SCHEME = CP4;
+static int CP_SCHEME = CP4;
+
+static int f_decode (size_t z, unsigned char *bz, size_t n, unsigned char *bp);
+
+extern void
+set_decoding_scheme(int x)
+{
+ DECODE_SCHEME = x;
+ CP_SCHEME = x;
+}
+
+extern int decoding_scheme(void)
+{
+ return DECODE_SCHEME;
+}
+
+extern int
+decode (size_t z, unsigned char *bz, size_t n, unsigned char *bp)
+{
+ return f_decode (z, bz, n, bp);
+}
+
+/*======================== WRAPPERS ========================*/
+
+static int
+f_decode (size_t z, unsigned char *bz, size_t n, unsigned char *bp)
+{
+/* bp buffer provided
+| bz buffer "zipped", compressed
+| n len of buffer provided
+| z len of buffer zipped
+\*---------------------------------------------------------------*/
+
+/*
+ unsigned char *ib = intermediate_block;
+ unsigned int m;
+ return huff_decode (bz, z, ib, &m, MAXBLOCK) && rle_decode (ib, m, bp, &n, MAXBLOCK);
+*/
+
+ if (CP_SCHEME == CP1) {
+
+ /* HUFFMAN */
+ return huff_decode (bz, z, bp, &n, MAXBLOCK);
+
+ } else if (CP_SCHEME == CP2) {
+
+ /* LZF */
+ return lzf_decode (bz, z, bp, &n, MAXBLOCK);
+
+ } else if (CP_SCHEME == CP3) {
+
+ /* ZLIB */
+ return zlib_decode (bz, z, bp, &n, MAXBLOCK);
+
+ } else if (CP_SCHEME == CP4) {
+
+ /* LZMA86 */
+ return lzma_decode (bz, z, bp, &n, n); /* maximum needs to be the exact number that it will produce */
+
+ } else if (CP_SCHEME == CP7) {
+
+ /* RLE */
+ return rle_decode (bz, z, bp, &n, MAXBLOCK);
+
+ #if defined (LIBBZIP2)
+ } else if (CP_SCHEME == CP8) {
+
+ /* BZIP2 */
+ return bzip2_decode (bz, z, bp, &n, MAXBLOCK);
+ #endif
+
+ } else if (CP_SCHEME == CP9) {
+
+ return justcopy_decode (bz, z, bp, &n, MAXBLOCK);
+
+ } else {
+
+ return FALSE;
+ }
+}
+
diff --git a/DroidFish/jni/gtb/gtb-dec.h b/DroidFish/jni/gtb/gtb-dec.h
new file mode 100644
index 0000000..82ac347
--- /dev/null
+++ b/DroidFish/jni/gtb/gtb-dec.h
@@ -0,0 +1,50 @@
+/*
+This Software is distributed with the following X11 License,
+sometimes also known as MIT license.
+
+Copyright (c) 2010 Miguel A. Ballicora
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+/* gtb-dec.h */
+#if !defined(H_DECOD)
+#define H_DECOD
+
+/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
+#include
+
+enum Compression {CP0, CP1, CP2, CP3, CP4, CP5, CP6, CP7, CP8, CP9, CP_END};
+
+extern void set_decoding_scheme(int x);
+
+extern int decoding_scheme(void);
+
+extern int decode (size_t z, unsigned char *bz, size_t n, unsigned char *bp);
+
+/*
+This function should be included with the TB compressor
+extern int encode (size_t n, unsigned char *bp, size_t *z, unsigned char *bz);
+*/
+
+/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+#endif
diff --git a/DroidFish/jni/gtb/gtb-probe.c b/DroidFish/jni/gtb/gtb-probe.c
new file mode 100644
index 0000000..f97f489
--- /dev/null
+++ b/DroidFish/jni/gtb/gtb-probe.c
@@ -0,0 +1,8039 @@
+/*
+This Software is distributed with the following X11 License,
+sometimes also known as MIT license.
+
+Copyright (c) 2010 Miguel A. Ballicora
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+
+/* NBBOTF will remove the internal bitbase on the fly */
+#ifdef NBBOTF
+ #ifdef WDL_PROBE
+ #undef WDL_PROBE
+ #endif
+#else
+ #define WDL_PROBE
+#endif
+
+/*-- Intended to be modified to make public --> Supporting functions the TB generator ---------------------*/
+
+#ifdef GTB_SHARE
+#define SHARED_forbuilding
+#endif
+
+/*---------------------------------------------------------------------------------------------------------*/
+#include
+#include
+#include
+
+#include "gtb-probe.h"
+
+#if defined(SHARED_forbuilding)
+ #include "gtb-prob2.h"
+#else
+ #define mySHARED static
+ typedef unsigned char SQ_CONTENT;
+ typedef unsigned int SQUARE;
+#endif
+
+#include "sysport.h"
+#include "gtb-att.h"
+#include "gtb-types.h"
+
+/*---------------------------------------------------------------------------------------------------------*/
+/*#include "posit_t.h"*/
+
+#define MAX_LISTSIZE 17
+#if 0
+typedef unsigned sq_t;
+typedef unsigned char pc_t;
+typedef uint32_t mv_t;
+#endif
+
+struct posit {
+ sq_t ws[MAX_LISTSIZE];
+ sq_t bs[MAX_LISTSIZE];
+ pc_t wp[MAX_LISTSIZE];
+ pc_t bp[MAX_LISTSIZE];
+ sq_t ep;
+ unsigned int stm;
+ unsigned int cas;
+};
+typedef struct posit posit_t;
+
+#if 0
+typedef long int tbkey_t;
+#endif
+
+/*---------------------------------------------------------------------------------------------------------*/
+/*#include "bool_t.h"*/
+
+#if !defined(H_BOOL)
+typedef int bool_t;
+#endif
+
+#if !defined(TRUE)
+#define TRUE ((bool_t)1)
+#endif
+
+#if !defined(FALSE)
+#define FALSE ((bool_t)0)
+#endif
+
+/*--------- private if external building code is not present ----------------------------------------------*/
+
+#if !defined(SHARED_forbuilding)
+
+#define MAX_EGKEYS 145
+#define SLOTSIZE 1
+#define NOINDEX ((index_t)(-1))
+
+#if 0
+typedef unsigned short int dtm_t;
+typedef size_t index_t;
+/*typedef int index_t;*/
+#endif
+
+enum Loading_status {
+ STATUS_ABSENT = 0,
+ STATUS_STATICRAM = 1,
+ STATUS_MALLOC = 2,
+ STATUS_FILE = 3,
+ STATUS_REJECT = 4
+};
+
+struct endgamekey {
+ int id;
+ const char *str;
+ index_t maxindex;
+ index_t slice_n;
+ void (*itopc) (index_t, SQUARE *, SQUARE *);
+ bool_t (*pctoi) (const SQUARE *, const SQUARE *, index_t *);
+ dtm_t * egt_w;
+ dtm_t * egt_b;
+ FILE * fd;
+ int status;
+ int pathn;
+};
+#endif
+
+/*----------------------------------------------------------------------------------------------------------*/
+
+/* array for better moves */
+#ifdef GTB_SHARE
+mySHARED int bettarr [2] [8] [8];
+#endif
+
+/*------------ ENUMS ----------------------------------------------------------*/
+
+enum Mask_values {
+ RESMASK = tb_RESMASK,
+ INFOMASK = tb_INFOMASK,
+ PLYSHIFT = tb_PLYSHIFT
+};
+
+enum Info_values {
+ iDRAW = tb_DRAW,
+ iWMATE = tb_WMATE,
+ iBMATE = tb_BMATE,
+ iFORBID = tb_FORBID,
+
+ iDRAWt = tb_DRAW |4,
+ iWMATEt = tb_WMATE |4,
+ iBMATEt = tb_BMATE |4,
+ iUNKNOWN = tb_UNKNOWN,
+
+ iUNKNBIT = (1<<2)
+};
+
+/*-------------------------- inherited from a previous maindef.h -----------*/
+
+#define WHITES (1u<<6)
+#define BLACKS (1u<<7)
+
+#define NOPIECE 0u
+#define PAWN 1u
+#define KNIGHT 2u
+#define BISHOP 3u
+#define ROOK 4u
+#define QUEEN 5u
+#define KING 6u
+
+#define WH 0
+#define BL 1
+#define Opp(x) ((x)^1)
+#define wK (KING | WHITES)
+
+/*-------------------
+ SQUARES
+ -------------------*/
+
+/* from 1-63 different squares posibles */
+
+/*squares*/
+enum SQUARES {
+ A1,B1,C1,D1,E1,F1,G1,H1,
+ A2,B2,C2,D2,E2,F2,G2,H2,
+ A3,B3,C3,D3,E3,F3,G3,H3,
+ A4,B4,C4,D4,E4,F4,G4,H4,
+ A5,B5,C5,D5,E5,F5,G5,H5,
+ A6,B6,C6,D6,E6,F6,G6,H6,
+ A7,B7,C7,D7,E7,F7,G7,H7,
+ A8,B8,C8,D8,E8,F8,G8,H8,
+ NOSQUARE,
+ ERRSQUARE = 128
+};
+
+/*------------------- end of inherited from a previous maindef.h -----------*/
+
+#if !defined(NDEBUG)
+#define NDEBUG
+#endif
+#ifdef DEBUG
+#undef NDEBUG
+#endif
+#include "assert.h"
+
+/*------------------- general DEFINES--------------------------- -----------*/
+
+#define gtbNOSIDE ((unsigned)-1)
+#define gtbNOINDEX ((index_t)-1)
+
+/*************************************************\
+|
+| COMPRESSION SCHEMES
+|
+\*************************************************/
+
+#include "gtb-dec.h"
+
+static const char *const Extension[] = {
+ ".gtb.cp0"
+ ,".gtb.cp1"
+ ,".gtb.cp2"
+ ,".gtb.cp3"
+ ,".gtb.cp4"
+ ,".gtb.cp5"
+ ,".gtb.cp6"
+ ,".gtb.cp7"
+ ,".gtb.cp8"
+ ,".gtb.cp9"
+};
+
+/*************************************************\
+|
+| MOVES
+|
+\*************************************************/
+
+enum move_kind {
+ NORMAL_MOVE = 0,
+ CASTLE_MOVE,
+ PASSNT_MOVE,
+ PROMOT_MOVE
+};
+
+enum move_content {
+ NOMOVE = 0
+};
+
+#define MV_TYPE(mv) ( (BYTE) ((mv) >>6 & 3 ) )
+#define MV_TO(mv) ( (SQUARE) ((mv) >>8 & 63) )
+#define MV_PT(mv) ( (SQ_CONTENT) ((mv) >>(3+16) &7 ) )
+#define MV_TK(mv) ( (SQ_CONTENT) ((mv) >>(6+16) &7 ) )
+#define MV_FROM(mv) ( (SQUARE) ((mv) & 63) )
+
+/*
+| move,type,color,piece,from,to,taken,promoted
+*------------------------------------------------------------------*/
+
+#define MV_BUILD(mv,ty,co,pc,fr,to,tk,pm) ( \
+ (mv) = (fr) | (to)<< 8 | (ty)<< 6 | (co)<<8 \
+ | (pc)<<16 | (pm)<< (3+16) | (tk)<< (6+16) \
+)
+
+#define MV_ADD_TOTK(mv,to,tk) ( \
+ mv |= (uint32_t)(to) << 8 \
+ | (uint32_t)(tk) << (6+16) \
+)
+
+#define map88(x) ( (x) + ((x)&070) )
+#define unmap88(x) ( ( (x) + ((x)& 07) ) >> 1 )
+
+/*************************************************\
+|
+| STATIC VARIABLES
+|
+\*************************************************/
+
+static int GTB_scheme = 4;
+
+/*************************************************\
+|
+| needed for
+| PRE LOAD CACHE AND DEPENDENT FUNCTIONS
+|
+\*************************************************/
+
+#define EGTB_MAXBLOCKSIZE 65536
+
+static int GTB_MAXOPEN = 4;
+
+static bool_t Uncompressed = TRUE;
+static unsigned char Buffer_zipped [EGTB_MAXBLOCKSIZE];
+static unsigned char Buffer_packed [EGTB_MAXBLOCKSIZE];
+static unsigned int zipinfo_init (void);
+static void zipinfo_done (void);
+
+enum Flip_flags {
+ WE_FLAG = 1, NS_FLAG = 2, NW_SE_FLAG = 4
+}; /* used in flipt */
+
+struct filesopen {
+ int n;
+ tbkey_t *key;
+};
+
+/* STATIC GLOBALS */
+
+static struct filesopen fd = {0, NULL};
+
+static bool_t TB_INITIALIZED = FALSE;
+static bool_t DTM_CACHE_INITIALIZED = FALSE;
+
+static int WDL_FRACTION = 64;
+static int WDL_FRACTION_MAX = 128;
+
+static size_t DTM_cache_size = 0;
+static size_t WDL_cache_size = 0;
+
+static unsigned int TB_AVAILABILITY = 0;
+
+/* LOCKS */
+static mythread_mutex_t Egtb_lock;
+
+
+/****************************************************************************\
+ *
+ *
+ * DEBUGGING or PRINTING ZONE
+ *
+ *
+ ****************************************************************************/
+
+#if 0
+#define FOLLOW_EGTB
+#ifndef DEBUG
+#define DEBUG
+#endif
+#endif
+
+#define validsq(x) ((x) >= A1 && (x) <= H8)
+
+#if defined(DEBUG)
+static void print_pos (const sq_t *ws, const sq_t *bs, const pc_t *wp, const pc_t *bp);
+#endif
+
+#if defined(DEBUG) || defined(FOLLOW_EGTB)
+static void output_state (unsigned stm, const SQUARE *wSQ, const SQUARE *bSQ,
+ const SQ_CONTENT *wPC, const SQ_CONTENT *bPC);
+static const char *Square_str[64] = {
+ "a1","b1","c1","d1","e1","f1","g1","h1",
+ "a2","b2","c2","d2","e2","f2","g2","h2",
+ "a3","b3","c3","d3","e3","f3","g3","h3",
+ "a4","b4","c4","d4","e4","f4","g4","h4",
+ "a5","b5","c5","d5","e5","f5","g5","h5",
+ "a6","b6","c6","d6","e6","f6","g6","h6",
+ "a7","b7","c7","d7","e7","f7","g7","h7",
+ "a8","b8","c8","d8","e8","f8","g8","h8"
+};
+static const char *P_str[] = {
+ "--", "P", "N", "B", "R", "Q", "K"
+};
+#endif
+
+#ifdef FOLLOW_EGTB
+ #define STAB
+ #define STABCONDITION 1 /*(stm == BL && whiteSQ[0]==H1 && whiteSQ[1]==D1 && whiteSQ[2]==D3 && blackSQ[0]==C2 )*/
+ static bool_t GLOB_REPORT = TRUE;
+#endif
+
+#if defined(FOLLOW_EGTB)
+static const char *Info_str[8] = {
+ " Draw", " Wmate", " Bmate", "Illegal",
+ "~Draw", "~Wmate", "~Bmate", "Unknown"
+};
+#endif
+
+static void list_index (void);
+static void fatal_error(void) {
+ exit(EXIT_FAILURE);
+}
+
+#ifdef STAB
+ #define FOLLOW_LU(x,y) {if (GLOB_REPORT) printf ("************** %s: %lu\n", (x), (long unsigned)(y));}
+#else
+ #define FOLLOW_LU(x,y)
+#endif
+
+#ifdef STAB
+ #define FOLLOW_LULU(x,y,z) {if (GLOB_REPORT) printf ("************** %s: %lu, %lu\n", (x), (long unsigned)(y), (long unsigned)(z));}
+#else
+ #define FOLLOW_LULU(x,y,z)
+#endif
+
+#ifdef STAB
+ #define FOLLOW_label(x) {if (GLOB_REPORT) printf ("************** %s\n", (x));}
+#else
+ #define FOLLOW_label(x)
+#endif
+
+#ifdef STAB
+ #define FOLLOW_DTM(msg,dtm) {if (GLOB_REPORT) printf ("************** %s: %lu, info:%s, plies:%lu \n"\
+ , (msg), (long unsigned)(dtm), (Info_str[(dtm)&INFOMASK]), (long unsigned)((dtm)>>PLYSHIFT)\
+ );}
+#else
+ #define FOLLOW_DTM(msg,dtm)
+#endif
+
+
+/*--------------------------------*\
+|
+|
+| INDEXING FUNCTIONS
+|
+|
+*---------------------------------*/
+
+#define IDX_set_empty(x) {x=0;x--;}
+#define IDX_is_empty(x) (0==(1+(x)))
+
+#define NO_KKINDEX NOINDEX
+#define MAX_KKINDEX 462
+#define MAX_PPINDEX 576
+#define MAX_PpINDEX (24 * 48)
+/*1128*/
+#define MAX_AAINDEX ((63-62) + (62 * (127-62)/2) - 1 + 1)
+#define MAX_AAAINDEX (64*21*31)
+#define MAX_PP48_INDEX (1128)
+/* (24*23*22/6) + 24 * (24*23/2) */
+#define MAX_PPP48_INDEX 8648
+
+/* VARIABLES */
+
+static index_t kkidx [64] [64];
+static index_t ppidx [24] [48];
+static index_t pp48_idx[48][48];
+static index_t ppp48_idx[48][48][48];
+
+static sq_t wksq [MAX_KKINDEX];
+static sq_t bksq [MAX_KKINDEX];
+static sq_t pp48_sq_x[MAX_PP48_INDEX];
+static sq_t pp48_sq_y[MAX_PP48_INDEX];
+
+static index_t pp_hi24 [MAX_PPINDEX]; /* was unsigned int */
+static index_t pp_lo48 [MAX_PPINDEX];
+static unsigned int flipt [64] [64];
+static index_t aaidx [64] [64]; /* was unsigned int */
+static unsigned char aabase [MAX_AAINDEX];
+
+static uint8_t ppp48_sq_x[MAX_PPP48_INDEX];
+static uint8_t ppp48_sq_y[MAX_PPP48_INDEX];
+static uint8_t ppp48_sq_z[MAX_PPP48_INDEX];
+
+/* FUNCTIONS */
+
+static void init_indexing (int verbosity);
+static void norm_kkindex (SQUARE x, SQUARE y, /*@out@*/ SQUARE *pi, /*@out@*/ SQUARE *pj);
+static void pp_putanchorfirst (SQUARE a, SQUARE b, /*@out@*/ SQUARE *out_anchor, /*@out@*/ SQUARE *out_loosen);
+
+static index_t wsq_to_pidx24 (SQUARE pawn);
+static index_t wsq_to_pidx48 (SQUARE pawn);
+static SQUARE pidx24_to_wsq (index_t a);
+static SQUARE pidx48_to_wsq (index_t a);
+
+static SQUARE flipWE (SQUARE x) { return x ^ 07;}
+static SQUARE flipNS (SQUARE x) { return x ^ 070;}
+static SQUARE flipNW_SE (SQUARE x) { return ((x&7)<<3) | (x>>3);}
+static SQUARE getcol (SQUARE x) { return x & 7;}
+static SQUARE getrow (SQUARE x) { return x >> 3;}
+static bool_t in_queenside (sq_t x) { return 0 == (x & (1<<2));}
+
+/* 1:0 */
+static void kxk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+/* 2:0 */
+static void kabk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+static void kakb_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+static void kaak_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+/* 2:1 */
+static void kabkc_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+static void kaakb_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+/* 3:0 */
+static void kabck_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+static void kaabk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+static void kaaak_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+static void kabbk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+/* one pawn */
+static void kpk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+/* 1:1 one pawn */
+static void kakp_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+/* 2:0 one pawn */
+static void kapk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+/* 2:0 two pawns */
+static void kppk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+/* 2:1 one pawn */
+static void kapkb_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+static void kabkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+static void kaakp_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+/* 2:1 + 3:0 two pawns */
+static void kppka_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+static void kappk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+static void kapkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+/* 3:0 one pawn */
+static void kabpk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+static void kaapk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+/* three pawns */
+static void kpppk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+static void kppkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+/* 1:1 two pawns */
+static void kpkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+/* corresponding pc to index */
+static bool_t kxk_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);
+static bool_t kabk_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);
+static bool_t kakb_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);
+static bool_t kpk_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);
+static bool_t kakp_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);
+static bool_t kapk_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);
+static bool_t kppk_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);
+static bool_t kaak_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);
+static bool_t kabkc_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);
+
+static bool_t kaakb_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);/**/
+
+static bool_t kabck_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);
+static bool_t kaabk_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);/**/
+static bool_t kaaak_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);
+static bool_t kabbk_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);/**/
+static bool_t kapkb_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);
+static bool_t kabkp_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);
+static bool_t kaakp_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out);
+static bool_t kppka_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out);
+static bool_t kappk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out);
+static bool_t kapkp_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out);
+static bool_t kabpk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out);
+static bool_t kaapk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out);
+static bool_t kppkp_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out);
+static bool_t kpppk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out);
+static bool_t kpkp_pctoindex (const SQUARE *pw, const SQUARE *pb, /*@out@*/ index_t *out);
+
+/* testing functions */
+static bool_t test_kppk (void);
+static bool_t test_kaakb (void);
+static bool_t test_kaabk (void);
+static bool_t test_kaaak (void);
+static bool_t test_kabbk (void);
+static bool_t test_kapkb (void);
+static bool_t test_kabkp (void);
+static bool_t test_kppka (void);
+static bool_t test_kappk (void);
+static bool_t test_kapkp (void);
+static bool_t test_kabpk (void);
+static bool_t test_kaapk (void);
+static bool_t test_kaakp (void);
+static bool_t test_kppkp (void);
+static bool_t test_kpppk (void);
+
+static unsigned flip_type (SQUARE x, SQUARE y);
+static index_t init_kkidx (void);
+static index_t init_ppidx (void);
+static void init_flipt (void);
+static index_t init_aaidx (void);
+static index_t init_aaa (void);
+static index_t init_pp48_idx (void);
+static index_t init_ppp48_idx (void);
+
+enum TB_INDEXES
+ { MAX_KXK = MAX_KKINDEX*64
+ ,MAX_kabk = MAX_KKINDEX*64*64
+ ,MAX_kakb = MAX_KKINDEX*64*64
+ ,MAX_kpk = 24*64*64
+ ,MAX_kakp = 24*64*64*64
+ ,MAX_kapk = 24*64*64*64
+ ,MAX_kppk = MAX_PPINDEX*64*64
+ ,MAX_kpkp = MAX_PpINDEX*64*64
+ ,MAX_kaak = MAX_KKINDEX*MAX_AAINDEX
+ ,MAX_kabkc = MAX_KKINDEX*64*64*64
+ ,MAX_kabck = MAX_KKINDEX*64*64*64
+ ,MAX_kaakb = MAX_KKINDEX*MAX_AAINDEX*64
+ ,MAX_kaabk = MAX_KKINDEX*MAX_AAINDEX*64
+ ,MAX_kabbk = MAX_KKINDEX*MAX_AAINDEX*64
+ ,MAX_kaaak = MAX_KKINDEX*MAX_AAAINDEX
+ ,MAX_kapkb = 24*64*64*64*64
+ ,MAX_kabkp = 24*64*64*64*64
+ ,MAX_kabpk = 24*64*64*64*64
+ ,MAX_kppka = MAX_kppk*64
+ ,MAX_kappk = MAX_kppk*64
+ ,MAX_kapkp = MAX_kpkp*64
+ ,MAX_kaapk = 24*MAX_AAINDEX*64*64
+ ,MAX_kaakp = 24*MAX_AAINDEX*64*64
+ ,MAX_kppkp = 24*MAX_PP48_INDEX*64*64
+ ,MAX_kpppk = MAX_PPP48_INDEX*64*64
+};
+
+#if defined(SHARED_forbuilding)
+extern index_t
+biggest_memory_needed (void) {
+ return MAX_kabkc;
+}
+#endif
+
+/*--------------------------------*\
+|
+|
+| CACHE PROTOTYPES
+|
+|
+*---------------------------------*/
+
+#if !defined(SHARED_forbuilding)
+mySHARED bool_t get_dtm (tbkey_t key, unsigned side, index_t idx, dtm_t *out, bool_t probe_hard);
+#endif
+
+static bool_t get_dtm_from_cache (tbkey_t key, unsigned side, index_t idx, dtm_t *out);
+
+
+/*--------------------------------*\
+|
+|
+| INIT
+|
+|
+*---------------------------------*/
+
+static bool_t fd_init (struct filesopen *pfd);
+static void fd_done (struct filesopen *pfd);
+
+static void RAM_egtbfree (void);
+
+/*--------------------------------------------------------------------------*/
+#if !defined(SHARED_forbuilding)
+mySHARED void egtb_freemem (int i);
+#endif
+
+mySHARED struct endgamekey egkey[] = {
+
+{0, "kqk", MAX_KXK, 1, kxk_indextopc, kxk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{1, "krk", MAX_KXK, 1, kxk_indextopc, kxk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{2, "kbk", MAX_KXK, 1, kxk_indextopc, kxk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{3, "knk", MAX_KXK, 1, kxk_indextopc, kxk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{4, "kpk", MAX_kpk, 24,kpk_indextopc, kpk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+ /* 4 pieces */
+{5, "kqkq", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{6, "kqkr", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{7, "kqkb", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{8, "kqkn", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+
+{9, "krkr", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{10,"krkb", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{11,"krkn", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+
+{12,"kbkb", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{13,"kbkn", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+
+{14,"knkn", MAX_kakb, 1, kakb_indextopc, kakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+ /**/
+{15,"kqqk", MAX_kaak, 1, kaak_indextopc, kaak_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{16,"kqrk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{17,"kqbk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{18,"kqnk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+
+{19,"krrk", MAX_kaak, 1, kaak_indextopc, kaak_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{20,"krbk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{21,"krnk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+
+{22,"kbbk", MAX_kaak, 1, kaak_indextopc, kaak_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{23,"kbnk", MAX_kabk, 1, kabk_indextopc, kabk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+
+{24,"knnk", MAX_kaak, 1, kaak_indextopc, kaak_pctoindex, NULL , NULL ,NULL ,0, 0 },
+ /**/
+ /**/
+{25,"kqkp", MAX_kakp, 24,kakp_indextopc, kakp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{26,"krkp", MAX_kakp, 24,kakp_indextopc, kakp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{27,"kbkp", MAX_kakp, 24,kakp_indextopc, kakp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{28,"knkp", MAX_kakp, 24,kakp_indextopc, kakp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+ /**/
+{29,"kqpk", MAX_kapk, 24,kapk_indextopc, kapk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{30,"krpk", MAX_kapk, 24,kapk_indextopc, kapk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{31,"kbpk", MAX_kapk, 24,kapk_indextopc, kapk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{32,"knpk", MAX_kapk, 24,kapk_indextopc, kapk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+ /**/
+{33,"kppk", MAX_kppk, MAX_PPINDEX ,kppk_indextopc, kppk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+ /**/
+{34,"kpkp", MAX_kpkp, MAX_PpINDEX ,kpkp_indextopc, kpkp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+ /**/
+ /**/
+ /* 5 pieces */
+{ 35,"kqqqk", MAX_kaaak, 1, kaaak_indextopc, kaaak_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 36,"kqqrk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 37,"kqqbk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 38,"kqqnk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 39,"kqrrk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 40,"kqrbk", MAX_kabck, 1, kabck_indextopc, kabck_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 41,"kqrnk", MAX_kabck, 1, kabck_indextopc, kabck_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 42,"kqbbk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 43,"kqbnk", MAX_kabck, 1, kabck_indextopc, kabck_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 44,"kqnnk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 45,"krrrk", MAX_kaaak, 1, kaaak_indextopc, kaaak_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 46,"krrbk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 47,"krrnk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 48,"krbbk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 49,"krbnk", MAX_kabck, 1, kabck_indextopc, kabck_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 50,"krnnk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 51,"kbbbk", MAX_kaaak, 1, kaaak_indextopc, kaaak_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 52,"kbbnk", MAX_kaabk, 1, kaabk_indextopc, kaabk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 53,"kbnnk", MAX_kabbk, 1, kabbk_indextopc, kabbk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 54,"knnnk", MAX_kaaak, 1, kaaak_indextopc, kaaak_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 55,"kqqkq", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 56,"kqqkr", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 57,"kqqkb", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 58,"kqqkn", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 59,"kqrkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 60,"kqrkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 61,"kqrkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 62,"kqrkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 63,"kqbkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 64,"kqbkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 65,"kqbkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 66,"kqbkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 67,"kqnkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 68,"kqnkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 69,"kqnkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 70,"kqnkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 71,"krrkq", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 72,"krrkr", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 73,"krrkb", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 74,"krrkn", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 75,"krbkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 76,"krbkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 77,"krbkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 78,"krbkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 79,"krnkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 80,"krnkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 81,"krnkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 82,"krnkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 83,"kbbkq", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 84,"kbbkr", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 85,"kbbkb", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 86,"kbbkn", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 87,"kbnkq", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 88,"kbnkr", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 89,"kbnkb", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 90,"kbnkn", MAX_kabkc, 1, kabkc_indextopc, kabkc_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 91,"knnkq", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 92,"knnkr", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 93,"knnkb", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 94,"knnkn", MAX_kaakb, 1, kaakb_indextopc, kaakb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+
+{ 95,"kqqpk", MAX_kaapk, 24, kaapk_indextopc, kaapk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 96,"kqrpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 97,"kqbpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 98,"kqnpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{ 99,"krrpk", MAX_kaapk, 24, kaapk_indextopc, kaapk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{100,"krbpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{101,"krnpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{102,"kbbpk", MAX_kaapk, 24, kaapk_indextopc, kaapk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{103,"kbnpk", MAX_kabpk, 24, kabpk_indextopc, kabpk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{104,"knnpk", MAX_kaapk, 24, kaapk_indextopc, kaapk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+
+{105,"kqppk", MAX_kappk, MAX_PPINDEX, kappk_indextopc, kappk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{106,"krppk", MAX_kappk, MAX_PPINDEX, kappk_indextopc, kappk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{107,"kbppk", MAX_kappk, MAX_PPINDEX, kappk_indextopc, kappk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{108,"knppk", MAX_kappk, MAX_PPINDEX, kappk_indextopc, kappk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+
+{109,"kqpkq", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{110,"kqpkr", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{111,"kqpkb", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{112,"kqpkn", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{113,"krpkq", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{114,"krpkr", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{115,"krpkb", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{116,"krpkn", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{117,"kbpkq", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{118,"kbpkr", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{119,"kbpkb", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{120,"kbpkn", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{121,"knpkq", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{122,"knpkr", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{123,"knpkb", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{124,"knpkn", MAX_kapkb, 24, kapkb_indextopc, kapkb_pctoindex, NULL , NULL ,NULL ,0, 0 },
+
+{125,"kppkq", MAX_kppka, MAX_PPINDEX, kppka_indextopc, kppka_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{126,"kppkr", MAX_kppka, MAX_PPINDEX, kppka_indextopc, kppka_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{127,"kppkb", MAX_kppka, MAX_PPINDEX, kppka_indextopc, kppka_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{128,"kppkn", MAX_kppka, MAX_PPINDEX, kppka_indextopc, kppka_pctoindex, NULL , NULL ,NULL ,0, 0 },
+
+{129,"kqqkp", MAX_kaakp, 24, kaakp_indextopc, kaakp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{130,"kqrkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{131,"kqbkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{132,"kqnkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{133,"krrkp", MAX_kaakp, 24, kaakp_indextopc, kaakp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{134,"krbkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{135,"krnkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{136,"kbbkp", MAX_kaakp, 24, kaakp_indextopc, kaakp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{137,"kbnkp", MAX_kabkp, 24, kabkp_indextopc, kabkp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{138,"knnkp", MAX_kaakp, 24, kaakp_indextopc, kaakp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+
+{139,"kqpkp", MAX_kapkp, MAX_PpINDEX, kapkp_indextopc, kapkp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{140,"krpkp", MAX_kapkp, MAX_PpINDEX, kapkp_indextopc, kapkp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{141,"kbpkp", MAX_kapkp, MAX_PpINDEX, kapkp_indextopc, kapkp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{142,"knpkp", MAX_kapkp, MAX_PpINDEX, kapkp_indextopc, kapkp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+
+{143,"kppkp", MAX_kppkp, 24*MAX_PP48_INDEX, kppkp_indextopc, kppkp_pctoindex, NULL , NULL ,NULL ,0, 0 },
+{144,"kpppk", MAX_kpppk, MAX_PPP48_INDEX, kpppk_indextopc, kpppk_pctoindex, NULL , NULL ,NULL ,0, 0 },
+
+{MAX_EGKEYS, NULL, 0, 1, NULL, NULL, NULL, NULL ,NULL ,0 ,0}
+
+};
+
+static int eg_was_open[MAX_EGKEYS];
+
+static uint64_t Bytes_read = 0;
+
+/****************************************************************************\
+|
+|
+| PATH MANAGEMENT ZONE
+|
+|
+\****************************************************************************/
+
+#define MAXPATHLEN tb_MAXPATHLEN
+#define MAX_GTBPATHS 10
+
+static int Gtbpath_end_index = 0;
+static const char ** Gtbpath = NULL;
+
+/*---------------- EXTERNAL PATH MANAGEMENT --------------------------------*/
+
+extern const char *tbpaths_getmain (void) { return Gtbpath[0];}
+
+extern const char **
+tbpaths_init(void)
+{
+ const char **newps;
+ newps = (const char **) malloc (sizeof (char *));
+ if (newps != NULL) {
+ newps[0] = NULL;
+ }
+ return newps;
+}
+
+static const char **
+tbpaths_add_single(const char **ps, const char *newpath)
+{
+ size_t counter;
+ const char **newps;
+ size_t i, psize;
+ char *ppath;
+
+ if (NULL == ps)
+ return NULL;
+
+ psize = strlen(newpath) + 1;
+ ppath = (char *) malloc (psize * sizeof (char));
+ if (NULL == ppath)
+ return ps; /* failed to incorporate a new path */
+ for (i = 0; i < psize; i++) ppath[i] = newpath[i];
+
+ for (counter = 0; ps[counter] != NULL; counter++)
+ ;
+
+ /* cast to deal with const poisoning */
+ newps = (const char **) realloc ((char **)ps, sizeof(char *) * (counter+2));
+ if (newps != NULL) {
+ newps [counter] = ppath;
+ newps [counter+1] = NULL;
+ }
+ return newps;
+}
+
+
+extern const char **
+tbpaths_add(const char **ps, const char *newpath)
+{
+ size_t i, psize;
+ char *mpath;
+
+ if (NULL == ps)
+ return NULL;
+
+ psize = strlen(newpath) + 1;
+ mpath = (char *) malloc (psize * sizeof (char));
+ if (NULL == mpath) {
+ return ps; /* failed to incorporate a new path */
+ }
+ for (i = 0; i < psize; i++) mpath[i] = newpath[i];
+
+ for (i = 0; i < psize; i++) {
+ if(';' == mpath[i])
+ mpath[i] = '\0';
+ }
+
+ for (i = 0;;) {
+ while (i < psize && mpath[i] == '\0') i++;
+ if (i >= psize) break;
+ ps = tbpaths_add_single (ps, &mpath[i]);
+ while (i < psize && mpath[i] != '\0') i++;
+ }
+
+ free(mpath);
+ return ps;
+}
+
+
+extern const char **
+tbpaths_done(const char **ps)
+{
+ int counter;
+ void *q;
+
+ if (ps != NULL) {
+ for (counter = 0; ps[counter] != NULL; counter++) {
+ /* cast to deal with const poisoning */
+ void *p = (void *) ps[counter];
+ free(p);
+ }
+ /* cast to deal with const poisoning */
+ q = (void *) ps;
+ free(q);
+ }
+ return NULL;
+}
+
+/*---------------- PATH INITIALIZATION ROUTINES ----------------------------*/
+
+static void path_system_reset(void) {Gtbpath_end_index = 0;}
+
+static bool_t
+path_system_init (const char **path)
+{
+ size_t i;
+ size_t sz;
+ const char *x;
+ bool_t ok = TRUE;
+ path_system_reset();
+
+ if (path == NULL) {
+ return FALSE;
+ }
+
+ /* calculate needed size for Gtbpath */
+ i = 0;
+ do {
+ x = path[i++];
+ } while (x != NULL);
+ sz = i; /* sz includes the NULL */
+
+
+ Gtbpath = (const char **) malloc (sz * sizeof(char *));
+
+ if (Gtbpath) {
+
+ ok = TRUE;
+ /* point to the same strings provided */
+ Gtbpath_end_index = 0;
+ for (i = 0; i < sz; i++) {
+ Gtbpath[i] = path[i];
+ Gtbpath_end_index++;
+ }
+
+ } else {
+ ok = FALSE;
+ }
+ return ok;
+
+}
+
+static void
+path_system_done (void)
+{
+ /* before we free Gtbpath, we have to deal with the
+ "const poisoning" and cast it. free() does not accept
+ const pointers */
+ char ** p = (char **) Gtbpath;
+ /* clean up */
+ if (p != NULL)
+ free(p);
+ return;
+}
+
+
+/****************************************************************************\
+ *
+ *
+ * General Initialization Zone
+ *
+ *
+ ****************************************************************************/
+
+
+#ifdef WDL_PROBE
+static size_t wdl_cache_init (size_t cache_mem);
+static void wdl_cache_flush (void);
+
+static void wdl_cache_reset_counters (void);
+static void wdl_cache_done (void);
+
+static bool_t get_WDL_from_cache (tbkey_t key, unsigned side, index_t idx, unsigned int *out);
+static bool_t wdl_preload_cache (tbkey_t key, unsigned side, index_t idx);
+#endif
+
+#ifdef GTB_SHARE
+static void init_bettarr (void);
+#endif
+
+static void eg_was_open_reset(void)
+{
+ int i;
+ for (i = 0; i < MAX_EGKEYS; i++) {
+ eg_was_open[i] = 0;
+ }
+}
+
+static long unsigned int eg_was_open_count(void)
+{
+ long int i, x;
+ for (i = 0, x = 0; i < MAX_EGKEYS; i++) {
+ x += eg_was_open[i];
+ }
+ return (long unsigned) x;
+}
+
+
+enum Sizes {INISIZE = 4096};
+static char ini_str[INISIZE];
+static void sjoin(char *s, const char *tail, size_t max) {strncat(s, tail, max - strlen(s) - 1);}
+
+char *
+tb_init (int verbosity, int decoding_sch, const char **paths)
+{
+ unsigned int zi;
+ int paths_ok;
+ char *ret_str;
+ char localstr[256];
+
+ assert(!TB_INITIALIZED);
+
+ if (verbosity) {
+ ini_str[0] = '\0';
+ ret_str = ini_str;
+ } else {
+ ret_str = NULL;
+ }
+
+ paths_ok = path_system_init (paths);
+
+ if (paths_ok && verbosity) {
+ int g;
+ assert(Gtbpath!=NULL);
+ sjoin(ini_str,"\nGTB PATHS\n",INISIZE);
+ for (g = 0; Gtbpath[g] != NULL; g++) {
+ const char *p = Gtbpath[g];
+ if (0 == g) {
+ sprintf (localstr," main: %s\n", p);
+ } else {
+ sprintf (localstr," #%d: %s\n", g, p);
+ }
+ sjoin(ini_str,localstr,INISIZE);
+ }
+ }
+
+ if (!paths_ok && verbosity) {
+ sjoin (ini_str,"\nGTB PATHS not initialized\n",INISIZE);
+ }
+
+ if (!reach_was_initialized())
+ reach_init();
+
+ attack_maps_init (); /* external initialization */
+
+ init_indexing(0 /* no verbosity */);
+
+ #ifdef GTB_SHARE
+ init_bettarr();
+ #endif
+
+ if (!fd_init (&fd) && verbosity) {
+ sjoin (ini_str," File Open Memory initialization = **FAILED**\n",INISIZE);
+ return ret_str;
+ }
+
+ GTB_scheme = decoding_sch;
+ Uncompressed = GTB_scheme == 0;
+
+ if (GTB_scheme == 0) {
+ Uncompressed = TRUE;
+ }
+
+ set_decoding_scheme(GTB_scheme);
+
+ if (verbosity) {
+ sjoin (ini_str,"\nGTB initialization\n",INISIZE);
+ sprintf (localstr," Compression Scheme = %d\n", GTB_scheme);
+ sjoin (ini_str,localstr,INISIZE);
+ }
+
+ zi = zipinfo_init();
+
+ TB_AVAILABILITY = zi;
+
+ if (verbosity) {
+ if (0 == zi) {
+ sjoin (ini_str," Compression Indexes = **FAILED**\n",INISIZE);
+ } else {
+ int n, bit;
+
+ n = 3; bit = 1;
+ if (zi&(1u<n = 0;
+
+ allowed = mysys_fopen_max() - 5 /*stdin,stdout,sterr,stdlog,book*/;
+ if (allowed < 4)
+ GTB_MAXOPEN = 4;
+ if (allowed > 32)
+ GTB_MAXOPEN = 32;
+
+ p = (tbkey_t *) malloc(sizeof(tbkey_t)*(size_t)GTB_MAXOPEN);
+
+ if (p != NULL) {
+ for (i = 0; i < GTB_MAXOPEN; i++) {
+ p[i] = -1;
+ }
+ pfd->key = p;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+static void
+fd_done (struct filesopen *pfd)
+{
+ int i;
+ tbkey_t closingkey;
+ FILE *finp;
+
+ assert(pfd != NULL);
+
+ for (i = 0; i < pfd->n; i++) {
+ closingkey = pfd->key[i];
+ finp = egkey [closingkey].fd;
+ fclose (finp);
+ egkey[closingkey].fd = NULL;
+ pfd->key[i] = -1;
+ }
+ pfd->n = 0;
+ free(pfd->key);
+}
+
+/****************************************************************************\
+|
+|
+| PROBE ZONE
+|
+|
+\****************************************************************************/
+
+#if !defined(SHARED_forbuilding)
+
+/* shared with building routines */
+mySHARED void list_sq_copy (const SQUARE *a, SQUARE *b);
+mySHARED void list_pc_copy (const SQ_CONTENT *a, SQ_CONTENT *b);
+mySHARED dtm_t inv_dtm (dtm_t x);
+mySHARED bool_t egtb_get_id (SQ_CONTENT *w, SQ_CONTENT *b, tbkey_t *id);
+mySHARED void list_sq_flipNS (SQUARE *s);
+mySHARED dtm_t adjust_up (dtm_t dist);
+mySHARED dtm_t bestx (unsigned stm, dtm_t a, dtm_t b);
+mySHARED void sortlists (SQUARE *ws, SQ_CONTENT *wp);
+
+mySHARED /*@NULL@*/ FILE * fd_openit(tbkey_t key);
+
+mySHARED dtm_t dtm_unpack (unsigned stm, unsigned char packed);
+mySHARED void unpackdist (dtm_t d, unsigned int *res, unsigned int *ply);
+mySHARED dtm_t packdist (unsigned int inf, unsigned int ply);
+
+mySHARED bool_t fread_entry_packed (FILE *dest, unsigned side, dtm_t *px);
+mySHARED bool_t fpark_entry_packed (FILE *finp, unsigned side, index_t max, index_t idx);
+#endif
+
+/* use only with probe */
+static bool_t egtb_get_dtm (tbkey_t k, unsigned stm, const SQUARE *wS, const SQUARE *bS, bool_t probe_hard, dtm_t *dtm);
+static void removepiece (SQUARE *ys, SQ_CONTENT *yp, int j);
+static bool_t egtb_filepeek (tbkey_t key, unsigned side, index_t idx, dtm_t *out_dtm);
+
+
+/*prototype*/
+#ifdef WDL_PROBE
+static bool_t
+tb_probe_wdl
+ (unsigned stm,
+ const SQUARE *inp_wSQ,
+ const SQUARE *inp_bSQ,
+ const SQ_CONTENT *inp_wPC,
+ const SQ_CONTENT *inp_bPC,
+ bool_t probingtype,
+ /*@out@*/ unsigned *res);
+#endif
+
+static bool_t
+tb_probe_ (unsigned stm,
+ SQUARE epsq,
+ const SQUARE *inp_wSQ,
+ const SQUARE *inp_bSQ,
+ const SQ_CONTENT *inp_wPC,
+ const SQ_CONTENT *inp_bPC,
+ bool_t probingtype,
+ /*@out@*/ unsigned *res,
+ /*@out@*/ unsigned *ply);
+
+
+extern bool_t
+tb_probe_soft
+ (unsigned stm,
+ SQUARE epsq,
+ unsigned castles,
+ const SQUARE *inp_wSQ,
+ const SQUARE *inp_bSQ,
+ const SQ_CONTENT *inp_wPC,
+ const SQ_CONTENT *inp_bPC,
+ /*@out@*/ unsigned *res,
+ /*@out@*/ unsigned *ply)
+{
+ if (castles != 0)
+ return FALSE;
+ return tb_probe_ (stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, FALSE, res, ply);
+}
+
+extern bool_t
+tb_probe_hard
+ (unsigned stm,
+ SQUARE epsq,
+ unsigned castles,
+ const SQUARE *inp_wSQ,
+ const SQUARE *inp_bSQ,
+ const SQ_CONTENT *inp_wPC,
+ const SQ_CONTENT *inp_bPC,
+ /*@out@*/ unsigned *res,
+ /*@out@*/ unsigned *ply)
+{
+ if (castles != 0)
+ return FALSE;
+ return tb_probe_ (stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, TRUE, res, ply);
+}
+
+extern bool_t
+tb_probe_WDL_soft
+ (unsigned stm,
+ SQUARE epsq,
+ unsigned castles,
+ const SQUARE *inp_wSQ,
+ const SQUARE *inp_bSQ,
+ const SQ_CONTENT *inp_wPC,
+ const SQ_CONTENT *inp_bPC,
+ /*@out@*/ unsigned *res)
+{
+ unsigned ply_n;
+ unsigned *ply = &ply_n;
+ if (castles != 0)
+ return FALSE;
+ if (epsq != NOSQUARE)
+ return tb_probe_ (stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, FALSE, res, ply);
+
+ /* probe bitbase like, assuming no en passant */
+ #ifdef WDL_PROBE
+ return tb_probe_wdl (stm, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, FALSE, res);
+ #else
+ return tb_probe_ (stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, FALSE, res, ply);
+ #endif
+}
+
+extern bool_t
+tb_probe_WDL_hard
+ (unsigned stm,
+ SQUARE epsq,
+ unsigned castles,
+ const SQUARE *inp_wSQ,
+ const SQUARE *inp_bSQ,
+ const SQ_CONTENT *inp_wPC,
+ const SQ_CONTENT *inp_bPC,
+ /*@out@*/ unsigned *res)
+{
+ unsigned ply_n;
+ unsigned *ply = &ply_n;
+ if (castles != 0)
+ return FALSE;
+ if (epsq != NOSQUARE)
+ return tb_probe_ (stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, TRUE, res, ply);
+
+ /* probe bitbase like, assuming no en passant */
+ #ifdef WDL_PROBE
+ return tb_probe_wdl (stm, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, TRUE, res);
+ #else
+ return tb_probe_ (stm, epsq, inp_wSQ, inp_bSQ, inp_wPC, inp_bPC, TRUE, res, ply);
+ #endif
+}
+
+
+static bool_t
+tb_probe_ (unsigned stm,
+ SQUARE epsq,
+ const SQUARE *inp_wSQ,
+ const SQUARE *inp_bSQ,
+ const SQ_CONTENT *inp_wPC,
+ const SQ_CONTENT *inp_bPC,
+ bool_t probingtype,
+ /*@out@*/ unsigned *res,
+ /*@out@*/ unsigned *ply)
+{
+ int i = 0, j = 0;
+ tbkey_t id = -1;
+ dtm_t dtm;
+
+ SQUARE storage_ws [MAX_LISTSIZE], storage_bs [MAX_LISTSIZE];
+ SQ_CONTENT storage_wp [MAX_LISTSIZE], storage_bp [MAX_LISTSIZE];
+
+ SQUARE *ws = storage_ws;
+ SQUARE *bs = storage_bs;
+ SQ_CONTENT *wp = storage_wp;
+ SQ_CONTENT *bp = storage_bp;
+
+ SQUARE *xs;
+ SQUARE *ys;
+ SQ_CONTENT *xp;
+ SQ_CONTENT *yp;
+
+ SQUARE tmp_ws [MAX_LISTSIZE], tmp_bs [MAX_LISTSIZE];
+ SQ_CONTENT tmp_wp [MAX_LISTSIZE], tmp_bp [MAX_LISTSIZE];
+
+ SQUARE *temps;
+ bool_t straight = FALSE;
+
+ SQUARE capturer_a, capturer_b, xed = NOSQUARE;
+
+ unsigned int plies;
+ unsigned int inf;
+
+ bool_t okdtm = TRUE;
+ bool_t okcall = TRUE;
+
+ /************************************/
+
+ assert (stm == WH || stm == BL);
+ /*assert (inp_wPC[0] == KING && inp_bPC[0] == KING );*/
+ assert ((epsq >> 3) == 2 || (epsq >> 3) == 5 || epsq == NOSQUARE);
+
+ /* VALID ONLY FOR KK!! */
+ if (inp_wPC[1] == NOPIECE && inp_bPC[1] == NOPIECE) {
+ index_t dummy_i;
+ bool_t b = kxk_pctoindex (inp_wSQ, inp_bSQ, &dummy_i);
+ *res = b? iDRAW: iFORBID;
+ *ply = 0;
+ return TRUE;
+ }
+
+ /* copy input */
+ list_pc_copy (inp_wPC, wp);
+ list_pc_copy (inp_bPC, bp);
+ list_sq_copy (inp_wSQ, ws);
+ list_sq_copy (inp_bSQ, bs);
+
+ sortlists (ws, wp);
+ sortlists (bs, bp);
+
+ FOLLOW_label("EGTB_PROBE")
+
+ if (egtb_get_id (wp, bp, &id)) {
+ FOLLOW_LU("got ID",id)
+ straight = TRUE;
+ } else if (egtb_get_id (bp, wp, &id)) {
+ FOLLOW_LU("rev ID",id)
+ straight = FALSE;
+ list_sq_flipNS (ws);
+ list_sq_flipNS (bs);
+ temps = ws;
+ ws = bs;
+ bs = temps;
+ stm = Opp(stm);
+ if (epsq != NOSQUARE) epsq ^= 070; /* added */
+ {SQ_CONTENT *tempp = wp; wp = bp; bp = tempp;} /* added */
+ } else {
+ #if defined(DEBUG)
+ printf("did not get id...\n");
+ output_state (stm, ws, bs, wp, bp);
+ #endif
+ unpackdist (iFORBID, res, ply);
+ return FALSE;
+ }
+
+ /* store position... */
+ list_pc_copy (wp, tmp_wp);
+ list_pc_copy (bp, tmp_bp);
+ list_sq_copy (ws, tmp_ws);
+ list_sq_copy (bs, tmp_bs);
+
+ /* x will be stm and y will be stw */
+ if (stm == WH) {
+ xs = ws;
+ xp = wp;
+ ys = bs;
+ yp = bp;
+ } else {
+ xs = bs;
+ xp = bp;
+ ys = ws;
+ yp = wp;
+ }
+
+ okdtm = egtb_get_dtm (id, stm, ws, bs, probingtype, &dtm);
+
+ FOLLOW_LU("dtmok?",okdtm)
+ FOLLOW_DTM("dtm", dtm)
+
+ if (okdtm) {
+
+ capturer_a = NOSQUARE;
+ capturer_b = NOSQUARE;
+
+ if (epsq != NOSQUARE) {
+ /* captured pawn, trick: from epsquare to captured */
+ xed = epsq ^ (1<<3);
+
+ /* find index captured (j) */
+ for (j = 0; ys[j] != NOSQUARE; j++) {
+ if (ys[j] == xed) break;
+ }
+
+ /* try first possible ep capture */
+ if (0 == (0x88 & (map88(xed) + 1)))
+ capturer_a = xed + 1;
+ /* try second possible ep capture */
+ if (0 == (0x88 & (map88(xed) - 1)))
+ capturer_b = xed - 1;
+
+ if (ys[j] == xed) {
+
+ /* find capturers (i) */
+ for (i = 0; xs[i] != NOSQUARE && okcall; i++) {
+
+ if (xp[i]==PAWN && (xs[i]==capturer_a || xs[i]==capturer_b)) {
+ dtm_t epscore = iFORBID;
+
+ /* execute capture */
+ xs[i] = epsq;
+ removepiece (ys, yp, j);
+
+ okcall = tb_probe_ (Opp(stm), NOSQUARE, ws, bs, wp, bp, probingtype, &inf, &plies);
+
+ if (okcall) {
+ epscore = packdist (inf, plies);
+ epscore = adjust_up (epscore);
+
+ /* chooses to ep or not */
+ dtm = bestx (stm, epscore, dtm);
+ }
+
+ /* restore position */
+ list_pc_copy (tmp_wp, wp);
+ list_pc_copy (tmp_bp, bp);
+
+ list_sq_copy (tmp_ws, ws);
+ list_sq_copy (tmp_bs, bs);
+ }
+ }
+ }
+ } /* ep */
+
+ if (straight) {
+ unpackdist (dtm, res, ply);
+ } else {
+ unpackdist (inv_dtm (dtm), res, ply);
+ }
+ }
+
+ if (!okdtm || !okcall) {
+ unpackdist (iFORBID, res, ply);
+ }
+
+ return okdtm && okcall;
+}
+
+#ifdef _MSC_VER
+/* to silence warning for sprintf usage */
+#pragma warning(disable:4996)
+#endif
+
+static bool_t
+egtb_filepeek (tbkey_t key, unsigned side, index_t idx, dtm_t *out_dtm)
+{
+ FILE *finp;
+
+#define USE_FD
+
+ #if !defined(USE_FD)
+ char buf[1024];
+ char *filename = buf;
+ #endif
+
+ bool_t ok;
+ dtm_t x=0;
+ index_t maxindex = egkey[key].maxindex;
+
+
+
+ assert (Uncompressed);
+ assert (side == WH || side == BL);
+ assert (out_dtm != NULL);
+ assert (idx >= 0);
+ assert (key < MAX_EGKEYS);
+
+
+ #if defined(USE_FD)
+ if (NULL == (finp = egkey[key].fd) ) {
+ if (NULL == (finp = fd_openit (key))) {
+ return FALSE;
+ }
+ }
+ #else
+ sprintf (buf, "%s.gtb", egkey[key].str);
+ if (NULL == (finp = fopen (filename, "rb"))) {
+ return FALSE;
+ }
+ #endif
+
+ ok = fpark_entry_packed (finp, side, maxindex, idx);
+ ok = ok && fread_entry_packed (finp, side, &x);
+
+ if (ok) {
+ *out_dtm = x;
+ } else
+ *out_dtm = iFORBID;
+
+ #if !defined(USE_FD)
+ fclose (finp);
+ #endif
+
+ return ok;
+}
+
+/* will get defined later */
+static bool_t dtm_cache_is_on (void);
+
+static bool_t
+egtb_get_dtm (tbkey_t k, unsigned stm, const SQUARE *wS, const SQUARE *bS, bool_t probe_hard_flag, dtm_t *dtm)
+{
+ bool_t idxavail;
+ index_t idx;
+ dtm_t *tab[2];
+ bool_t (*pc2idx) (const SQUARE *, const SQUARE *, index_t *);
+
+ FOLLOW_label("egtb_get_dtm --> starts")
+
+ if (egkey[k].status == STATUS_MALLOC || egkey[k].status == STATUS_STATICRAM) {
+
+ tab[WH] = egkey[k].egt_w;
+ tab[BL] = egkey[k].egt_b;
+ pc2idx = egkey[k].pctoi;
+
+ idxavail = pc2idx (wS, bS, &idx);
+
+ FOLLOW_LU("indexavail (RAM)",idxavail)
+
+ if (idxavail) {
+ *dtm = tab[stm][idx];
+ } else {
+ *dtm = iFORBID;
+ }
+
+ return TRUE;
+
+ } else if (egkey[k].status == STATUS_ABSENT) {
+
+ pc2idx = egkey[k].pctoi;
+ idxavail = pc2idx (wS, bS, &idx);
+
+ FOLLOW_LU("indexavail (HD)",idxavail)
+
+ if (idxavail) {
+ bool_t success;
+
+ /*
+ | LOCK
+ *-------------------------------*/
+ mythread_mutex_lock (&Egtb_lock);
+
+ if (dtm_cache_is_on()) {
+
+ success = get_dtm (k, stm, idx, dtm, probe_hard_flag);
+
+ FOLLOW_LU("get_dtm (succ)",success)
+ FOLLOW_LU("get_dtm (dtm )",*dtm)
+
+ #if defined(DEBUG)
+ if (Uncompressed) {
+ dtm_t dtm_temp;
+ bool_t ok;
+ bool_t success2;
+
+ assert (decoding_scheme() == 0 && GTB_scheme == 0);
+
+ success2 = egtb_filepeek (k, stm, idx, &dtm_temp);
+ ok = (success == success2) && (!success || *dtm == dtm_temp);
+ if (!ok) {
+ printf ("\nERROR\nsuccess1=%d sucess2=%d\n"
+ "k=%d stm=%u idx=%d dtm_peek=%d dtm_cache=%d\n",
+ success, success2, k, stm, idx, dtm_temp, *dtm);
+ fatal_error();
+ }
+ }
+ #endif
+
+ } else {
+ assert(Uncompressed);
+ if (probe_hard_flag && Uncompressed)
+ success = egtb_filepeek (k, stm, idx, dtm);
+ else
+ success = FALSE;
+ }
+
+ mythread_mutex_unlock (&Egtb_lock);
+ /*------------------------------*\
+ | UNLOCK
+ */
+
+
+ if (success) {
+ return TRUE;
+ } else {
+ if (probe_hard_flag) /* after probing hard and failing, no chance to succeed later */
+ egkey[k].status = STATUS_REJECT;
+ *dtm = iUNKNOWN;
+ return FALSE;
+ }
+
+ } else {
+ *dtm = iFORBID;
+ return TRUE;
+ }
+
+ } else if (egkey[k].status == STATUS_REJECT) {
+
+ FOLLOW_label("STATUS_REJECT")
+
+ *dtm = iFORBID;
+ return FALSE;
+ } else {
+
+ FOLLOW_label("STATUS_WRONG!")
+
+ assert(0);
+ *dtm = iFORBID;
+ return FALSE;
+ }
+
+}
+
+static void
+removepiece (SQUARE *ys, SQ_CONTENT *yp, int j)
+{
+ int k;
+ for (k = j; ys[k] != NOSQUARE; k++) {
+ ys[k] = ys[k+1];
+ yp[k] = yp[k+1];
+ }
+}
+
+/*
+|
+| mySHARED by probe and build
+|
+\*----------------------------------------------------*/
+
+mySHARED /*@NULL@*/ FILE *
+fd_openit (tbkey_t key)
+{
+ int i;
+ tbkey_t closingkey;
+ FILE * finp = NULL;
+ char buf[4096];
+ char * filename = buf;
+ int start;
+ int end;
+ int pth;
+ const char * extension;
+
+ assert (0 <= key && key < MAX_EGKEYS);
+ assert (0 <= fd.n && fd.n <= GTB_MAXOPEN);
+
+ /* test if I reach limit of files open */
+ if (fd.n == GTB_MAXOPEN) {
+
+ /* fclose the last accessed, first in the list */
+ closingkey = fd.key[0];
+ finp = egkey [closingkey].fd;
+ assert (finp != NULL);
+ fclose (finp);
+ egkey[closingkey].fd = NULL;
+ finp = NULL;
+
+ for (i = 1; i < fd.n; i++) {
+ fd.key[i-1] = fd.key[i];
+ }
+ fd.key[--fd.n] = -1;
+ }
+
+ assert (fd.n < GTB_MAXOPEN);
+
+ /* set proper extensions to the File */
+ if (Uncompressed) {
+ assert (decoding_scheme() == 0 && GTB_scheme == 0);
+ extension = ".gtb";
+ } else {
+ extension = Extension[decoding_scheme()];
+ }
+
+ /* Scan folders to find the File*/
+ finp = NULL;
+
+ start = egkey[key].pathn;
+ end = Gtbpath_end_index;
+
+/*@@
+printf ("start: %d\n",start);
+printf ("===================Gtbpath[0]=%s\n",Gtbpath[0]);
+*/
+ for (pth = start; NULL == finp && pth < end && Gtbpath[pth] != NULL; pth++) {
+ const char *path = Gtbpath[pth];
+ size_t pl = strlen(path);
+/*@@
+printf ("path: %s\n",path);
+*/
+ if (pl == 0) {
+ sprintf (buf, "%s%s%s", path, egkey[key].str, extension);
+ } else {
+ if (isfoldersep( path[pl-1] )) {
+ sprintf (buf, "%s%s%s", path, egkey[key].str, extension);
+ } else {
+ sprintf (buf, "%s%s%s%s", path, FOLDERSEP, egkey[key].str, extension);
+ }
+ }
+/*printf ("try to open %s --> ",filename);*/
+ /* Finally found the file? */
+ finp = fopen (filename, "rb");
+/*printf ("%d\n",finp != NULL);*/
+ }
+
+ /* File was found and opened */
+ if (NULL != finp) {
+ fd.key [fd.n++] = key;
+ egkey[key].fd = finp;
+ egkey[key].pathn = pth; /* remember succesful path */
+ eg_was_open[key] = 1;
+ return finp;
+ }
+
+ start = 0;
+ end = egkey[key].pathn;
+ for (pth = start; NULL == finp && pth < end && Gtbpath[pth] != NULL; pth++) {
+ const char *path = Gtbpath[pth];
+ size_t pl = strlen(path);
+
+ if (pl == 0) {
+ sprintf (buf, "%s%s%s", path, egkey[key].str, extension);
+ } else {
+ if (isfoldersep( path[pl-1] )) {
+ sprintf (buf, "%s%s%s", path, egkey[key].str, extension);
+ } else {
+ sprintf (buf, "%s%s%s%s", path, FOLDERSEP, egkey[key].str, extension);
+ }
+ }
+/*printf ("try to open %s --> ",filename);*/
+ /* Finally found the file? */
+ finp = fopen (filename, "rb");
+/*printf ("%d\n",finp != NULL);*/
+ }
+
+
+ /* File was found and opened */
+ if (NULL != finp) {
+ fd.key [fd.n++] = key;
+ egkey[key].fd = finp;
+ egkey[key].pathn = pth; /* remember succesful path */
+ eg_was_open[key] = 1;
+ }
+
+ return finp;
+}
+
+#ifdef _MSC_VER
+/* to silence warning for sprintf usage */
+#pragma warning(default:4996)
+#endif
+
+mySHARED void
+sortlists (SQUARE *ws, SQ_CONTENT *wp)
+{
+ int i, j;
+ SQUARE ts;
+ SQ_CONTENT tp;
+ /* input is sorted */
+ for (i = 0; wp[i] != NOPIECE; i++) {
+ for (j = (i+1); wp[j] != NOPIECE; j++) {
+ if (wp[j] > wp[i]) {
+ tp = wp[i]; wp[i] = wp[j]; wp[j] = tp;
+ ts = ws[i]; ws[i] = ws[j]; ws[j] = ts;
+ }
+ }
+ }
+}
+
+mySHARED void
+list_sq_copy (const SQUARE *a, SQUARE *b)
+{
+ while (NOSQUARE != (*b++ = *a++))
+ ;
+}
+
+mySHARED void
+list_pc_copy (const SQ_CONTENT *a, SQ_CONTENT *b)
+{
+ while (NOPIECE != (*b++ = *a++))
+ ;
+}
+
+mySHARED dtm_t
+inv_dtm (dtm_t x)
+{
+ unsigned mat;
+ assert ( (x & iUNKNBIT) == 0);
+
+ if (x == iDRAW || x == iFORBID)
+ return x;
+
+ mat = (unsigned)x & 3u;
+ if (mat == iWMATE)
+ mat = iBMATE;
+ else
+ mat = iWMATE;
+
+ x = (dtm_t) (((unsigned)x & ~3u) | mat);
+
+ return x;
+}
+
+static const char pctoch[] = {'-','p','n','b','r','q','k'};
+
+mySHARED bool_t
+egtb_get_id (SQ_CONTENT *w, SQ_CONTENT *b, tbkey_t *id)
+{
+
+ char pcstr[2*MAX_LISTSIZE];
+ SQ_CONTENT *s;
+ char *t;
+ bool_t found;
+ tbkey_t i;
+ static tbkey_t cache_i = 0;
+
+ assert (PAWN == 1 && KNIGHT == 2 && BISHOP == 3 && ROOK == 4 && QUEEN == 5 && KING == 6);
+
+ t = pcstr;
+
+ s = w;
+ while (NOPIECE != *s)
+ *t++ = pctoch[*s++];
+ s = b;
+ while (NOPIECE != *s)
+ *t++ = pctoch[*s++];
+
+ *t = '\0';
+
+ found = (0 == strcmp(pcstr, egkey[cache_i].str));
+ if (found) {
+ *id = cache_i;
+ return found;
+ }
+
+ for (i = 0, found = FALSE; !found && egkey[i].str != NULL; i++) {
+ found = (0 == strcmp(pcstr, egkey[i].str));
+ }
+ if (found) {
+ cache_i = *id = i - 1;
+ }
+
+ return found;
+}
+
+mySHARED void
+list_sq_flipNS (SQUARE *s)
+{
+ while (*s != NOSQUARE) {
+ *s ^= 070;
+ s++;
+ }
+}
+
+mySHARED void
+unpackdist (dtm_t d, unsigned int *res, unsigned int *ply)
+{
+ *ply = (unsigned int)d >> PLYSHIFT;
+ *res = d & INFOMASK;
+}
+
+mySHARED dtm_t
+packdist (unsigned int inf, unsigned int ply)
+{
+ assert (inf <= INFOMASK);
+ return (dtm_t) (inf | ply << PLYSHIFT);
+}
+
+mySHARED dtm_t
+adjust_up (dtm_t dist)
+{
+ #if 0
+ static const dtm_t adding[] = {
+ 0, 1<> 2;
+
+ if (WH == stm) {
+ switch (info) {
+ case iWMATE:
+ moves = store + 1;
+ plies = moves * 2 - 1;
+ prefx = info;
+ break;
+
+ case iBMATE:
+ moves = store;
+ plies = moves * 2;
+ prefx = info;
+ break;
+
+ case iDRAW:
+ moves = store + 1 + 63;
+ plies = moves * 2 - 1;
+ prefx = iWMATE;
+ break;
+
+ case iFORBID:
+
+ moves = store + 63;
+ plies = moves * 2;
+ prefx = iBMATE;
+ break;
+ default:
+ plies = 0;
+ prefx = 0;
+ assert(0);
+ break;
+
+ }
+ ret = (dtm_t) (prefx | (plies << 3));
+ } else {
+ switch (info) {
+ case iBMATE:
+ moves = store + 1;
+ plies = moves * 2 - 1;
+ prefx = info;
+ break;
+
+ case iWMATE:
+ moves = store;
+ plies = moves * 2;
+ prefx = info;
+ break;
+
+ case iDRAW:
+
+ if (store == 63) {
+ /* exception: no position in the 5-man
+ TBs needs to store 63 for iBMATE
+ it is then used to indicate iWMATE
+ when just overflows */
+ store++;
+
+ moves = store + 63;
+ plies = moves * 2;
+ prefx = iWMATE;
+
+ break;
+ }
+
+ moves = store + 1 + 63;
+ plies = moves * 2 - 1;
+ prefx = iBMATE;
+ break;
+
+ case iFORBID:
+
+ moves = store + 63;
+ plies = moves * 2;
+ prefx = iWMATE;
+ break;
+ default:
+ plies = 0;
+ prefx = 0;
+ assert(0);
+ break;
+
+ }
+ ret = (dtm_t) (prefx | (plies << 3));
+ }
+ return ret;
+}
+
+
+/*
+static bool_t fwrite_entry_packed (FILE *dest, unsigned side, dtm_t x);
+*/
+
+
+mySHARED bool_t
+fread_entry_packed (FILE *finp, unsigned side, dtm_t *px)
+{
+ unsigned char p[SLOTSIZE];
+ bool_t ok = (SLOTSIZE == fread (p, sizeof(unsigned char), SLOTSIZE, finp));
+ if (ok) {
+ *px = dtm_unpack (side, p[0]);
+ }
+ return ok;
+}
+
+
+mySHARED bool_t
+fpark_entry_packed (FILE *finp, unsigned side, index_t max, index_t idx)
+{
+ bool_t ok;
+ index_t i;
+ long int fseek_i;
+ index_t sz = (index_t) sizeof(unsigned char);
+
+ assert (side == WH || side == BL);
+ assert (finp != NULL);
+ assert (idx >= 0);
+ i = ((index_t)side * max + idx) * sz;
+ fseek_i = (long int) i;
+ assert (fseek_i >= 0);
+ ok = (0 == fseek (finp, fseek_i, SEEK_SET));
+ return ok;
+}
+
+/*----------------------------------------------------*\
+|
+| shared by probe and build
+|
+\*/
+
+
+/*---------------------------------------------------------------------*\
+| WDL CACHE Implementation ZONE
+\*---------------------------------------------------------------------*/
+
+#define WDL_entries_per_unit 4
+#define WDL_entry_mask 3
+static size_t WDL_units_per_block = 0;
+
+static bool_t WDL_CACHE_INITIALIZED = FALSE;
+
+typedef unsigned char unit_t; /* block unit */
+
+typedef struct wdl_block wdl_block_t;
+
+struct wdl_block {
+ tbkey_t key;
+ unsigned side;
+ index_t offset;
+ unit_t *p_arr;
+ wdl_block_t *prev;
+ wdl_block_t *next;
+};
+
+struct WDL_CACHE {
+ /* defined at init */
+ bool_t cached;
+ size_t max_blocks;
+ size_t entries_per_block;
+ unit_t * buffer;
+
+ /* flushables */
+ wdl_block_t * top;
+ wdl_block_t * bot;
+ size_t n;
+ wdl_block_t * blocks; /* was entry */
+
+ /* counters */
+ uint64_t hard;
+ uint64_t soft;
+ uint64_t hardmisses;
+ uint64_t hits;
+ uint64_t softmisses;
+ uint64_t comparisons;
+};
+
+struct WDL_CACHE wdl_cache = {FALSE,0,0,NULL,
+ NULL,NULL,0,NULL,
+ 0,0,0,0,0,0};
+
+
+/*---------------------------------------------------------------------*\
+| DTM CACHE Implementation ZONE
+\*---------------------------------------------------------------------*/
+
+struct dtm_block;
+
+typedef struct dtm_block dtm_block_t;
+
+struct dtm_block {
+ tbkey_t key;
+ unsigned side;
+ index_t offset;
+ dtm_t *p_arr;
+ dtm_block_t *prev;
+ dtm_block_t *next;
+};
+
+struct cache_table {
+ /* defined at init */
+ bool_t cached;
+ size_t max_blocks;
+ size_t entries_per_block;
+ dtm_t * buffer;
+
+ /* flushables */
+ dtm_block_t * top;
+ dtm_block_t * bot;
+ size_t n;
+ dtm_block_t * entry;
+
+ /* counters */
+ uint64_t hard;
+ uint64_t soft;
+ uint64_t hardmisses;
+ uint64_t hits;
+ uint64_t softmisses;
+ unsigned long comparisons;
+};
+
+struct cache_table dtm_cache = {FALSE,0,0,NULL,
+ NULL,NULL,0,NULL,
+ 0,0,0,0,0,0};
+
+struct general_counters {
+ /* counters */
+ uint64_t hits;
+ uint64_t miss;
+};
+
+static struct general_counters Drive = {0,0};
+
+
+static void split_index (size_t entries_per_block, index_t i, index_t *o, index_t *r);
+static dtm_block_t *point_block_to_replace (void);
+static bool_t preload_cache (tbkey_t key, unsigned side, index_t idx);
+static void movetotop (dtm_block_t *t);
+
+/*--cache prototypes--------------------------------------------------------*/
+
+/*- WDL --------------------------------------------------------------------*/
+#ifdef WDL_PROBE
+static unsigned int wdl_extract (unit_t *uarr, index_t x);
+static wdl_block_t * wdl_point_block_to_replace (void);
+static void wdl_movetotop (wdl_block_t *t);
+
+#if 0
+static bool_t wdl_cache_init (size_t cache_mem);
+static void wdl_cache_flush (void);
+static bool_t get_WDL (tbkey_t key, unsigned side, index_t idx, unsigned int *info_out, bool_t probe_hard_flag);
+#endif
+
+static bool_t wdl_cache_is_on (void);
+static void wdl_cache_reset_counters (void);
+static void wdl_cache_done (void);
+
+static wdl_block_t * wdl_point_block_to_replace (void);
+static bool_t get_WDL_from_cache (tbkey_t key, unsigned side, index_t idx, unsigned int *out);
+static void wdl_movetotop (wdl_block_t *t);
+static bool_t wdl_preload_cache (tbkey_t key, unsigned side, index_t idx);
+#endif
+/*--------------------------------------------------------------------------*/
+/*- DTM --------------------------------------------------------------------*/
+static bool_t dtm_cache_is_on (void);
+static void dtm_cache_reset_counters (void);
+static void dtm_cache_done (void);
+
+static size_t dtm_cache_init (size_t cache_mem);
+static void dtm_cache_flush (void);
+/*--------------------------------------------------------------------------*/
+
+static bool_t
+dtm_cache_is_on (void)
+{
+ return dtm_cache.cached;
+}
+
+static void
+dtm_cache_reset_counters (void)
+{
+ dtm_cache.hard = 0;
+ dtm_cache.soft = 0;
+ dtm_cache.hardmisses = 0;
+ dtm_cache.hits = 0;
+ dtm_cache.softmisses = 0;
+ dtm_cache.comparisons = 0;
+ return;
+}
+
+
+static size_t
+dtm_cache_init (size_t cache_mem)
+{
+ unsigned int i;
+ dtm_block_t *p;
+ size_t entries_per_block;
+ size_t max_blocks;
+ size_t block_mem;
+
+ if (DTM_CACHE_INITIALIZED)
+ dtm_cache_done();
+
+ entries_per_block = 16 * 1024; /* fixed, needed for the compression schemes */
+
+ block_mem = entries_per_block * sizeof(dtm_t);
+
+ max_blocks = cache_mem / block_mem;
+ if (!Uncompressed && 1 > max_blocks)
+ max_blocks = 1;
+ cache_mem = max_blocks * block_mem;
+
+
+ dtm_cache_reset_counters ();
+
+ dtm_cache.entries_per_block = entries_per_block;
+ dtm_cache.max_blocks = max_blocks;
+ dtm_cache.cached = TRUE;
+ dtm_cache.top = NULL;
+ dtm_cache.bot = NULL;
+ dtm_cache.n = 0;
+
+ if (0 == cache_mem || NULL == (dtm_cache.buffer = (dtm_t *) malloc (cache_mem))) {
+ dtm_cache.cached = FALSE;
+ dtm_cache.buffer = NULL;
+ dtm_cache.entry = NULL;
+ return 0;
+ }
+
+ if (0 == max_blocks|| NULL == (dtm_cache.entry = (dtm_block_t *) malloc (max_blocks * sizeof(dtm_block_t)))) {
+ dtm_cache.cached = FALSE;
+ dtm_cache.entry = NULL;
+ free (dtm_cache.buffer);
+ dtm_cache.buffer = NULL;
+ return 0;
+ }
+
+ for (i = 0; i < max_blocks; i++) {
+ p = &dtm_cache.entry[i];
+ p->key = -1;
+ p->side = gtbNOSIDE;
+ p->offset = gtbNOINDEX;
+ p->p_arr = dtm_cache.buffer + i * entries_per_block;
+ p->prev = NULL;
+ p->next = NULL;
+ }
+
+ DTM_CACHE_INITIALIZED = TRUE;
+
+ return cache_mem;
+}
+
+
+static void
+dtm_cache_done (void)
+{
+ assert(DTM_CACHE_INITIALIZED);
+
+ dtm_cache.cached = FALSE;
+ dtm_cache.hard = 0;
+ dtm_cache.soft = 0;
+ dtm_cache.hardmisses = 0;
+ dtm_cache.hits = 0;
+ dtm_cache.softmisses = 0;
+ dtm_cache.comparisons = 0;
+ dtm_cache.max_blocks = 0;
+ dtm_cache.entries_per_block = 0;
+
+ dtm_cache.top = NULL;
+ dtm_cache.bot = NULL;
+ dtm_cache.n = 0;
+
+ if (dtm_cache.buffer != NULL)
+ free (dtm_cache.buffer);
+ dtm_cache.buffer = NULL;
+
+ if (dtm_cache.entry != NULL)
+ free (dtm_cache.entry);
+ dtm_cache.entry = NULL;
+
+ DTM_CACHE_INITIALIZED = FALSE;
+
+ return;
+}
+
+static void
+dtm_cache_flush (void)
+{
+ unsigned int i;
+ dtm_block_t *p;
+ size_t entries_per_block = dtm_cache.entries_per_block;
+ size_t max_blocks = dtm_cache.max_blocks;
+
+ dtm_cache.top = NULL;
+ dtm_cache.bot = NULL;
+ dtm_cache.n = 0;
+
+ for (i = 0; i < max_blocks; i++) {
+ p = &dtm_cache.entry[i];
+ p->key = -1;
+ p->side = gtbNOSIDE;
+ p->offset = gtbNOINDEX;
+ p->p_arr = dtm_cache.buffer + i * entries_per_block;
+ p->prev = NULL;
+ p->next = NULL;
+ }
+ dtm_cache_reset_counters ();
+ return;
+}
+
+
+/*---- end tbcache zone ----------------------------------------------------------------------*/
+
+extern bool_t
+tbcache_is_on (void)
+{
+ return dtm_cache_is_on() || wdl_cache_is_on();
+}
+
+
+/* STATISTICS OUTPUT */
+
+extern void
+tbstats_get (struct TB_STATS *x)
+{
+ long unsigned mask = 0xfffffffflu;
+ uint64_t memory_hits, total_hits;
+
+
+ /*
+ | WDL CACHE
+ \*---------------------------------------------------*/
+
+ x->wdl_easy_hits[0] = (long unsigned)(wdl_cache.hits & mask);
+ x->wdl_easy_hits[1] = (long unsigned)(wdl_cache.hits >> 32);
+
+ x->wdl_hard_prob[0] = (long unsigned)(wdl_cache.hard & mask);
+ x->wdl_hard_prob[1] = (long unsigned)(wdl_cache.hard >> 32);
+
+ x->wdl_soft_prob[0] = (long unsigned)(wdl_cache.soft & mask);
+ x->wdl_soft_prob[1] = (long unsigned)(wdl_cache.soft >> 32);
+
+ x->wdl_cachesize = WDL_cache_size;
+
+ /* occupancy */
+ x->wdl_occupancy = wdl_cache.max_blocks==0? 0:(double)100.0*(double)wdl_cache.n/(double)wdl_cache.max_blocks;
+
+ /*
+ | DTM CACHE
+ \*---------------------------------------------------*/
+
+ x->dtm_easy_hits[0] = (long unsigned)(dtm_cache.hits & mask);
+ x->dtm_easy_hits[1] = (long unsigned)(dtm_cache.hits >> 32);
+
+ x->dtm_hard_prob[0] = (long unsigned)(dtm_cache.hard & mask);
+ x->dtm_hard_prob[1] = (long unsigned)(dtm_cache.hard >> 32);
+
+ x->dtm_soft_prob[0] = (long unsigned)(dtm_cache.soft & mask);
+ x->dtm_soft_prob[1] = (long unsigned)(dtm_cache.soft >> 32);
+
+ x->dtm_cachesize = DTM_cache_size;
+
+ /* occupancy */
+ x->dtm_occupancy = dtm_cache.max_blocks==0? 0:(double)100.0*(double)dtm_cache.n/(double)dtm_cache.max_blocks;
+
+ /*
+ | GENERAL
+ \*---------------------------------------------------*/
+
+ /* memory */
+ memory_hits = wdl_cache.hits + dtm_cache.hits;
+ x->memory_hits[0] = (long unsigned)(memory_hits & mask);
+ x->memory_hits[1] = (long unsigned)(memory_hits >> 32);
+
+ /* hard drive */
+ x->drive_hits[0] = (long unsigned)(Drive.hits & mask);
+ x->drive_hits[1] = (long unsigned)(Drive.hits >> 32);
+
+ x->drive_miss[0] = (long unsigned)(Drive.miss & mask);
+ x->drive_miss[1] = (long unsigned)(Drive.miss >> 32);
+
+ x->bytes_read[0] = (long unsigned)(Bytes_read & mask);
+ x->bytes_read[1] = (long unsigned)(Bytes_read >> 32);
+
+ x->files_opened = eg_was_open_count();
+
+ /* total */
+ total_hits = memory_hits + Drive.hits;
+ x->total_hits[0] = (long unsigned)(total_hits & mask);
+ x->total_hits[1] = (long unsigned)(total_hits >> 32);
+
+ /* efficiency */
+ { uint64_t denominator = memory_hits + Drive.hits + Drive.miss;
+ x->memory_efficiency = 0==denominator? 0: 100.0 * (double)(memory_hits) / (double)(denominator);
+ }
+}
+
+
+extern bool_t
+tbcache_init (size_t cache_mem, int wdl_fraction)
+{
+ assert (wdl_fraction <= WDL_FRACTION_MAX && wdl_fraction >= 0);
+
+ /* defensive against input */
+ if (wdl_fraction > WDL_FRACTION_MAX) wdl_fraction = WDL_FRACTION_MAX;
+ if (wdl_fraction < 0) wdl_fraction = 0;
+ WDL_FRACTION = wdl_fraction;
+
+ DTM_cache_size = (cache_mem/(size_t)WDL_FRACTION_MAX)*(size_t)(WDL_FRACTION_MAX-WDL_FRACTION);
+ WDL_cache_size = (cache_mem/(size_t)WDL_FRACTION_MAX)*(size_t) WDL_FRACTION ;
+
+ #ifdef WDL_PROBE
+ /* returns the actual memory allocated */
+ DTM_cache_size = dtm_cache_init (DTM_cache_size);
+ WDL_cache_size = wdl_cache_init (WDL_cache_size);
+ #else
+ /* returns the actual memory allocated */
+ DTM_cache_size = dtm_cache_init (DTM_cache_size);
+ #endif
+ tbstats_reset ();
+ return TRUE;
+}
+
+extern bool_t
+tbcache_restart (size_t cache_mem, int wdl_fraction)
+{
+ return tbcache_init (cache_mem, wdl_fraction);
+}
+
+extern void
+tbcache_done (void)
+{
+ dtm_cache_done();
+ #ifdef WDL_PROBE
+ wdl_cache_done();
+ #endif
+ tbstats_reset ();
+ return;
+}
+
+extern void
+tbcache_flush (void)
+{
+ dtm_cache_flush();
+ #ifdef WDL_PROBE
+ wdl_cache_flush();
+ #endif
+ tbstats_reset ();
+ return;
+}
+
+extern void
+tbstats_reset (void)
+{
+ dtm_cache_reset_counters ();
+ #ifdef WDL_PROBE
+ wdl_cache_reset_counters ();
+ #endif
+ eg_was_open_reset();
+ Drive.hits = 0;
+ Drive.miss = 0;
+ return;
+}
+
+static dtm_block_t *
+dtm_cache_pointblock (tbkey_t key, unsigned side, index_t idx)
+{
+ index_t offset;
+ index_t remainder;
+ dtm_block_t * p;
+ dtm_block_t * ret;
+
+ if (!dtm_cache_is_on())
+ return NULL;
+
+ split_index (dtm_cache.entries_per_block, idx, &offset, &remainder);
+
+ ret = NULL;
+
+ for (p = dtm_cache.top; p != NULL; p = p->prev) {
+
+ dtm_cache.comparisons++;
+
+ if (key == p->key && side == p->side && offset == p->offset) {
+ ret = p;
+ break;
+ }
+ }
+
+ FOLLOW_LU("point_to_dtm_block ok?",(ret!=NULL))
+
+ return ret;
+}
+
+/****************************************************************************\
+|
+|
+| WRAPPERS for ENCODING/DECODING FUNCTIONS ZONE
+|
+|
+\****************************************************************************/
+
+#include "gtb-dec.h"
+
+/*
+|
+| PRE LOAD CACHE AND DEPENDENT FUNCTIONS
+|
+\*--------------------------------------------------------------------------*/
+
+struct ZIPINFO {
+ index_t extraoffset;
+ index_t totalblocks;
+ index_t * blockindex;
+};
+
+struct ZIPINFO Zipinfo[MAX_EGKEYS];
+
+static index_t egtb_block_getnumber (tbkey_t key, unsigned side, index_t idx);
+static index_t egtb_block_getsize (tbkey_t key, index_t idx);
+static index_t egtb_block_getsize_zipped (tbkey_t key, index_t block );
+static bool_t egtb_block_park (tbkey_t key, index_t block);
+static bool_t egtb_block_read (tbkey_t key, index_t len, unsigned char *buffer);
+static bool_t egtb_block_decode (tbkey_t key, index_t z, unsigned char *bz, index_t n, unsigned char *bp);
+static bool_t egtb_block_unpack (unsigned side, index_t n, const unsigned char *bp, dtm_t *out);
+static bool_t egtb_file_beready (tbkey_t key);
+static bool_t egtb_loadindexes (tbkey_t key);
+static index_t egtb_block_uncompressed_to_index (tbkey_t key, index_t b);
+static bool_t fread32 (FILE *f, unsigned long int *y);
+
+
+static unsigned int
+zipinfo_init (void)
+{
+ int i, start, end;
+ unsigned ret;
+ bool_t ok, complet[8] = {0,0,0,0,0,0,0,0};
+ bool_t pa, partial[8] = {0,0,0,0,0,0,0,0};
+ unsigned int z;
+ int x, j;
+
+ /* reset all values */
+ for (i = 0; i < MAX_EGKEYS; i++) {
+ Zipinfo[i].blockindex = NULL;
+ Zipinfo[i].extraoffset = 0;
+ Zipinfo[i].totalblocks = 0;
+ }
+
+ /* load all values */
+ start = 0;
+ end = 5;
+ x = 3;
+ for (i = start, ok = TRUE, pa = FALSE; i < end; i++) {
+ ok = NULL != fd_openit(i);
+ pa = pa || ok;
+ ok = ok && egtb_loadindexes (i);
+ }
+ complet[x] = ok;
+ partial[x] = pa;
+
+ start = 5;
+ end = 35;
+ x = 4;
+ for (i = start, ok = TRUE, pa = FALSE; i < end; i++) {
+ ok = NULL != fd_openit(i);
+ pa = pa || ok;
+ ok = ok && egtb_loadindexes (i);
+ }
+ complet[x] = ok;
+ partial[x] = pa;
+
+ start = 35;
+ end = MAX_EGKEYS;
+ x = 5;
+ for (i = start, ok = TRUE, pa = FALSE; i < end; i++) {
+ ok = NULL != fd_openit(i);
+ pa = pa || ok;
+ ok = ok && egtb_loadindexes (i);
+ }
+ complet[x] = ok;
+ partial[x] = pa;
+
+
+ for (j = 0, z = 0, x = 3; x < 8; x++) {
+ if (partial[x]) z |= 1u << j;
+ j++;
+ if (complet[x]) z |= 1u << j;
+ j++;
+ }
+
+ ret = z;
+
+ return ret;
+}
+
+static void
+zipinfo_done (void)
+{
+ int i;
+ bool_t ok;
+ for (i = 0, ok = TRUE; ok && i < MAX_EGKEYS; i++) {
+ if (Zipinfo[i].blockindex != NULL) {
+ free(Zipinfo[i].blockindex);
+ Zipinfo[i].blockindex = NULL;
+ Zipinfo[i].extraoffset = 0;
+ Zipinfo[i].totalblocks = 0;
+ }
+ }
+ return;
+}
+
+static size_t
+zipinfo_memory_allocated (void)
+{
+ int i;
+ index_t accum_blocks = 0;
+ for (i = 0; i < MAX_EGKEYS; i++) {
+ if (Zipinfo[i].blockindex != NULL) {
+ accum_blocks += Zipinfo[i].totalblocks;
+ }
+ }
+ return (size_t)accum_blocks * sizeof(index_t);
+}
+
+extern size_t
+tb_indexmemory (void)
+{
+ return zipinfo_memory_allocated ();
+}
+
+static bool_t
+fread32 (FILE *f, unsigned long int *y)
+{
+ enum SIZE {SZ = 4};
+ int i;
+ unsigned long int x;
+ unsigned char p[SZ];
+ bool_t ok;
+
+ ok = (SZ == fread (p, sizeof(unsigned char), SZ, f));
+
+ if (ok) {
+ for (x = 0, i = 0; i < SZ; i++) {
+ x |= (unsigned long int)p[i] << (i*8);
+ }
+ *y = x;
+ }
+ return ok;
+}
+
+static bool_t
+egtb_loadindexes (tbkey_t key)
+{
+
+ unsigned long int blocksize = 1;
+ unsigned long int tailblocksize1 = 0;
+ unsigned long int tailblocksize2 = 0;
+ unsigned long int offset=0;
+ unsigned long int dummy;
+ unsigned long int i;
+ unsigned long int blocks;
+ unsigned long int n_idx;
+ unsigned long int idx;
+ index_t *p;
+
+ bool_t ok;
+
+ FILE *f;
+
+ if (Uncompressed) {
+ assert (decoding_scheme() == 0 && GTB_scheme == 0);
+ return TRUE; /* no need to load indexes */
+ }
+ if (Zipinfo[key].blockindex != NULL)
+ return TRUE; /* indexes must have been loaded already */
+
+ if (NULL == (f = egkey[key].fd))
+ return FALSE; /* file was no open */
+
+ /* Get Reserved bytes, blocksize, offset */
+ ok = (0 == fseek (f, 0, SEEK_SET)) &&
+ fread32 (f, &dummy) &&
+ fread32 (f, &dummy) &&
+ fread32 (f, &blocksize) &&
+ fread32 (f, &dummy) &&
+ fread32 (f, &tailblocksize1) &&
+ fread32 (f, &dummy) &&
+ fread32 (f, &tailblocksize2) &&
+ fread32 (f, &dummy) &&
+ fread32 (f, &offset) &&
+ fread32 (f, &dummy);
+
+ blocks = (offset - 40)/4 -1;
+ n_idx = blocks + 1;
+
+ p = NULL;
+
+ ok = ok && NULL != (p = (index_t *)malloc (n_idx * sizeof(index_t)));
+
+ /* Input of Indexes */
+ for (i = 0; ok && i < n_idx; i++) {
+ ok = fread32 (f, &idx);
+ p[i] = (index_t)idx; /* reads a 32 bit int, and converts it to index_t */ assert (sizeof(index_t) >= 4);
+ }
+
+ if (ok) {
+ Zipinfo[key].extraoffset = 0;
+ assert (n_idx <= MAXINDEX_T);
+ Zipinfo[key].totalblocks = (index_t) n_idx;
+ Zipinfo[key].blockindex = p;
+ }
+
+ if (!ok && p != NULL) {
+ free(p);
+ }
+
+ return ok;
+}
+
+static index_t
+egtb_block_uncompressed_to_index (tbkey_t key, index_t b)
+{
+ index_t max;
+ index_t blocks_per_side;
+ index_t idx;
+
+ max = egkey[key].maxindex;
+ blocks_per_side = 1 + (max-1) / (index_t)dtm_cache.entries_per_block;
+
+ if (b < blocks_per_side) {
+ idx = 0;
+ } else {
+ b -= blocks_per_side;
+ idx = max;
+ }
+ idx += b * (index_t)dtm_cache.entries_per_block;
+ return idx;
+}
+
+
+static index_t
+egtb_block_getnumber (tbkey_t key, unsigned side, index_t idx)
+{
+ index_t blocks_per_side;
+ index_t block_in_side;
+ index_t max = egkey[key].maxindex;
+
+ blocks_per_side = 1 + (max-1) / (index_t)dtm_cache.entries_per_block;
+ block_in_side = idx / (index_t)dtm_cache.entries_per_block;
+
+ return (index_t)side * blocks_per_side + block_in_side; /* block */
+}
+
+
+static index_t
+egtb_block_getsize (tbkey_t key, index_t idx)
+{
+ index_t blocksz = (index_t) dtm_cache.entries_per_block;
+ index_t maxindex = egkey[key].maxindex;
+ index_t block, offset, x;
+
+ assert (dtm_cache.entries_per_block <= MAXINDEX_T);
+ assert (0 <= idx && idx < maxindex);
+ assert (key < MAX_EGKEYS);
+
+ block = idx / blocksz;
+ offset = block * blocksz;
+
+ /*
+ | adjust block size in case that this is the last block
+ | and is shorter than "blocksz"
+ */
+ if ( (offset + blocksz) > maxindex)
+ x = maxindex - offset; /* last block size */
+ else
+ x = blocksz; /* size of a normal block */
+
+ return x;
+}
+
+static index_t
+egtb_block_getsize_zipped (tbkey_t key, index_t block )
+{
+ index_t i, j;
+ assert (Zipinfo[key].blockindex != NULL);
+ i = Zipinfo[key].blockindex[block];
+ j = Zipinfo[key].blockindex[block+1];
+ return j - i;
+}
+
+
+static bool_t
+egtb_file_beready (tbkey_t key)
+{
+ bool_t success;
+ assert (key < MAX_EGKEYS);
+ success = (NULL != egkey[key].fd) ||
+ (NULL != fd_openit(key) && egtb_loadindexes (key));
+ return success;
+}
+
+
+static bool_t
+egtb_block_park (tbkey_t key, index_t block)
+{
+ index_t i;
+ long fseek_i;
+ assert (egkey[key].fd != NULL);
+
+ if (Uncompressed) {
+ assert (decoding_scheme() == 0 && GTB_scheme == 0);
+ i = egtb_block_uncompressed_to_index (key, block);
+ } else {
+ assert (Zipinfo[key].blockindex != NULL);
+ i = Zipinfo[key].blockindex[block];
+ i += Zipinfo[key].extraoffset;
+ }
+
+ fseek_i = (long) i;
+ assert (fseek_i >= 0);
+ return 0 == fseek (egkey[key].fd, fseek_i, SEEK_SET);
+}
+
+
+static bool_t
+egtb_block_read (tbkey_t key, index_t len, unsigned char *buffer)
+{
+ assert (egkey[key].fd != NULL);
+ assert (sizeof(size_t) >= sizeof(len));
+ return ((size_t)len == fread (buffer, sizeof (unsigned char), (size_t)len, egkey[key].fd));
+}
+
+tbkey_t TB_PROBE_indexing_dummy;
+
+static bool_t
+egtb_block_decode (tbkey_t key, index_t z, unsigned char *bz, index_t n, unsigned char *bp)
+/* bz:buffer zipped to bp:buffer packed */
+{
+ size_t zz = (size_t) z;
+ size_t nn = (size_t) n;
+ TB_PROBE_indexing_dummy = key; /* to silence compiler */
+ assert (sizeof(size_t) >= sizeof(n));
+ assert (sizeof(size_t) >= sizeof(z));
+ return decode (zz-1, bz+1, nn, bp);
+}
+
+static bool_t
+egtb_block_unpack (unsigned side, index_t n, const unsigned char *bp, dtm_t *out)
+/* bp:buffer packed to out:distance to mate buffer */
+{
+ index_t i;
+ for (i = 0; i < n; i++) {
+ *out++ = dtm_unpack (side, bp[i]);
+ }
+ return TRUE;
+}
+
+static bool_t
+preload_cache (tbkey_t key, unsigned side, index_t idx)
+/* output to the least used block of the cache */
+{
+ dtm_block_t *pblock;
+ dtm_t *p;
+ bool_t ok;
+
+ FOLLOW_label("preload_cache starts")
+
+ if (idx >= egkey[key].maxindex) {
+ FOLLOW_LULU("Wrong index", __LINE__, idx)
+ return FALSE;
+ }
+
+ /* find aged blocked in cache */
+ pblock = point_block_to_replace();
+
+ if (NULL == pblock)
+ return FALSE;
+
+ p = pblock->p_arr;
+
+ if (Uncompressed) {
+
+ index_t block = egtb_block_getnumber (key, side, idx);
+ index_t n = egtb_block_getsize (key, idx);
+
+ ok = egtb_file_beready (key)
+ && egtb_block_park (key, block)
+ && egtb_block_read (key, n, Buffer_packed)
+ && egtb_block_unpack (side, n, Buffer_packed, p);
+
+ FOLLOW_LULU("preload_cache", __LINE__, ok)
+
+ assert (decoding_scheme() == 0 && GTB_scheme == 0);
+
+ if (ok) { Bytes_read = Bytes_read + (uint64_t) n; }
+
+ } else {
+
+ index_t block = 0;
+ index_t n = 0;
+ index_t z = 0;
+
+ ok = egtb_file_beready (key);
+
+ FOLLOW_LULU("preload_cache", __LINE__, ok)
+
+ if (ok) {
+ block = egtb_block_getnumber (key, side, idx);
+ n = egtb_block_getsize (key, idx);
+ z = egtb_block_getsize_zipped (key, block);
+ }
+
+ ok = ok
+ && egtb_block_park (key, block);
+ FOLLOW_LULU("preload_cache", __LINE__, ok)
+
+ ok = ok
+ && egtb_block_read (key, z, Buffer_zipped);
+ FOLLOW_LULU("preload_cache", __LINE__, ok)
+
+ ok = ok
+ && egtb_block_decode (key, z, Buffer_zipped, n, Buffer_packed);
+ FOLLOW_LULU("preload_cache", __LINE__, ok)
+
+ ok = ok
+ && egtb_block_unpack (side, n, Buffer_packed, p);
+ FOLLOW_LULU("preload_cache", __LINE__, ok)
+
+ if (ok) { Bytes_read = Bytes_read + (uint64_t) z; }
+ }
+
+ if (ok) {
+
+ index_t offset;
+ index_t remainder;
+ split_index (dtm_cache.entries_per_block, idx, &offset, &remainder);
+
+ pblock->key = key;
+ pblock->side = side;
+ pblock->offset = offset;
+ } else {
+ /* make it unusable */
+ pblock->key = -1;
+ pblock->side = gtbNOSIDE;
+ pblock->offset = gtbNOINDEX;
+ }
+
+ FOLLOW_LU("preload_cache?", ok)
+
+ return ok;
+}
+
+/****************************************************************************\
+|
+|
+| MEMORY ALLOCATION ZONE
+|
+|
+\****************************************************************************/
+
+
+mySHARED void
+egtb_freemem (int i)
+{
+ if (egkey[i].status == STATUS_MALLOC) {
+ assert (egkey[i].egt_w != NULL);
+ assert (egkey[i].egt_b != NULL);
+ free (egkey[i].egt_w);
+ free (egkey[i].egt_b);
+ egkey[i].egt_w = NULL;
+ egkey[i].egt_b = NULL;
+ }
+ egkey[i].status = STATUS_ABSENT;
+}
+
+/***************************************************************************/
+
+mySHARED bool_t
+get_dtm (tbkey_t key, unsigned side, index_t idx, dtm_t *out, bool_t probe_hard_flag)
+{
+ bool_t found;
+
+ if (probe_hard_flag) {
+ dtm_cache.hard++;
+ } else {
+ dtm_cache.soft++;
+ }
+
+ if (get_dtm_from_cache (key, side, idx, out)) {
+ dtm_cache.hits++;
+ found = TRUE;
+ } else if (probe_hard_flag) {
+ dtm_cache.hardmisses++;
+ found = preload_cache (key, side, idx) &&
+ get_dtm_from_cache (key, side, idx, out);
+
+ if (found) {
+ Drive.hits++;
+ } else {
+ Drive.miss++;
+ }
+
+
+ } else {
+ dtm_cache.softmisses++;
+ found = FALSE;
+ }
+ return found;
+}
+
+
+static bool_t
+get_dtm_from_cache (tbkey_t key, unsigned side, index_t idx, dtm_t *out)
+{
+ index_t offset;
+ index_t remainder;
+ bool_t found;
+ dtm_block_t *p;
+
+ if (!dtm_cache_is_on())
+ return FALSE;
+
+ split_index (dtm_cache.entries_per_block, idx, &offset, &remainder);
+
+ found = NULL != (p = dtm_cache_pointblock (key, side, idx));
+
+ if (found) {
+ *out = p->p_arr[remainder];
+ movetotop(p);
+ }
+
+ FOLLOW_LU("get_dtm_from_cache ok?",found)
+
+ return found;
+}
+
+
+static void
+split_index (size_t entries_per_block, index_t i, index_t *o, index_t *r)
+{
+ index_t n;
+ n = i / (index_t) entries_per_block;
+ *o = n * (index_t) entries_per_block;
+ *r = i - *o;
+ return;
+}
+
+
+static dtm_block_t *
+point_block_to_replace (void)
+{
+ dtm_block_t *p, *t, *s;
+
+ assert (0 == dtm_cache.n || dtm_cache.top != NULL);
+ assert (0 == dtm_cache.n || dtm_cache.bot != NULL);
+ assert (0 == dtm_cache.n || dtm_cache.bot->prev == NULL);
+ assert (0 == dtm_cache.n || dtm_cache.top->next == NULL);
+
+ /* no cache is being used */
+ if (dtm_cache.max_blocks == 0)
+ return NULL;
+
+ if (dtm_cache.n > 0 && -1 == dtm_cache.top->key) {
+
+ /* top entry is unusable, should be the one to replace*/
+ p = dtm_cache.top;
+
+ } else
+ if (dtm_cache.n == 0) {
+
+ assert (NULL != dtm_cache.entry);
+ p = &dtm_cache.entry[dtm_cache.n++];
+ dtm_cache.top = p;
+ dtm_cache.bot = p;
+
+ assert (NULL != p);
+ p->prev = NULL;
+ p->next = NULL;
+
+ } else
+ if (dtm_cache.n < dtm_cache.max_blocks) { /* add */
+
+ assert (NULL != dtm_cache.entry);
+ s = dtm_cache.top;
+ p = &dtm_cache.entry[dtm_cache.n++];
+ dtm_cache.top = p;
+
+ assert (NULL != p && NULL != s);
+ s->next = p;
+ p->prev = s;
+ p->next = NULL;
+
+ } else if (1 < dtm_cache.max_blocks) { /* replace*/
+
+ assert (NULL != dtm_cache.bot && NULL != dtm_cache.top);
+ t = dtm_cache.bot;
+ s = dtm_cache.top;
+
+ dtm_cache.bot = t->next;
+ dtm_cache.top = t;
+
+ s->next = t;
+ t->prev = s;
+
+ assert (dtm_cache.top);
+ dtm_cache.top->next = NULL;
+
+ assert (dtm_cache.bot);
+ dtm_cache.bot->prev = NULL;
+
+ p = t;
+
+ } else {
+
+ assert (1 == dtm_cache.max_blocks);
+ p = dtm_cache.top;
+ assert (p == dtm_cache.bot && p == dtm_cache.entry);
+ }
+
+ /* make the information content unusable, it will be replaced */
+ p->key = -1;
+ p->side = gtbNOSIDE;
+ p->offset = gtbNOINDEX;
+
+ return p;
+}
+
+static void
+movetotop (dtm_block_t *t)
+{
+ dtm_block_t *s, *nx, *pv;
+
+ assert (t != NULL);
+
+ if (t->next == NULL) /* at the top already */
+ return;
+
+ /* detach */
+ pv = t->prev;
+ nx = t->next;
+
+ if (pv == NULL) /* at the bottom */
+ dtm_cache.bot = nx;
+ else
+ pv->next = nx;
+
+ if (nx == NULL) /* at the top */
+ dtm_cache.top = pv;
+ else
+ nx->prev = pv;
+
+ /* relocate */
+ s = dtm_cache.top;
+ assert (s != NULL);
+ if (s == NULL)
+ dtm_cache.bot = t;
+ else
+ s->next = t;
+
+ t->next = NULL;
+ t->prev = s;
+ dtm_cache.top = t;
+
+ return;
+}
+
+/****************************************************************************\
+ *
+ *
+ * INDEXING ZONE
+ *
+ *
+ ****************************************************************************/
+
+static void
+init_indexing (int verbosity)
+{
+ index_t a,b,c,d,e,f;
+
+ init_flipt ();
+
+ a = init_kkidx () ;
+ b = init_ppidx () ;
+ c = init_aaidx () ;
+ d = init_aaa () ;
+ e = init_pp48_idx () ;
+ f = init_ppp48_idx () ;
+
+ if (verbosity) {
+ printf ("\nGTB supporting tables, Initialization\n");
+ printf (" Max kk idx: %8d\n", (int)a );
+ printf (" Max pp idx: %8d\n", (int)b );
+ printf (" Max aa idx: %8d\n", (int)c );
+ printf (" Max aaa idx: %8d\n", (int)d );
+ printf (" Max pp48 idx: %8d\n", (int)e );
+ printf (" Max ppp48 idx: %8d\n", (int)f );
+ }
+
+ if (!reach_was_initialized())
+ reach_init();
+
+ /* testing used only in development stage */
+
+#ifdef _MSC_VER
+#pragma warning(disable:4127)
+#endif
+
+ if (0) {
+ list_index ();
+ printf ("\nTEST indexing functions\n");
+
+ test_kaakb ();
+ test_kaabk ();
+ test_kaaak ();
+ test_kabbk ();
+
+ test_kapkb ();
+ test_kabkp ();
+
+ test_kppka ();
+
+ test_kapkp ();
+ test_kabpk();
+ test_kaapk ();
+
+ test_kappk ();
+ test_kaakp ();
+ test_kppk ();
+ test_kppkp ();
+ test_kpppk ();
+ }
+
+#ifdef _MSC_VER
+#pragma warning(default:4127)
+#endif
+
+ return;
+}
+
+
+static index_t
+init_kkidx (void)
+/* modifies kkidx[][], wksq[], bksq[] */
+{
+ index_t idx;
+ SQUARE x, y, i, j;
+
+ /* default is noindex */
+ for (x = 0; x < 64; x++) {
+ for (y = 0; y < 64; y++) {
+ IDX_set_empty(kkidx [x][y]);
+ }
+ }
+
+ idx = 0;
+ for (x = 0; x < 64; x++) {
+ for (y = 0; y < 64; y++) {
+
+ /* is x,y illegal? continue */
+ if (possible_attack (x, y, wK) || x == y)
+ continue;
+
+ /* normalize */
+ /*i <-- x; j <-- y */
+ norm_kkindex (x, y, &i, &j);
+
+ if (IDX_is_empty(kkidx [i][j])) { /* still empty */
+ kkidx [i][j] = idx;
+ kkidx [x][y] = idx;
+ bksq [idx] = i;
+ wksq [idx] = j;
+ idx++;
+ }
+ }
+ }
+
+ assert (idx == MAX_KKINDEX);
+
+ return idx;
+}
+
+
+static index_t
+init_aaidx (void)
+/* modifies aabase[], aaidx[][] */
+{
+ index_t idx;
+ SQUARE x, y;
+
+ /* default is noindex */
+ for (x = 0; x < 64; x++) {
+ for (y = 0; y < 64; y++) {
+ IDX_set_empty(aaidx [x][y]);
+ }
+ }
+
+ for (idx = 0; idx < MAX_AAINDEX; idx++)
+ aabase [idx] = 0;
+
+ idx = 0;
+ for (x = 0; x < 64; x++) {
+ for (y = x + 1; y < 64; y++) {
+
+ assert (idx == (int)((y - x) + x * (127-x)/2 - 1) );
+
+ if (IDX_is_empty(aaidx [x][y])) { /* still empty */
+ aaidx [x] [y] = idx;
+ aaidx [y] [x] = idx;
+ aabase [idx] = (unsigned char) x;
+ idx++;
+ } else {
+ assert (aaidx [x] [y] == idx);
+ assert (aabase [idx] == x);
+ }
+
+
+ }
+ }
+
+ assert (idx == MAX_AAINDEX);
+
+ return idx;
+}
+
+
+static index_t
+init_ppidx (void)
+/* modifies ppidx[][], pp_hi24[], pp_lo48[] */
+{
+ index_t i, j;
+ index_t idx = 0;
+ SQUARE a, b;
+
+ /* default is noindex */
+ for (i = 0; i < 24; i++) {
+ for (j = 0; j < 48; j++) {
+ IDX_set_empty(ppidx [i][j]);
+ }
+ }
+
+ for (idx = 0; idx < MAX_PPINDEX; idx++) {
+ IDX_set_empty(pp_hi24 [idx]);
+ IDX_set_empty(pp_lo48 [idx]);
+ }
+
+ idx = 0;
+ for (a = H7; a >= A2; a--) {
+
+ if ((a & 07) < 4) /* square in the queen side */
+ continue;
+
+ for (b = a - 1; b >= A2; b--) {
+
+ SQUARE anchor, loosen;
+
+ pp_putanchorfirst (a, b, &anchor, &loosen);
+
+ if ((anchor & 07) > 3) { /* square in the king side */
+ anchor = flipWE(anchor);
+ loosen = flipWE(loosen);
+ }
+
+ i = wsq_to_pidx24 (anchor);
+ j = wsq_to_pidx48 (loosen);
+
+ if (IDX_is_empty(ppidx [i] [j])) {
+
+ ppidx [i] [j] = idx;
+ assert (idx < MAX_PPINDEX);
+ pp_hi24 [idx] = i;
+ assert (i < 24);
+ pp_lo48 [idx] = j;
+ assert (j < 48);
+ idx++;
+ }
+
+ }
+ }
+ assert (idx == MAX_PPINDEX);
+ return idx;
+}
+
+static void
+init_flipt (void)
+{
+ unsigned int i, j;
+ for (i = 0; i < 64; i++) {
+ for (j = 0; j < 64; j++) {
+ flipt [i] [j] = flip_type (i, j);
+ }
+ }
+}
+
+/*--- NORMALIZE -------*/
+
+static void
+norm_kkindex (SQUARE x, SQUARE y, /*@out@*/ SQUARE *pi, /*@out@*/ SQUARE *pj)
+{
+ unsigned int rowx, rowy, colx, coly;
+
+ assert (x < 64);
+ assert (y < 64);
+
+ if (getcol(x) > 3) {
+ x = flipWE (x); /* x = x ^ 07 */
+ y = flipWE (y);
+ }
+ if (getrow(x) > 3) {
+ x = flipNS (x); /* x = x ^ 070 */
+ y = flipNS (y);
+ }
+ rowx = getrow(x);
+ colx = getcol(x);
+ if ( rowx > colx ) {
+ x = flipNW_SE (x); /* x = ((x&7)<<3) | (x>>3) */
+ y = flipNW_SE (y);
+ }
+ rowy = getrow(y);
+ coly = getcol(y);
+ if ( rowx == colx && rowy > coly) {
+ x = flipNW_SE (x);
+ y = flipNW_SE (y);
+ }
+
+ *pi = x;
+ *pj = y;
+}
+
+static unsigned int
+flip_type (SQUARE x, SQUARE y)
+{
+ unsigned int rowx, rowy, colx, coly;
+ unsigned int ret = 0;
+
+ assert (x < 64);
+ assert (y < 64);
+
+
+ if (getcol(x) > 3) {
+ x = flipWE (x); /* x = x ^ 07 */
+ y = flipWE (y);
+ ret |= 1;
+ }
+ if (getrow(x) > 3) {
+ x = flipNS (x); /* x = x ^ 070 */
+ y = flipNS (y);
+ ret |= 2;
+ }
+ rowx = getrow(x);
+ colx = getcol(x);
+ if ( rowx > colx ) {
+ x = flipNW_SE (x); /* x = ((x&7)<<3) | (x>>3) */
+ y = flipNW_SE (y);
+ ret |= 4;
+ }
+ rowy = getrow(y);
+ coly = getcol(y);
+ if ( rowx == colx && rowy > coly) {
+ x = flipNW_SE (x);
+ y = flipNW_SE (y);
+ ret |= 4;
+ }
+ return ret;
+}
+
+
+static void
+pp_putanchorfirst (SQUARE a, SQUARE b, /*@out@*/ SQUARE *out_anchor, /*@out@*/ SQUARE *out_loosen)
+{
+ unsigned int anchor, loosen;
+
+ unsigned int row_b, row_a;
+ row_b = b & 070;
+ row_a = a & 070;
+
+ /* default */
+ anchor = a;
+ loosen = b;
+ if (row_b > row_a) {
+ anchor = b;
+ loosen = a;
+ }
+ else
+ if (row_b == row_a) {
+ unsigned int x, col, inv, hi_a, hi_b;
+ x = a;
+ col = x & 07;
+ inv = col ^ 07;
+ x = (1u< hi_a) {
+ anchor = b;
+ loosen = a;
+ }
+
+ if (hi_b < hi_a) {
+ anchor = a;
+ loosen = b;
+ }
+
+ if (hi_b == hi_a) {
+ if (a < b) {
+ anchor = a;
+ loosen = b;
+ } else {
+ anchor = b;
+ loosen = a;
+ }
+ }
+ }
+
+ *out_anchor = anchor;
+ *out_loosen = loosen;
+ return;
+}
+
+
+static index_t
+wsq_to_pidx24 (SQUARE pawn)
+{
+ unsigned int idx24;
+ SQUARE sq = pawn;
+
+ /* input can be only queen side, pawn valid */
+ assert (A2 <= pawn && pawn < A8);
+ assert ((pawn & 07) < 4);
+
+ sq ^= 070; /* flipNS*/
+ sq -= 8; /* down one row*/
+ idx24 = (sq+(sq&3)) >> 1;
+ assert (idx24 < 24);
+ return (index_t) idx24;
+}
+
+static index_t
+wsq_to_pidx48 (SQUARE pawn)
+{
+ unsigned int idx48;
+ SQUARE sq = pawn;
+
+ /* input can be both queen or king side, pawn valid square */
+ assert (A2 <= pawn && pawn < A8);
+
+ sq ^= 070; /* flipNS*/
+ sq -= 8; /* down one row*/
+ idx48 = sq;
+ assert (idx48 < 48);
+ return (index_t)idx48;
+}
+
+static SQUARE
+pidx24_to_wsq (index_t a)
+{
+ enum {B11100 = 7u << 2};
+ unsigned int x = (unsigned int) a; /* x is pslice */
+ assert (a < 24);
+
+ x += x & B11100; /* get upper part and double it */
+ x += 8; /* add extra row */
+ x ^= 070; /* flip NS */
+ return (SQUARE) x;
+}
+
+static SQUARE
+pidx48_to_wsq (index_t a)
+{
+ unsigned int x;
+ assert (a < 48);
+ /* x is pslice */
+ x = (unsigned int)a;
+ x += 8; /* add extra row */
+ x ^= 070; /* flip NS */
+ return x;
+}
+
+
+static void
+kxk_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ enum {BLOCK_A = 64};
+
+ index_t a = i / BLOCK_A;
+ index_t b = i - a * BLOCK_A;
+
+ pw[0] = wksq [a];
+ pb[0] = bksq [a];
+ pw[1] = (SQUARE) b;
+ pw[2] = NOSQUARE;
+ pb[1] = NOSQUARE;
+
+ assert (kxk_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+static bool_t
+kxk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out)
+{
+ enum {BLOCK_A = 64};
+ SQUARE *p;
+ SQUARE ws[32], bs[32];
+ index_t ki;
+ int i;
+
+ unsigned int ft;
+
+ ft = flip_type (inp_pb[0],inp_pw[0]);
+
+ assert (ft < 8);
+
+
+ for (i = 0; inp_pw[i] != NOSQUARE; i++) {
+ ws[i] = inp_pw[i];
+ }
+ ws[i] = NOSQUARE;
+ for (i = 0; inp_pb[i] != NOSQUARE; i++) {
+ bs[i] = inp_pb[i];
+ }
+ bs[i] = NOSQUARE;
+
+ if ((ft & 1) != 0) {
+ for (p = ws; *p != NOSQUARE; p++)
+ *p = flipWE (*p);
+ for (p = bs; *p != NOSQUARE; p++)
+ *p = flipWE (*p);
+ }
+
+ if ((ft & 2) != 0) {
+ for (p = ws; *p != NOSQUARE; p++)
+ *p = flipNS (*p);
+ for (p = bs; *p != NOSQUARE; p++)
+ *p = flipNS (*p);
+ }
+
+ if ((ft & 4) != 0) {
+ for (p = ws; *p != NOSQUARE; p++)
+ *p = flipNW_SE (*p);
+ for (p = bs; *p != NOSQUARE; p++)
+ *p = flipNW_SE (*p);
+ }
+
+ ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */
+
+ if (IDX_is_empty(ki)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+ *out = ki * BLOCK_A + (index_t) ws[1];
+ return TRUE;
+
+}
+
+
+static void
+kabk_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ enum {BLOCK_A = 64*64, BLOCK_B = 64};
+ index_t a, b, c, r;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r;
+
+ pw[0] = wksq [a];
+ pb[0] = bksq [a];
+
+ pw[1] = (SQUARE) b;
+ pw[2] = (SQUARE) c;
+ pw[3] = NOSQUARE;
+
+ pb[1] = NOSQUARE;
+
+ assert (kabk_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kabk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out)
+{
+ enum {BLOCK_A = 64*64, BLOCK_B = 64};
+ SQUARE *p;
+ SQUARE ws[32], bs[32];
+ index_t ki;
+ int i;
+
+ unsigned int ft;
+
+ ft = flip_type (inp_pb[0],inp_pw[0]);
+
+ assert (ft < 8);
+
+ for (i = 0; inp_pw[i] != NOSQUARE; i++) {
+ ws[i] = inp_pw[i];
+ }
+ ws[i] = NOSQUARE;
+ for (i = 0; inp_pb[i] != NOSQUARE; i++) {
+ bs[i] = inp_pb[i];
+ }
+ bs[i] = NOSQUARE;
+
+ if ((ft & 1) != 0) {
+ for (p = ws; *p != NOSQUARE; p++)
+ *p = flipWE (*p);
+ for (p = bs; *p != NOSQUARE; p++)
+ *p = flipWE (*p);
+ }
+
+ if ((ft & 2) != 0) {
+ for (p = ws; *p != NOSQUARE; p++)
+ *p = flipNS (*p);
+ for (p = bs; *p != NOSQUARE; p++)
+ *p = flipNS (*p);
+ }
+
+ if ((ft & 4) != 0) {
+ for (p = ws; *p != NOSQUARE; p++)
+ *p = flipNW_SE (*p);
+ for (p = bs; *p != NOSQUARE; p++)
+ *p = flipNW_SE (*p);
+ }
+
+ ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */
+
+ if (IDX_is_empty(ki)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+ *out = ki * BLOCK_A + (index_t)ws[1] * BLOCK_B + (index_t)ws[2];
+ return TRUE;
+
+}
+
+
+static void
+kabkc_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ enum {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+ index_t a, b, c, d, r;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r / BLOCK_C;
+ r -= c * BLOCK_C;
+ d = r;
+
+ pw[0] = wksq [a];
+ pb[0] = bksq [a];
+
+ pw[1] = (SQUARE) b;
+ pw[2] = (SQUARE) c;
+ pw[3] = NOSQUARE;
+
+ pb[1] = (SQUARE) d;
+ pb[2] = NOSQUARE;
+
+ assert (kabkc_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kabkc_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out)
+{
+ enum {N_WHITE = 3, N_BLACK = 2};
+
+ enum {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+ SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE];
+ index_t ki;
+ int i;
+ unsigned int ft;
+
+ #if 0
+ ft = flip_type (inp_pb[0], inp_pw[0]);
+ #else
+ ft = flipt [inp_pb[0]] [inp_pw[0]];
+ #endif
+
+ assert (ft < 8);
+
+ for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; ws[N_WHITE] = NOSQUARE;
+ for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; bs[N_BLACK] = NOSQUARE;
+
+ if ((ft & WE_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipWE (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipWE (bs[i]);
+ }
+
+ if ((ft & NS_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipNS (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipNS (bs[i]);
+ }
+
+ if ((ft & NW_SE_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE (bs[i]);
+ }
+
+
+ ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */
+
+ if (IDX_is_empty(ki)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+ *out = ki * BLOCK_A + (index_t)ws[1] * BLOCK_B + (index_t)ws[2] * BLOCK_C + (index_t)bs[1];
+ return TRUE;
+
+}
+
+/* ABC/ ***/
+
+extern void
+kabck_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ enum {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+ index_t a, b, c, d, r;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r / BLOCK_C;
+ r -= c * BLOCK_C;
+ d = r;
+
+ pw[0] = wksq [a];
+ pb[0] = bksq [a];
+
+ pw[1] = (SQUARE) b;
+ pw[2] = (SQUARE) c;
+ pw[3] = (SQUARE) d;
+ pw[4] = NOSQUARE;
+
+ pb[1] = NOSQUARE;
+
+ assert (kabck_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+extern bool_t
+kabck_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out)
+{
+ enum {N_WHITE = 4, N_BLACK = 1};
+ enum {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+
+ SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE];
+ index_t ki;
+ int i;
+ unsigned int ft;
+
+ ft = flipt [inp_pb[0]] [inp_pw[0]];
+
+ assert (ft < 8);
+
+ for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; ws[N_WHITE] = NOSQUARE;
+ for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; bs[N_BLACK] = NOSQUARE;
+
+ if ((ft & WE_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipWE (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipWE (bs[i]);
+ }
+
+ if ((ft & NS_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipNS (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipNS (bs[i]);
+ }
+
+ if ((ft & NW_SE_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE (bs[i]);
+ }
+
+
+ ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */
+
+ if (IDX_is_empty(ki)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+ *out = ki * BLOCK_A + (index_t)ws[1] * BLOCK_B + (index_t)ws[2] * BLOCK_C + (index_t)ws[3];
+ return TRUE;
+
+}
+
+
+static void
+kakb_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ enum {BLOCK_A = 64*64, BLOCK_B = 64};
+ index_t a, b, c, r;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r;
+
+ pw[0] = wksq [a];
+ pb[0] = bksq [a];
+
+ pw[1] = (SQUARE) b;
+ pw[2] = NOSQUARE;
+
+ pb[1] = (SQUARE) c;
+ pb[2] = NOSQUARE;
+
+ assert (kakb_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kakb_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out)
+{
+ enum {BLOCK_A = 64*64, BLOCK_B = 64};
+ SQUARE ws[32], bs[32];
+ index_t ki;
+ unsigned int ft;
+
+ #if 0
+ ft = flip_type (inp_pb[0], inp_pw[0]);
+ #else
+ ft = flipt [inp_pb[0]] [inp_pw[0]];
+ #endif
+
+ assert (ft < 8);
+
+ ws[0] = inp_pw[0];
+ ws[1] = inp_pw[1];
+ ws[2] = NOSQUARE;
+
+ bs[0] = inp_pb[0];
+ bs[1] = inp_pb[1];
+ bs[2] = NOSQUARE;
+
+ if ((ft & 1) != 0) {
+ ws[0] = flipWE (ws[0]);
+ ws[1] = flipWE (ws[1]);
+ bs[0] = flipWE (bs[0]);
+ bs[1] = flipWE (bs[1]);
+ }
+
+ if ((ft & 2) != 0) {
+ ws[0] = flipNS (ws[0]);
+ ws[1] = flipNS (ws[1]);
+ bs[0] = flipNS (bs[0]);
+ bs[1] = flipNS (bs[1]);
+ }
+
+ if ((ft & 4) != 0) {
+ ws[0] = flipNW_SE (ws[0]);
+ ws[1] = flipNW_SE (ws[1]);
+ bs[0] = flipNW_SE (bs[0]);
+ bs[1] = flipNW_SE (bs[1]);
+ }
+
+ ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */
+
+ if (IDX_is_empty(ki)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+ *out = ki * BLOCK_A + (index_t)ws[1] * BLOCK_B + (index_t)bs[1];
+ return TRUE;
+
+}
+
+/********************** KAAKB *************************************/
+
+static bool_t test_kaakb (void);
+static bool_t kaakb_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out);
+static void kaakb_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+static bool_t
+test_kaakb (void)
+{
+
+ enum {MAXPC = 16+1};
+ char str[] = "kaakb";
+ SQUARE a, b, c, d, e;
+ SQUARE pw[MAXPC], pb[MAXPC];
+ SQUARE px[MAXPC], py[MAXPC];
+
+ index_t i, j;
+ bool_t err = FALSE;
+
+ printf ("%8s ", str);
+
+ for (a = 0; a < 64; a++) {
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ for (d = 0; d < 64; d++) {
+ for (e = 0; e < 64; e++) {
+
+ pw[0] = a;
+ pw[1] = b;
+ pw[2] = c;
+ pw[3] = NOSQUARE;
+
+ pb[0] = d;
+ pb[1] = e;
+ pb[2] = NOSQUARE;
+
+ if (kaakb_pctoindex (pw, pb, &i)) {
+ kaakb_indextopc (i, px, py);
+ kaakb_pctoindex (px, py, &j);
+ if (i != j) {
+ err = TRUE;
+ }
+ assert (i == j);
+ }
+
+ }
+ }
+ }
+ }
+
+ if ((a&1)==0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+
+ if (err)
+ printf ("> %s NOT passed\n", str);
+ else
+ printf ("> %s PASSED\n", str);
+ return !err;
+}
+
+static void
+kaakb_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ enum {
+ BLOCK_B = 64,
+ BLOCK_A = BLOCK_B * MAX_AAINDEX
+ };
+ index_t a, b, c, r, x, y;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+
+ c = r;
+
+ assert (i == (a * BLOCK_A + b * BLOCK_B + c));
+
+ pw[0] = wksq [a];
+ pb[0] = bksq [a];
+
+ x = aabase [b];
+ y = (b + 1) + x - (x * (127-x)/2);
+
+ pw[1] = (SQUARE) x;
+ pw[2] = (SQUARE) y;
+ pw[3] = NOSQUARE;
+
+ pb[1] = (SQUARE) c;
+ pb[2] = NOSQUARE;
+
+ assert (kaakb_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+static bool_t
+kaakb_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out)
+{
+ enum {N_WHITE = 3, N_BLACK = 2};
+ enum {
+ BLOCK_B = 64,
+ BLOCK_A = BLOCK_B * MAX_AAINDEX
+ };
+ SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE];
+ index_t ki, ai;
+ unsigned int ft;
+ int i;
+
+ ft = flipt [inp_pb[0]] [inp_pw[0]];
+
+ assert (ft < 8);
+
+ for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; ws[N_WHITE] = NOSQUARE;
+ for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; bs[N_BLACK] = NOSQUARE;
+
+ if ((ft & WE_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipWE (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipWE (bs[i]);
+ }
+
+ if ((ft & NS_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipNS (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipNS (bs[i]);
+ }
+
+ if ((ft & NW_SE_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE (bs[i]);
+ }
+
+ ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */
+ ai = aaidx [ws[1]] [ws[2]];
+
+ if (IDX_is_empty(ki) || IDX_is_empty(ai)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+ *out = ki * BLOCK_A + ai * BLOCK_B + (index_t)bs[1];
+ return TRUE;
+}
+
+/****************** End KAAKB *************************************/
+
+/********************** KAAB/K ************************************/
+
+static bool_t test_kaabk (void);
+static bool_t kaabk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out);
+static void kaabk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+static bool_t
+test_kaabk (void)
+{
+
+ enum {MAXPC = 16+1};
+ char str[] = "kaabk";
+ SQUARE a, b, c, d, e;
+ SQUARE pw[MAXPC], pb[MAXPC];
+ SQUARE px[MAXPC], py[MAXPC];
+
+ index_t i, j;
+ bool_t err = FALSE;
+
+ printf ("%8s ", str);
+
+ for (a = 0; a < 64; a++) {
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ for (d = 0; d < 64; d++) {
+ for (e = 0; e < 64; e++) {
+
+ pw[0] = a;
+ pw[1] = b;
+ pw[2] = c;
+ pw[3] = d;
+ pw[4] = NOSQUARE;
+
+ pb[0] = e;
+ pb[1] = NOSQUARE;
+
+ if (kaabk_pctoindex (pw, pb, &i)) {
+ kaabk_indextopc (i, px, py);
+ kaabk_pctoindex (px, py, &j);
+ if (i != j) {
+ err = TRUE;
+ }
+ assert (i == j);
+ }
+
+ }
+ }
+ }
+ }
+
+ if ((a&1)==0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+
+ if (err)
+ printf ("> %s NOT passed\n", str);
+ else
+ printf ("> %s PASSED\n", str);
+ return !err;
+}
+
+static void
+kaabk_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ enum {
+ BLOCK_B = 64,
+ BLOCK_A = BLOCK_B * MAX_AAINDEX
+ };
+ index_t a, b, c, r, x, y;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+
+ c = r;
+
+ assert (i == (a * BLOCK_A + b * BLOCK_B + c));
+
+ pw[0] = wksq [a];
+ pb[0] = bksq [a];
+
+ x = aabase [b];
+ y = (b + 1) + x - (x * (127-x)/2);
+
+ pw[1] = (SQUARE) x;
+ pw[2] = (SQUARE) y;
+ pw[3] = (SQUARE) c;
+ pw[4] = NOSQUARE;
+
+ pb[1] = NOSQUARE;
+
+ assert (kaabk_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+static bool_t
+kaabk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out)
+{
+ enum {N_WHITE = 4, N_BLACK = 1};
+ enum {
+ BLOCK_B = 64,
+ BLOCK_A = BLOCK_B * MAX_AAINDEX
+ };
+ SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE];
+ index_t ki, ai;
+ unsigned int ft;
+ int i;
+
+ ft = flipt [inp_pb[0]] [inp_pw[0]];
+
+ assert (ft < 8);
+
+ for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; ws[N_WHITE] = NOSQUARE;
+ for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; bs[N_BLACK] = NOSQUARE;
+
+ if ((ft & WE_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipWE (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipWE (bs[i]);
+ }
+
+ if ((ft & NS_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipNS (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipNS (bs[i]);
+ }
+
+ if ((ft & NW_SE_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE (bs[i]);
+ }
+
+ ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */
+ ai = aaidx [ws[1]] [ws[2]];
+
+ if (IDX_is_empty(ki) || IDX_is_empty(ai)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+ *out = ki * BLOCK_A + ai * BLOCK_B + (index_t)ws[3];
+ return TRUE;
+}
+
+/****************** End KAAB/K *************************************/
+
+/********************** KABB/K ************************************/
+
+static bool_t test_kabbk (void);
+static bool_t kabbk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out);
+static void kabbk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+static bool_t
+test_kabbk (void)
+{
+
+ enum {MAXPC = 16+1};
+ char str[] = "kabbk";
+ SQUARE a, b, c, d, e;
+ SQUARE pw[MAXPC], pb[MAXPC];
+ SQUARE px[MAXPC], py[MAXPC];
+
+ index_t i, j;
+ bool_t err = FALSE;
+
+ printf ("%8s ", str);
+
+ for (a = 0; a < 64; a++) {
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ for (d = 0; d < 64; d++) {
+ for (e = 0; e < 64; e++) {
+
+ pw[0] = a;
+ pw[1] = b;
+ pw[2] = c;
+ pw[3] = d;
+ pw[4] = NOSQUARE;
+
+ pb[0] = e;
+ pb[1] = NOSQUARE;
+
+ if (kabbk_pctoindex (pw, pb, &i)) {
+ kabbk_indextopc (i, px, py);
+ kabbk_pctoindex (px, py, &j);
+ if (i != j) {
+ err = TRUE;
+ }
+ assert (i == j);
+ }
+
+ }
+ }
+ }
+ }
+
+ if ((a&1)==0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+
+ if (err)
+ printf ("> %s NOT passed\n", str);
+ else
+ printf ("> %s PASSED\n", str);
+ return !err;
+}
+
+static void
+kabbk_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ enum {
+ BLOCK_B = 64,
+ BLOCK_A = BLOCK_B * MAX_AAINDEX
+ };
+ index_t a, b, c, r, x, y;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+
+ c = r;
+
+ assert (i == (a * BLOCK_A + b * BLOCK_B + c));
+
+ pw[0] = wksq [a];
+ pb[0] = bksq [a];
+
+ x = aabase [b];
+ y = (b + 1) + x - (x * (127-x)/2);
+
+ pw[1] = (SQUARE) c;
+ pw[2] = (SQUARE) x;
+ pw[3] = (SQUARE) y;
+ pw[4] = NOSQUARE;
+
+ pb[1] = NOSQUARE;
+
+ assert (kabbk_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+static bool_t
+kabbk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, /*@out@*/ index_t *out)
+{
+ enum {N_WHITE = 4, N_BLACK = 1};
+ enum {
+ BLOCK_B = 64,
+ BLOCK_A = BLOCK_B * MAX_AAINDEX
+ };
+ SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE];
+ index_t ki, ai;
+ unsigned int ft;
+ int i;
+
+ ft = flipt [inp_pb[0]] [inp_pw[0]];
+
+ assert (ft < 8);
+
+ for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; ws[N_WHITE] = NOSQUARE;
+ for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; bs[N_BLACK] = NOSQUARE;
+
+ if ((ft & WE_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipWE (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipWE (bs[i]);
+ }
+
+ if ((ft & NS_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipNS (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipNS (bs[i]);
+ }
+
+ if ((ft & NW_SE_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE (bs[i]);
+ }
+
+ ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */
+ ai = aaidx [ws[2]] [ws[3]];
+
+ if (IDX_is_empty(ki) || IDX_is_empty(ai)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+ *out = ki * BLOCK_A + ai * BLOCK_B + (index_t)ws[1];
+ return TRUE;
+}
+
+/********************** End KABB/K *************************************/
+
+/********************** init KAAA/K ************************************/
+
+static index_t
+aaa_getsubi (sq_t x, sq_t y, sq_t z);
+
+static sq_t aaa_xyz [MAX_AAAINDEX] [3];
+static index_t aaa_base [64];
+
+static index_t
+init_aaa (void)
+/* modifies aaa_base[], aaa_xyz[][] */
+{
+ index_t comb [64];
+ index_t accum;
+ index_t a;
+
+ index_t idx;
+ SQUARE x, y, z;
+
+ /* getting aaa_base */
+ comb [0] = 0;
+ for (a = 1; a < 64; a++) {
+ comb [a] = a * (a-1) / 2;
+ }
+
+ accum = 0;
+ aaa_base [0] = accum;
+ for (a = 0; a < (64-1); a++) {
+ accum += comb[a];
+ aaa_base [a+1] = accum;
+ }
+
+ assert ((accum + comb[63]) == MAX_AAAINDEX);
+ /* end getting aaa_base */
+
+
+ /* initialize aaa_xyz [][] */
+ for (idx = 0; idx < MAX_AAAINDEX; idx++) {
+ IDX_set_empty (aaa_xyz[idx][0]);
+ IDX_set_empty (aaa_xyz[idx][1]);
+ IDX_set_empty (aaa_xyz[idx][2]);
+ }
+
+ idx = 0;
+ for (z = 0; z < 64; z++) {
+ for (y = 0; y < z; y++) {
+ for (x = 0; x < y; x++) {
+
+ assert (idx == aaa_getsubi (x, y, z));
+
+ aaa_xyz [idx] [0] = x;
+ aaa_xyz [idx] [1] = y;
+ aaa_xyz [idx] [2] = z;
+
+ idx++;
+ }
+ }
+ }
+
+ assert (idx == MAX_AAAINDEX);
+
+ return idx;
+}
+
+
+static index_t
+aaa_getsubi (sq_t x, sq_t y, sq_t z)
+/* uses aaa_base */
+{
+ index_t calc_idx, base;
+
+ assert (x < 64 && y < 64 && z < 64);
+ assert (x < y && y < z);
+
+ base = aaa_base[z];
+ calc_idx = (index_t)x + ((index_t)y - 1) * (index_t)y / 2 + base;
+
+ return calc_idx;
+}
+
+/********************** KAAA/K ************************************/
+
+static bool_t test_kaaak (void);
+static bool_t kaaak_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out);
+static void kaaak_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+static bool_t
+test_kaaak (void)
+{
+
+ enum {MAXPC = 16+1};
+ char str[] = "kaaak";
+ SQUARE a, b, c, d, e;
+ SQUARE pw[MAXPC], pb[MAXPC];
+ SQUARE px[MAXPC], py[MAXPC];
+
+ index_t i, j;
+ bool_t err = FALSE;
+
+ printf ("%8s ", str);
+
+ for (a = 0; a < 64; a++) {
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ for (d = 0; d < 64; d++) {
+ for (e = 0; e < 64; e++) {
+
+ pw[0] = a;
+ pw[1] = b;
+ pw[2] = c;
+ pw[3] = d;
+ pw[4] = NOSQUARE;
+
+ pb[0] = e;
+ pb[1] = NOSQUARE;
+
+ if (kaaak_pctoindex (pw, pb, &i)) {
+ kaaak_indextopc (i, px, py);
+ kaaak_pctoindex (px, py, &j);
+ if (i != j) {
+ err = TRUE;
+ }
+ assert (i == j);
+ }
+
+ }
+ }
+ }
+ }
+
+ if ((a&1)==0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+
+ if (err)
+ printf ("> %s NOT passed\n", str);
+ else
+ printf ("> %s PASSED\n", str);
+ return !err;
+}
+
+static void
+kaaak_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ enum {
+ BLOCK_A = MAX_AAAINDEX
+ };
+ index_t a, b, r;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+
+ b = r;
+
+ assert (i == (a * BLOCK_A + b));
+ assert (b < BLOCK_A);
+
+ pw[0] = wksq [a];
+ pb[0] = bksq [a];
+
+ pw[1] = aaa_xyz [b] [0];
+ pw[2] = aaa_xyz [b] [1];
+ pw[3] = aaa_xyz [b] [2];
+ pw[4] = NOSQUARE;
+
+ pb[1] = NOSQUARE;
+
+ assert (kaaak_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+static bool_t
+kaaak_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out)
+{
+ enum {N_WHITE = 4, N_BLACK = 1};
+ enum {
+ BLOCK_A = MAX_AAAINDEX
+ };
+ SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE];
+ index_t ki, ai;
+ unsigned int ft;
+ int i;
+
+ ft = flipt [inp_pb[0]] [inp_pw[0]];
+
+ assert (ft < 8);
+
+ for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i]; ws[N_WHITE] = NOSQUARE;
+ for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i]; bs[N_BLACK] = NOSQUARE;
+
+ if ((ft & WE_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipWE (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipWE (bs[i]);
+ }
+
+ if ((ft & NS_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipNS (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipNS (bs[i]);
+ }
+
+ if ((ft & NW_SE_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE (bs[i]);
+ }
+
+
+ {
+ SQUARE tmp;
+ if (ws[2] < ws[1]) {
+ tmp = ws[1];
+ ws[1] = ws[2];
+ ws[2] = tmp;
+ }
+ if (ws[3] < ws[2]) {
+ tmp = ws[2];
+ ws[2] = ws[3];
+ ws[3] = tmp;
+ }
+ if (ws[2] < ws[1]) {
+ tmp = ws[1];
+ ws[1] = ws[2];
+ ws[2] = tmp;
+ }
+ }
+
+ ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */
+
+/*128 == (128 & (((ws[1]^ws[2])-1) | ((ws[1]^ws[3])-1) | ((ws[2]^ws[3])-1)) */
+
+ if (ws[1] == ws[2] || ws[1] == ws[3] || ws[2] == ws[3]) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+
+ ai = aaa_getsubi ( ws[1], ws[2], ws[3] );
+
+ if (IDX_is_empty(ki) || IDX_is_empty(ai)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+ *out = ki * BLOCK_A + ai;
+ return TRUE;
+}
+
+/****************** End KAAB/K *************************************/
+
+/********************** KAP/KB ************************************/
+
+static bool_t test_kapkb (void);
+static bool_t kapkb_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out);
+static void kapkb_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+static bool_t
+test_kapkb (void)
+{
+
+ enum {MAXPC = 16+1};
+ char str[] = "kapkb";
+ SQUARE a, b, c, d, e;
+ SQUARE pw[MAXPC], pb[MAXPC];
+ SQUARE px[MAXPC], py[MAXPC];
+
+ index_t i, j;
+ bool_t err = FALSE;
+
+ printf ("%8s ", str);
+
+ for (a = 0; a < 64; a++) {
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ for (d = 0; d < 64; d++) {
+ for (e = 0; e < 64; e++) {
+
+ if (c <= H1 || c >= A8)
+ continue;
+
+ pw[0] = a;
+ pw[1] = b;
+ pw[2] = c;
+ pw[3] = NOSQUARE;
+
+ pb[0] = e;
+ pb[1] = d;
+ pb[2] = NOSQUARE;
+
+ if (kapkb_pctoindex (pw, pb, &i)) {
+ kapkb_indextopc (i, px, py);
+ kapkb_pctoindex (px, py, &j);
+ if (i != j) {
+ err = TRUE;
+ }
+ assert (i == j);
+ }
+
+ }
+ }
+ }
+ }
+
+ if ((a&1)==0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+
+ if (err)
+ printf ("> %s NOT passed\n", str);
+ else
+ printf ("> %s PASSED\n", str);
+ return !err;
+}
+
+static void
+kapkb_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ /*---------------------------------------------------------*
+ inverse work to make sure that the following is valid
+ index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d * BLOCK_D + e;
+ *----------------------------------------------------------*/
+ enum {B11100 = 7u << 2};
+ enum {BLOCK_A = 64*64*64*64, BLOCK_B = 64*64*64, BLOCK_C = 64*64, BLOCK_D = 64};
+ index_t a, b, c, d, e, r;
+ index_t x;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r / BLOCK_C;
+ r -= c * BLOCK_C;
+ d = r / BLOCK_D;
+ r -= d * BLOCK_D;
+ e = r;
+
+ /* x is pslice */
+ x = a;
+ x += x & B11100; /* get upper part and double it */
+ x += 8; /* add extra row */
+ x ^= 070; /* flip NS */
+
+ pw[0] = (SQUARE) b;
+ pb[0] = (SQUARE) c;
+ pw[1] = (SQUARE) d;
+ pw[2] = (SQUARE) x;
+ pw[3] = NOSQUARE;
+ pb[1] = (SQUARE) e;
+ pb[2] = NOSQUARE;
+
+ assert (kapkb_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kapkb_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out)
+{
+ enum {BLOCK_A = 64*64*64*64, BLOCK_B = 64*64*64, BLOCK_C = 64*64, BLOCK_D = 64};
+ index_t pslice;
+ SQUARE sq;
+ SQUARE pawn = pw[2];
+ SQUARE wa = pw[1];
+ SQUARE wk = pw[0];
+ SQUARE bk = pb[0];
+ SQUARE ba = pb[1];
+
+ assert (A2 <= pawn && pawn < A8);
+
+ if ( !(A2 <= pawn && pawn < A8)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+
+ if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */
+ pawn = flipWE (pawn);
+ wk = flipWE (wk);
+ bk = flipWE (bk);
+ wa = flipWE (wa);
+ ba = flipWE (ba);
+ }
+
+ sq = pawn;
+ sq ^= 070; /* flipNS*/
+ sq -= 8; /* down one row*/
+ pslice = (index_t) ((sq+(sq&3)) >> 1);
+
+ *out = pslice * BLOCK_A + (index_t)wk * BLOCK_B + (index_t)bk * BLOCK_C + (index_t)wa * BLOCK_D + (index_t)ba;
+
+ return TRUE;
+}
+/********************** end KAP/KB ************************************/
+
+/************************* KAB/KP ************************************/
+
+static bool_t test_kabkp (void);
+static bool_t kabkp_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out);
+static void kabkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+static bool_t
+test_kabkp (void)
+{
+
+ enum {MAXPC = 16+1};
+ char str[] = "kabkp";
+ SQUARE a, b, c, d, e;
+ SQUARE pw[MAXPC], pb[MAXPC];
+ SQUARE px[MAXPC], py[MAXPC];
+
+ index_t i, j;
+ bool_t err = FALSE;
+
+ printf ("%8s ", str);
+
+ for (a = 0; a < 64; a++) {
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ for (d = 0; d < 64; d++) {
+ for (e = 0; e < 64; e++) {
+
+ if (d <= H1 || d >= A8)
+ continue;
+
+ pw[0] = a;
+ pw[1] = b;
+ pw[2] = c;
+ pw[3] = NOSQUARE;
+
+ pb[0] = e;
+ pb[1] = d;
+ pb[2] = NOSQUARE;
+
+ if (kabkp_pctoindex (pw, pb, &i)) {
+ kabkp_indextopc (i, px, py);
+ kabkp_pctoindex (px, py, &j);
+ if (i != j) {
+ err = TRUE;
+ }
+ assert (i == j);
+ }
+
+ }
+ }
+ }
+ }
+
+ if ((a&1)==0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+
+ if (err)
+ printf ("> %s NOT passed\n", str);
+ else
+ printf ("> %s PASSED\n", str);
+ return !err;
+}
+
+static void
+kabkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ /*---------------------------------------------------------*
+ inverse work to make sure that the following is valid
+ index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d * BLOCK_D + e;
+ *----------------------------------------------------------*/
+ enum {B11100 = 7u << 2};
+ enum {BLOCK_A = 64*64*64*64, BLOCK_B = 64*64*64, BLOCK_C = 64*64, BLOCK_D = 64};
+ index_t a, b, c, d, e, r;
+ index_t x;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r / BLOCK_C;
+ r -= c * BLOCK_C;
+ d = r / BLOCK_D;
+ r -= d * BLOCK_D;
+ e = r;
+
+ /* x is pslice */
+ x = a;
+ x += x & B11100; /* get upper part and double it */
+ x += 8; /* add extra row */
+ /*x ^= 070;*/ /* do not flip NS */
+
+ pw[0] = (SQUARE) b;
+ pb[0] = (SQUARE) c;
+ pw[1] = (SQUARE) d;
+ pw[2] = (SQUARE) e;
+ pw[3] = NOSQUARE;
+ pb[1] = (SQUARE) x;
+ pb[2] = NOSQUARE;
+
+ assert (kabkp_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kabkp_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out)
+{
+ enum {BLOCK_A = 64*64*64*64, BLOCK_B = 64*64*64, BLOCK_C = 64*64, BLOCK_D = 64};
+ index_t pslice;
+ SQUARE sq;
+ SQUARE pawn = pb[1];
+ SQUARE wa = pw[1];
+ SQUARE wk = pw[0];
+ SQUARE bk = pb[0];
+ SQUARE wb = pw[2];
+
+ assert (A2 <= pawn && pawn < A8);
+
+ if ( !(A2 <= pawn && pawn < A8)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+
+ if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */
+ pawn = flipWE (pawn);
+ wk = flipWE (wk);
+ bk = flipWE (bk);
+ wa = flipWE (wa);
+ wb = flipWE (wb);
+ }
+
+ sq = pawn;
+ /*sq ^= 070;*/ /* do not flipNS*/
+ sq -= 8; /* down one row*/
+ pslice = (index_t) ((sq+(sq&3)) >> 1);
+
+ *out = pslice * BLOCK_A + (index_t)wk * BLOCK_B + (index_t)bk * BLOCK_C + (index_t)wa * BLOCK_D + (index_t)wb;
+
+ return TRUE;
+}
+/********************** end KAB/KP ************************************/
+
+
+static void
+kpk_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ /*---------------------------------------------------------*
+ inverse work to make sure that the following is valid
+ index = a * BLOCK_A + b * BLOCK_B + c;
+ *----------------------------------------------------------*/
+ enum {B11100 = 7u << 2};
+ enum {BLOCK_A = 64*64, BLOCK_B = 64};
+ index_t a, b, c, r;
+ index_t x;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r;
+
+ /* x is pslice */
+ x = a;
+ x += x & B11100; /* get upper part and double it */
+ x += 8; /* add extra row */
+ x ^= 070; /* flip NS */
+
+ pw[1] = (SQUARE) x;
+ pw[0] = (SQUARE) b;
+ pb[0] = (SQUARE) c;
+
+ pw[2] = NOSQUARE;
+ pb[1] = NOSQUARE;
+
+ assert (kpk_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kpk_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out)
+{
+ enum {BLOCK_A = 64*64, BLOCK_B = 64};
+ index_t pslice;
+ SQUARE sq;
+ SQUARE pawn = pw[1];
+ SQUARE wk = pw[0];
+ SQUARE bk = pb[0];
+
+ #ifdef DEBUG
+ if ( !(A2 <= pawn && pawn < A8)) {
+ SQ_CONTENT wp[MAX_LISTSIZE], bp[MAX_LISTSIZE];
+ bp [0] = wp[0] = KING;
+ wp[1] = PAWN;
+ wp[2] = bp[1] = NOPIECE;
+ output_state (0, pw, pb, wp, bp);
+ }
+ #endif
+
+ assert (A2 <= pawn && pawn < A8);
+
+ if ( !(A2 <= pawn && pawn < A8)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+
+ if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */
+ pawn = flipWE (pawn);
+ wk = flipWE (wk);
+ bk = flipWE (bk);
+ }
+
+ sq = pawn;
+ sq ^= 070; /* flipNS*/
+ sq -= 8; /* down one row*/
+ pslice = (index_t) ((sq+(sq&3)) >> 1);
+
+ *out = pslice * BLOCK_A + (index_t)wk * BLOCK_B + (index_t)bk;
+
+ return TRUE;
+}
+
+
+/********************** KPP/K ************************************/
+
+static bool_t test_kppk (void);
+static bool_t kppk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out);
+static void kppk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+static bool_t
+test_kppk (void)
+{
+
+ enum {MAXPC = 16+1};
+ char str[] = "kppk";
+ SQUARE a, b, c, d;
+ SQUARE pw[MAXPC], pb[MAXPC];
+ SQUARE px[MAXPC], py[MAXPC];
+
+ index_t i, j;
+ bool_t err = FALSE;
+
+ printf ("%8s ", str);
+
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ sq_t anchor1, anchor2, loosen1, loosen2;
+ if (c <= H1 || c >= A8)
+ continue;
+ if (b <= H1 || b >= A8)
+ continue;
+
+ pp_putanchorfirst (b, c, &anchor1, &loosen1);
+ pp_putanchorfirst (c, b, &anchor2, &loosen2);
+ if (!(anchor1 == anchor2 && loosen1 == loosen2)) {
+ printf ("Output depends on input in pp_outanchorfirst()\n input:%u, %u\n",(unsigned)b,(unsigned)c);
+ fatal_error();
+ }
+ }
+ }
+
+
+ for (a = 0; a < 64; a++) {
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ for (d = 0; d < 64; d++) {
+
+
+ if (c <= H1 || c >= A8)
+ continue;
+ if (b <= H1 || b >= A8)
+ continue;
+
+
+ pw[0] = a;
+ pw[1] = b;
+ pw[2] = c;
+ pw[3] = NOSQUARE;
+
+ pb[0] = d;
+ pb[1] = NOSQUARE;
+
+ if (kppk_pctoindex (pw, pb, &i)) {
+ kppk_indextopc (i, px, py);
+ kppk_pctoindex (px, py, &j);
+ if (i != j) {
+ err = TRUE;
+ }
+ assert (i == j);
+ }
+
+
+ }
+ }
+ }
+
+ if ((a&1)==0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+
+ if (err)
+ printf ("> %s NOT passed\n", str);
+ else
+ printf ("> %s PASSED\n", str);
+ return !err;
+}
+
+static void
+kppk_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ /*---------------------------------------------------------*
+ inverse work to make sure that the following is valid
+ index = a * BLOCK_A + b * BLOCK_B + c;
+ *----------------------------------------------------------*/
+ enum {B11100 = 7u << 2};
+ enum {BLOCK_A = 64*64, BLOCK_B = 64};
+ index_t a, b, c, r;
+ index_t m, n;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r;
+
+ m = pp_hi24 [a];
+ n = pp_lo48 [a];
+
+ pw[0] = (SQUARE) b;
+ pb[0] = (SQUARE) c;
+ pb[1] = NOSQUARE;
+
+ pw[1] = pidx24_to_wsq (m);
+ pw[2] = pidx48_to_wsq (n);
+
+ pw[3] = NOSQUARE;
+
+
+ assert (A2 <= pw[1] && pw[1] < A8);
+ assert (A2 <= pw[2] && pw[2] < A8);
+
+#ifdef DEBUG
+ if (!(kppk_pctoindex (pw, pb, &a) && a == i)) {
+ pc_t wp[] = {KING, PAWN, PAWN, NOPIECE};
+ pc_t bp[] = {KING, NOPIECE};
+ printf("Indexes not matching: input:%d, output:%d\n", i, a);
+ print_pos (pw, pb, wp, bp);
+ }
+#endif
+
+ assert (kppk_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kppk_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out)
+{
+ enum {BLOCK_A = 64*64, BLOCK_B = 64};
+ index_t pp_slice;
+ SQUARE anchor, loosen;
+
+ SQUARE wk = pw[0];
+ SQUARE pawn_a = pw[1];
+ SQUARE pawn_b = pw[2];
+ SQUARE bk = pb[0];
+ index_t i, j;
+
+ #ifdef DEBUG
+ if (!(A2 <= pawn_a && pawn_a < A8)) {
+ printf ("\n\nsquare of pawn_a: %s\n", Square_str[pawn_a]);
+ printf(" wk %s\n p1 %s\n p2 %s\n bk %s\n"
+ , Square_str[wk]
+ , Square_str[pawn_a]
+ , Square_str[pawn_b]
+ , Square_str[bk]
+ );
+ }
+ #endif
+
+ assert (A2 <= pawn_a && pawn_a < A8);
+ assert (A2 <= pawn_b && pawn_b < A8);
+
+ pp_putanchorfirst (pawn_a, pawn_b, &anchor, &loosen);
+
+ if ((anchor & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */
+ anchor = flipWE (anchor);
+ loosen = flipWE (loosen);
+ wk = flipWE (wk);
+ bk = flipWE (bk);
+ }
+
+ i = wsq_to_pidx24 (anchor);
+ j = wsq_to_pidx48 (loosen);
+
+ pp_slice = ppidx [i] [j];
+
+ if (IDX_is_empty(pp_slice)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+
+ assert (pp_slice < MAX_PPINDEX );
+
+ *out = pp_slice * BLOCK_A + (index_t)wk * BLOCK_B + (index_t)bk;
+
+ return TRUE;
+}
+/****************** end KPP/K ************************************/
+
+static void
+kakp_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ /*---------------------------------------------------------*
+ inverse work to make sure that the following is valid
+ index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d;
+ *----------------------------------------------------------*/
+ enum {B11100 = 7u << 2};
+ enum {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+ index_t a, b, c, d, r;
+ index_t x;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r / BLOCK_C;
+ r -= c * BLOCK_C;
+ d = r;
+
+ /* x is pslice */
+ x = a;
+ x += x & B11100; /* get upper part and double it */
+ x += 8; /* add extra row */
+/* x ^= 070; */ /* flip NS */
+
+ pw[0] = (SQUARE) b;
+ pb[0] = (SQUARE) c;
+ pw[1] = (SQUARE) d;
+ pb[1] = (SQUARE) x;
+ pw[2] = NOSQUARE;
+ pb[2] = NOSQUARE;
+
+ assert (kakp_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kakp_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out)
+{
+ enum {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+ index_t pslice;
+ SQUARE sq;
+ SQUARE pawn = pb[1];
+ SQUARE wa = pw[1];
+ SQUARE wk = pw[0];
+ SQUARE bk = pb[0];
+
+ assert (A2 <= pawn && pawn < A8);
+
+ if ( !(A2 <= pawn && pawn < A8)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+
+ if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */
+ pawn = flipWE (pawn);
+ wk = flipWE (wk);
+ bk = flipWE (bk);
+ wa = flipWE (wa);
+ }
+
+ sq = pawn;
+ /*sq ^= 070;*/ /* flipNS*/
+ sq -= 8; /* down one row*/
+ pslice = (index_t) ((sq+(sq&3)) >> 1);
+
+ *out = pslice * BLOCK_A + (index_t)wk * BLOCK_B + (index_t)bk * BLOCK_C + (index_t)wa;
+
+ return TRUE;
+}
+
+
+static void
+kapk_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ /*---------------------------------------------------------*
+ inverse work to make sure that the following is valid
+ index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d;
+ *----------------------------------------------------------*/
+ enum {B11100 = 7u << 2};
+ enum {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+ index_t a, b, c, d, r;
+ index_t x;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r / BLOCK_C;
+ r -= c * BLOCK_C;
+ d = r;
+
+ /* x is pslice */
+ x = a;
+ x += x & B11100; /* get upper part and double it */
+ x += 8; /* add extra row */
+ x ^= 070; /* flip NS */
+
+ pw[0] = (SQUARE) b;
+ pb[0] = (SQUARE) c;
+ pw[1] = (SQUARE) d;
+ pw[2] = (SQUARE) x;
+ pw[3] = NOSQUARE;
+ pb[1] = NOSQUARE;
+
+ assert (kapk_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kapk_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out)
+{
+ enum {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+ index_t pslice;
+ SQUARE sq;
+ SQUARE pawn = pw[2];
+ SQUARE wa = pw[1];
+ SQUARE wk = pw[0];
+ SQUARE bk = pb[0];
+
+ assert (A2 <= pawn && pawn < A8);
+
+ if ( !(A2 <= pawn && pawn < A8)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+
+ if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */
+ pawn = flipWE (pawn);
+ wk = flipWE (wk);
+ bk = flipWE (bk);
+ wa = flipWE (wa);
+ }
+
+ sq = pawn;
+ sq ^= 070; /* flipNS*/
+ sq -= 8; /* down one row*/
+ pslice = (index_t) ((sq+(sq&3)) >> 1);
+
+ *out = pslice * BLOCK_A + (index_t)wk * BLOCK_B + (index_t)bk * BLOCK_C + (index_t)wa;
+
+ return TRUE;
+}
+
+
+static void
+kaak_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ enum {BLOCK_A = MAX_AAINDEX};
+ index_t a, b, r, x, y;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r;
+
+ assert (i == (a * BLOCK_A + b));
+
+ pw[0] = wksq [a];
+ pb[0] = bksq [a];
+
+ x = aabase [b];
+ y = (b + 1) + x - (x * (127-x)/2);
+
+ pw[1] = (SQUARE) x;
+ pw[2] = (SQUARE) y;
+ pw[3] = NOSQUARE;
+
+ pb[1] = NOSQUARE;
+
+ assert (kaak_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kaak_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out)
+{
+ enum {N_WHITE = 3, N_BLACK = 1};
+ enum {BLOCK_A = MAX_AAINDEX};
+ SQUARE ws[MAX_LISTSIZE], bs[MAX_LISTSIZE];
+ index_t ki, ai;
+ unsigned int ft;
+ SQUARE i;
+
+ ft = flipt [inp_pb[0]] [inp_pw[0]];
+
+ assert (ft < 8);
+
+ for (i = 0; i < N_WHITE; i++) ws[i] = inp_pw[i];
+ ws[N_WHITE] = NOSQUARE;
+ for (i = 0; i < N_BLACK; i++) bs[i] = inp_pb[i];
+ bs[N_BLACK] = NOSQUARE;
+
+ if ((ft & WE_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipWE (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipWE (bs[i]);
+ }
+
+ if ((ft & NS_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipNS (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipNS (bs[i]);
+ }
+
+ if ((ft & NW_SE_FLAG) != 0) {
+ for (i = 0; i < N_WHITE; i++) ws[i] = flipNW_SE (ws[i]);
+ for (i = 0; i < N_BLACK; i++) bs[i] = flipNW_SE (bs[i]);
+ }
+
+ ki = kkidx [bs[0]] [ws[0]]; /* kkidx [black king] [white king] */
+ ai = (index_t) aaidx [ws[1]] [ws[2]];
+
+ if (IDX_is_empty(ki) || IDX_is_empty(ai)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+ *out = ki * BLOCK_A + ai;
+ return TRUE;
+}
+
+/********************** KPP/KA ************************************/
+
+static bool_t test_kppka (void);
+static bool_t kppka_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out);
+static void kppka_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+static bool_t
+test_kppka (void)
+{
+
+ enum {MAXPC = 16+1};
+ char str[] = "kppka";
+ SQUARE a, b, c, d, e;
+ SQUARE pw[MAXPC], pb[MAXPC];
+ SQUARE px[MAXPC], py[MAXPC];
+
+ index_t i, j;
+ bool_t err = FALSE;
+
+ printf ("%8s ", str);
+
+ for (a = 0; a < 64; a++) {
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ for (d = 0; d < 64; d++) {
+ for (e = 0; e < 64; e++) {
+
+ if (c <= H1 || c >= A8)
+ continue;
+ if (b <= H1 || b >= A8)
+ continue;
+
+
+ pw[0] = a;
+ pw[1] = b;
+ pw[2] = c;
+ pw[3] = NOSQUARE;
+
+ pb[0] = e;
+ pb[1] = d;
+ pb[2] = NOSQUARE;
+
+ if (kppka_pctoindex (pw, pb, &i)) {
+ kppka_indextopc (i, px, py);
+ kppka_pctoindex (px, py, &j);
+ if (i != j) {
+ err = TRUE;
+ }
+ assert (i == j);
+ }
+
+ }
+ }
+ }
+ }
+
+ if ((a&1)==0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+
+ if (err)
+ printf ("> %s NOT passed\n", str);
+ else
+ printf ("> %s PASSED\n", str);
+ return !err;
+}
+
+
+static void
+kppka_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ /*---------------------------------------------------------*
+ inverse work to make sure that the following is valid
+ index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d;
+ *----------------------------------------------------------*/
+
+ enum {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+ index_t a, b, c, d, r;
+ index_t m, n;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r / BLOCK_C;
+ r -= c * BLOCK_C;
+ d = r;
+
+ m = pp_hi24 [a];
+ n = pp_lo48 [a];
+
+ pw[0] = (SQUARE) b;
+ pw[1] = pidx24_to_wsq (m);
+ pw[2] = pidx48_to_wsq (n);
+ pw[3] = NOSQUARE;
+
+ pb[0] = (SQUARE) c;
+ pb[1] = (SQUARE) d;
+ pb[2] = NOSQUARE;
+
+
+ assert (A2 <= pw[1] && pw[1] < A8);
+ assert (A2 <= pw[2] && pw[2] < A8);
+ assert (kppka_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kppka_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out)
+{
+ enum {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+ index_t pp_slice;
+ index_t i, j;
+
+ SQUARE anchor, loosen;
+
+ SQUARE wk = pw[0];
+ SQUARE pawn_a = pw[1];
+ SQUARE pawn_b = pw[2];
+ SQUARE bk = pb[0];
+ SQUARE ba = pb[1];
+
+
+ assert (A2 <= pawn_a && pawn_a < A8);
+ assert (A2 <= pawn_b && pawn_b < A8);
+
+ pp_putanchorfirst (pawn_a, pawn_b, &anchor, &loosen);
+
+ if ((anchor & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */
+ anchor = flipWE (anchor);
+ loosen = flipWE (loosen);
+ wk = flipWE (wk);
+ bk = flipWE (bk);
+ ba = flipWE (ba);
+ }
+
+ i = wsq_to_pidx24 (anchor);
+ j = wsq_to_pidx48 (loosen);
+
+ pp_slice = ppidx [i] [j];
+
+ if (IDX_is_empty(pp_slice)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+
+ assert (pp_slice < MAX_PPINDEX );
+
+ *out = pp_slice * (index_t)BLOCK_A + (index_t)wk * (index_t)BLOCK_B + (index_t)bk * (index_t)BLOCK_C + (index_t)ba;
+
+ return TRUE;
+}
+
+/********************** end KPP/KA ************************************/
+
+/********************** KAPP/K ************************************/
+
+static bool_t test_kappk (void);
+static bool_t kappk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out);
+static void kappk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+static bool_t
+test_kappk (void)
+{
+
+ enum {MAXPC = 16+1};
+ char str[] = "kappk";
+ SQUARE a, b, c, d, e;
+ SQUARE pw[MAXPC], pb[MAXPC];
+ SQUARE px[MAXPC], py[MAXPC];
+
+ index_t i, j;
+ bool_t err = FALSE;
+
+ printf ("%8s ", str);
+
+ for (a = 0; a < 64; a++) {
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ for (d = 0; d < 64; d++) {
+ for (e = 0; e < 64; e++) {
+
+ if (c <= H1 || c >= A8)
+ continue;
+ if (b <= H1 || b >= A8)
+ continue;
+
+
+ pw[0] = a;
+ pw[1] = d;
+ pw[2] = b;
+ pw[3] = c;
+ pw[4] = NOSQUARE;
+
+ pb[0] = e;
+ pb[1] = NOSQUARE;
+
+ if (kappk_pctoindex (pw, pb, &i)) {
+ kappk_indextopc (i, px, py);
+ kappk_pctoindex (px, py, &j);
+ if (i != j) {
+ err = TRUE;
+ }
+ assert (i == j);
+ }
+
+ }
+ }
+ }
+ }
+
+ if ((a&1)==0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+
+ if (err)
+ printf ("> %s NOT passed\n", str);
+ else
+ printf ("> %s PASSED\n", str);
+ return !err;
+}
+
+
+static void
+kappk_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ /*---------------------------------------------------------*
+ inverse work to make sure that the following is valid
+ index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d;
+ *----------------------------------------------------------*/
+
+ enum {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+ index_t a, b, c, d, r;
+ index_t m, n;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r / BLOCK_C;
+ r -= c * BLOCK_C;
+ d = r;
+
+ m = pp_hi24 [a];
+ n = pp_lo48 [a];
+
+ pw[0] = (SQUARE) b;
+ pw[1] = (SQUARE) d;
+ pw[2] = pidx24_to_wsq (m);
+ pw[3] = pidx48_to_wsq (n);
+ pw[4] = NOSQUARE;
+
+ pb[0] = (SQUARE) c;
+ pb[1] = NOSQUARE;
+
+
+ assert (A2 <= pw[3] && pw[3] < A8);
+ assert (A2 <= pw[2] && pw[2] < A8);
+ assert (kappk_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kappk_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out)
+{
+ enum {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+ index_t pp_slice;
+ SQUARE anchor, loosen;
+
+ SQUARE wk = pw[0];
+ SQUARE wa = pw[1];
+ SQUARE pawn_a = pw[2];
+ SQUARE pawn_b = pw[3];
+ SQUARE bk = pb[0];
+
+ index_t i, j;
+
+ assert (A2 <= pawn_a && pawn_a < A8);
+ assert (A2 <= pawn_b && pawn_b < A8);
+
+ pp_putanchorfirst (pawn_a, pawn_b, &anchor, &loosen);
+
+ if ((anchor & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */
+ anchor = flipWE (anchor);
+ loosen = flipWE (loosen);
+ wk = flipWE (wk);
+ bk = flipWE (bk);
+ wa = flipWE (wa);
+ }
+
+ i = wsq_to_pidx24 (anchor);
+ j = wsq_to_pidx48 (loosen);
+
+ pp_slice = ppidx [i] [j];
+
+ if (IDX_is_empty(pp_slice)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+
+ assert (pp_slice < MAX_PPINDEX );
+
+ *out = pp_slice * (index_t)BLOCK_A + (index_t)wk * (index_t)BLOCK_B + (index_t)bk * (index_t)BLOCK_C + (index_t)wa;
+
+ return TRUE;
+}
+
+/********************** end KAPP/K ************************************/
+
+/********************** KAPP/K ************************************/
+
+static bool_t test_kapkp (void);
+static bool_t kapkp_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out);
+static void kapkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+static bool_t
+test_kapkp (void)
+{
+
+ enum {MAXPC = 16+1};
+ char str[] = "kapkp";
+ SQUARE a, b, c, d, e;
+ SQUARE pw[MAXPC], pb[MAXPC];
+ SQUARE px[MAXPC], py[MAXPC];
+
+ index_t i, j;
+ bool_t err = FALSE;
+
+ printf ("%8s ", str);
+
+ for (a = 0; a < 64; a++) {
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ for (d = 0; d < 64; d++) {
+ for (e = 0; e < 64; e++) {
+
+ if (c <= H1 || c >= A8)
+ continue;
+ if (b <= H1 || b >= A8)
+ continue;
+
+
+ pw[0] = a;
+ pw[1] = d;
+ pw[2] = b;
+ pw[3] = NOSQUARE;
+
+ pb[0] = e;
+ pb[1] = c;
+ pb[2] = NOSQUARE;
+
+ if (kapkp_pctoindex (pw, pb, &i)) {
+ kapkp_indextopc (i, px, py);
+ kapkp_pctoindex (px, py, &j);
+ if (i != j) {
+ err = TRUE;
+ }
+ assert (i == j);
+ }
+
+ }
+ }
+ }
+ }
+
+ if ((a&1)==0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+
+ if (err)
+ printf ("> %s NOT passed\n", str);
+ else
+ printf ("> %s PASSED\n", str);
+ return !err;
+}
+
+
+static bool_t
+kapkp_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out)
+{
+ enum {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+ index_t pp_slice;
+ SQUARE anchor, loosen;
+
+ SQUARE wk = pw[0];
+ SQUARE wa = pw[1];
+ SQUARE pawn_a = pw[2];
+ SQUARE bk = pb[0];
+ SQUARE pawn_b = pb[1];
+ index_t m, n;
+
+ assert (A2 <= pawn_a && pawn_a < A8);
+ assert (A2 <= pawn_b && pawn_b < A8);
+ assert (pw[3] == NOSQUARE && pb[2] == NOSQUARE);
+
+ anchor = pawn_a;
+ loosen = pawn_b;
+
+ if ((anchor & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */
+ anchor = flipWE (anchor);
+ loosen = flipWE (loosen);
+ wk = flipWE (wk);
+ bk = flipWE (bk);
+ wa = flipWE (wa);
+ }
+
+ m = wsq_to_pidx24 (anchor);
+ n = (index_t)loosen - 8;
+
+ pp_slice = m * 48 + n;
+
+ if (IDX_is_empty(pp_slice)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+
+ assert (pp_slice < (64*MAX_PpINDEX) );
+
+ *out = pp_slice * (index_t)BLOCK_A + (index_t)wk * (index_t)BLOCK_B + (index_t)bk * (index_t)BLOCK_C + (index_t)wa;
+
+ return TRUE;
+}
+
+static void
+kapkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ /*---------------------------------------------------------*
+ inverse work to make sure that the following is valid
+ index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d;
+ *----------------------------------------------------------*/
+ enum {BLOCK_A = 64*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+ enum {block_m = 48};
+ index_t a, b, c, d, r;
+ index_t m, n;
+ SQUARE sq_m, sq_n;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r / BLOCK_C;
+ r -= c * BLOCK_C;
+ d = r;
+
+ /* unpack a, which is pslice, into m and n */
+ r = a;
+ m = r / block_m;
+ r -= m * block_m;
+ n = r ;
+
+ sq_m = pidx24_to_wsq (m);
+ sq_n = (SQUARE) n + 8;
+
+ pw[0] = (SQUARE) b;
+ pb[0] = (SQUARE) c;
+ pw[1] = (SQUARE) d;
+ pw[2] = sq_m;
+ pb[1] = sq_n;
+ pw[3] = NOSQUARE;
+ pb[2] = NOSQUARE;
+
+ assert (A2 <= sq_m && sq_m < A8);
+ assert (A2 <= sq_n && sq_n < A8);
+ assert (kapkp_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+/********************** end KAP/KP ************************************/
+
+/********************** KABP/K ************************************/
+
+static bool_t test_kabpk (void);
+static bool_t kabpk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out);
+static void kabpk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+static bool_t
+test_kabpk (void)
+{
+
+ enum {MAXPC = 16+1};
+ char str[] = "kabpk";
+ SQUARE a, b, c, d, e;
+ SQUARE pw[MAXPC], pb[MAXPC];
+ SQUARE px[MAXPC], py[MAXPC];
+
+ index_t i, j;
+ bool_t err = FALSE;
+
+ printf ("%8s ", str);
+
+ for (a = 0; a < 64; a++) {
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ for (d = 0; d < 64; d++) {
+ for (e = 0; e < 64; e++) {
+
+ if (d <= H1 || d >= A8)
+ continue;
+
+ pw[0] = a;
+ pw[1] = b;
+ pw[2] = c;
+ pw[3] = d;
+ pw[4] = NOSQUARE;
+
+ pb[0] = e;
+ pb[1] = NOSQUARE;
+
+ if (kabpk_pctoindex (pw, pb, &i)) {
+ kabpk_indextopc (i, px, py);
+ kabpk_pctoindex (px, py, &j);
+ if (i != j) {
+ err = TRUE;
+ }
+ assert (i == j);
+ }
+
+ }
+ }
+ }
+ }
+
+ if ((a&1)==0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+
+ if (err)
+ printf ("> %s NOT passed\n", str);
+ else
+ printf ("> %s PASSED\n", str);
+ return !err;
+}
+
+
+static void
+kabpk_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+
+ /*---------------------------------------------------------*
+ inverse work to make sure that the following is valid
+ index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d * BLOCK_D + e;
+ *----------------------------------------------------------*/
+ enum {BLOCK_A = 64*64*64*64, BLOCK_B = 64*64*64, BLOCK_C = 64*64, BLOCK_D = 64};
+ index_t a, b, c, d, e, r;
+ SQUARE x;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r / BLOCK_C;
+ r -= c * BLOCK_C;
+ d = r / BLOCK_D;
+ r -= d * BLOCK_D;
+ e = r;
+
+ x = pidx24_to_wsq(a);
+
+ pw[0] = (SQUARE) b;
+ pw[1] = (SQUARE) d;
+ pw[2] = (SQUARE) e;
+ pw[3] = x;
+ pw[4] = NOSQUARE;
+
+ pb[0] = (SQUARE) c;
+ pb[1] = NOSQUARE;
+
+ assert (kabpk_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kabpk_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out)
+{
+ enum {BLOCK_A = 64*64*64*64, BLOCK_B = 64*64*64, BLOCK_C = 64*64, BLOCK_D = 64};
+ index_t pslice;
+
+ SQUARE wk = pw[0];
+ SQUARE wa = pw[1];
+ SQUARE wb = pw[2];
+ SQUARE pawn = pw[3];
+ SQUARE bk = pb[0];
+
+ assert (A2 <= pawn && pawn < A8);
+
+ if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */
+ pawn = flipWE (pawn);
+ wk = flipWE (wk);
+ bk = flipWE (bk);
+ wa = flipWE (wa);
+ wb = flipWE (wb);
+ }
+
+ pslice = wsq_to_pidx24 (pawn);
+
+ *out = pslice * (index_t)BLOCK_A + (index_t)wk * (index_t)BLOCK_B + (index_t)bk * (index_t)BLOCK_C + (index_t)wa * (index_t)BLOCK_D + (index_t)wb;
+
+ return TRUE;
+}
+
+/********************** end KABP/K ************************************/
+
+/********************** KAAP/K ************************************/
+
+static bool_t test_kaapk (void);
+static bool_t kaapk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out);
+static void kaapk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+static bool_t
+test_kaapk (void)
+{
+
+ enum {MAXPC = 16+1};
+ char str[] = "kaapk";
+ SQUARE a, b, c, d, e;
+ SQUARE pw[MAXPC], pb[MAXPC];
+ SQUARE px[MAXPC], py[MAXPC];
+
+ index_t i, j;
+ bool_t err = FALSE;
+
+ printf ("%8s ", str);
+
+ for (a = 0; a < 64; a++) {
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ for (d = 0; d < 64; d++) {
+ for (e = 0; e < 64; e++) {
+
+ if (d <= H1 || d >= A8)
+ continue;
+
+ pw[0] = a;
+ pw[1] = b;
+ pw[2] = c;
+ pw[3] = d;
+ pw[4] = NOSQUARE;
+
+ pb[0] = e;
+ pb[1] = NOSQUARE;
+
+ if (kaapk_pctoindex (pw, pb, &i)) {
+ kaapk_indextopc (i, px, py);
+ kaapk_pctoindex (px, py, &j);
+ if (i != j) {
+ err = TRUE;
+ }
+ assert (i == j);
+ }
+
+ }
+ }
+ }
+ }
+
+ if ((a&1)==0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+
+ if (err)
+ printf ("> %s NOT passed\n", str);
+ else
+ printf ("> %s PASSED\n", str);
+ return !err;
+}
+
+
+static void
+kaapk_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ /*---------------------------------------------------------*
+ inverse work to make sure that the following is valid
+ index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d;
+ *----------------------------------------------------------*/
+ enum {BLOCK_C = MAX_AAINDEX
+ ,BLOCK_B = 64*BLOCK_C
+ ,BLOCK_A = 64*BLOCK_B
+ };
+ index_t a, b, c, d, r;
+ index_t x, y, z;
+
+ assert (i >= 0);
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r / BLOCK_C;
+ r -= c * BLOCK_C;
+ d = r;
+
+ z = (index_t) pidx24_to_wsq(a);
+
+ /* split d into x, y*/
+ x = aabase [d];
+ y = (d + 1) + x - (x * (127-x)/2);
+
+ assert (aaidx[x][y] == aaidx[y][x]);
+ assert (aaidx[x][y] == d);
+
+
+ pw[0] = (SQUARE) b;
+ pw[1] = (SQUARE) x;
+ pw[2] = (SQUARE) y;
+ pw[3] = (SQUARE) z;
+ pw[4] = NOSQUARE;
+
+ pb[0] = (SQUARE) c;
+ pb[1] = NOSQUARE;
+
+ assert (kaapk_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kaapk_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out)
+{
+ enum {BLOCK_C = MAX_AAINDEX
+ ,BLOCK_B = 64*BLOCK_C
+ ,BLOCK_A = 64*BLOCK_B
+ };
+ index_t aa_combo, pslice;
+
+ SQUARE wk = pw[0];
+ SQUARE wa = pw[1];
+ SQUARE wa2 = pw[2];
+ SQUARE pawn = pw[3];
+ SQUARE bk = pb[0];
+
+ assert (A2 <= pawn && pawn < A8);
+
+ if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */
+ pawn = flipWE (pawn);
+ wk = flipWE (wk);
+ bk = flipWE (bk);
+ wa = flipWE (wa);
+ wa2 = flipWE (wa2);
+ }
+
+ pslice = wsq_to_pidx24 (pawn);
+
+ aa_combo = (index_t) aaidx [wa] [wa2];
+
+ if (IDX_is_empty(aa_combo)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+
+ *out = pslice * (index_t)BLOCK_A + (index_t)wk * (index_t)BLOCK_B + (index_t)bk * (index_t)BLOCK_C + aa_combo;
+
+ assert (*out >= 0);
+
+ return TRUE;
+}
+
+/********************** end KAAP/K ************************************/
+
+/********************** KAA/KP ************************************/
+
+static bool_t test_kaakp (void);
+static bool_t kaakp_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out);
+static void kaakp_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+static bool_t
+test_kaakp (void)
+{
+
+ enum {MAXPC = 16+1};
+ char str[] = "kaakp";
+ SQUARE a, b, c, d, e;
+ SQUARE pw[MAXPC], pb[MAXPC];
+ SQUARE px[MAXPC], py[MAXPC];
+
+ index_t i, j;
+ bool_t err = FALSE;
+
+ printf ("%8s ", str);
+
+ for (a = 0; a < 64; a++) {
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ for (d = 0; d < 64; d++) {
+ for (e = 0; e < 64; e++) {
+
+ if (d <= H1 || d >= A8)
+ continue;
+
+ pw[0] = a;
+ pw[1] = b;
+ pw[2] = c;
+ pw[3] = NOSQUARE;
+
+ pb[0] = e;
+ pb[1] = d;
+ pb[2] = NOSQUARE;
+
+ if (kaakp_pctoindex (pw, pb, &i)) {
+ kaakp_indextopc (i, px, py);
+ kaakp_pctoindex (px, py, &j);
+ if (i != j) {
+ err = TRUE;
+ }
+ assert (i == j);
+ }
+
+ }
+ }
+ }
+ }
+
+ if ((a&1)==0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+
+ if (err)
+ printf ("> %s NOT passed\n", str);
+ else
+ printf ("> %s PASSED\n", str);
+ return !err;
+}
+
+
+static void
+kaakp_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ /*---------------------------------------------------------*
+ inverse work to make sure that the following is valid
+ index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d;
+ *----------------------------------------------------------*/
+ enum {BLOCK_C = MAX_AAINDEX
+ ,BLOCK_B = 64*BLOCK_C
+ ,BLOCK_A = 64*BLOCK_B
+ };
+ index_t a, b, c, d, r;
+ index_t x, y, z;
+ SQUARE zq;
+
+ assert (i >= 0);
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r / BLOCK_C;
+ r -= c * BLOCK_C;
+ d = r;
+
+ zq = pidx24_to_wsq(a);
+ z = (index_t)flipNS(zq);
+
+
+ /* split d into x, y*/
+ x = aabase [d];
+ y = (d + 1) + x - (x * (127-x)/2);
+
+ assert (aaidx[x][y] == aaidx[y][x]);
+ assert (aaidx[x][y] == d);
+
+
+ pw[0] = (SQUARE)b;
+ pw[1] = (SQUARE)x;
+ pw[2] = (SQUARE)y;
+ pw[3] = NOSQUARE;
+
+ pb[0] = (SQUARE)c;
+ pb[1] = (SQUARE)z;
+ pb[2] = NOSQUARE;
+
+ assert (kaakp_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kaakp_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out)
+{
+ enum {BLOCK_C = MAX_AAINDEX
+ ,BLOCK_B = 64*BLOCK_C
+ ,BLOCK_A = 64*BLOCK_B
+ };
+ index_t aa_combo, pslice;
+
+ SQUARE wk = pw[0];
+ SQUARE wa = pw[1];
+ SQUARE wa2 = pw[2];
+ SQUARE bk = pb[0];
+ SQUARE pawn = pb[1];
+
+ assert (A2 <= pawn && pawn < A8);
+
+ if ((pawn & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */
+ pawn = flipWE (pawn);
+ wk = flipWE (wk);
+ bk = flipWE (bk);
+ wa = flipWE (wa);
+ wa2 = flipWE (wa2);
+ }
+
+ pawn = flipNS(pawn);
+ pslice = wsq_to_pidx24 (pawn);
+
+ aa_combo = (index_t)aaidx [wa] [wa2];
+
+ if (IDX_is_empty(aa_combo)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+
+ *out = pslice * (index_t)BLOCK_A + (index_t)wk * (index_t)BLOCK_B + (index_t)bk * (index_t)BLOCK_C + aa_combo;
+
+ assert (*out >= 0);
+
+ return TRUE;
+}
+
+/********************** end KAA/KP ************************************/
+
+/********************** KPP/KP ************************************/
+/*
+index_t pp48_idx[48][48];
+sq_t pp48_sq_x[MAX_PP48_INDEX];
+sq_t pp48_sq_y[MAX_PP48_INDEX];
+*/
+static bool_t test_kppkp (void);
+static bool_t kppkp_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out);
+static void kppkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+static sq_t map24_b (sq_t s);
+static sq_t unmap24_b (index_t i);
+
+static index_t
+init_pp48_idx (void)
+/* modifies pp48_idx[][], pp48_sq_x[], pp48_sq_y[] */
+{
+ enum {MAX_I = 48, MAX_J = 48};
+ SQUARE i, j;
+ index_t idx = 0;
+ SQUARE a, b;
+
+ /* default is noindex */
+ for (i = 0; i < MAX_I; i++) {
+ for (j = 0; j < MAX_J; j++) {
+ IDX_set_empty (pp48_idx [i][j]);
+ }
+ }
+
+ for (idx = 0; idx < MAX_PP48_INDEX; idx++) {
+ pp48_sq_x [idx] = NOSQUARE;
+ pp48_sq_y [idx] = NOSQUARE;
+ }
+
+ idx = 0;
+ for (a = H7; a >= A2; a--) {
+
+ for (b = a - 1; b >= A2; b--) {
+
+ i = flipWE( flipNS (a) ) - 8;
+ j = flipWE( flipNS (b) ) - 8;
+
+ if (IDX_is_empty(pp48_idx [i] [j])) {
+
+ pp48_idx [i][j]= idx; assert (idx < MAX_PP48_INDEX);
+ pp48_idx [j][i]= idx;
+ pp48_sq_x [idx] = i; assert (i < MAX_I);
+ pp48_sq_y [idx] = j; assert (j < MAX_J);
+ idx++;
+ }
+ }
+ }
+ assert (idx == MAX_PP48_INDEX);
+ return idx;
+}
+
+
+
+static bool_t
+test_kppkp (void)
+{
+
+ enum {MAXPC = 16+1};
+ char str[] = "kppkp";
+ SQUARE a, b, c, d, e;
+ SQUARE pw[MAXPC], pb[MAXPC];
+ SQUARE px[MAXPC], py[MAXPC];
+
+ index_t i, j;
+ bool_t err = FALSE;
+
+ printf ("%8s ", str);
+
+ for (a = 0; a < 64; a++) {
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ for (d = 0; d < 64; d++) {
+ for (e = 0; e < 64; e++) {
+
+ if (c <= H1 || c >= A8)
+ continue;
+ if (b <= H1 || b >= A8)
+ continue;
+ if (d <= H1 || d >= A8)
+ continue;
+
+ pw[0] = a;
+ pw[1] = b;
+ pw[2] = c;
+ pw[3] = NOSQUARE;
+
+ pb[0] = e;
+ pb[1] = d;
+ pb[2] = NOSQUARE;
+
+ if (kppkp_pctoindex (pw, pb, &i)) {
+ kppkp_indextopc (i, px, py);
+ kppkp_pctoindex (px, py, &j);
+ if (i != j) {
+ err = TRUE;
+ }
+ assert (i == j);
+ }
+
+ }
+ }
+ }
+ }
+
+ if ((a&1)==0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+
+ if (err)
+ printf ("> %s NOT passed\n", str);
+ else
+ printf ("> %s PASSED\n", str);
+ return !err;
+}
+
+
+static void
+kppkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ /*---------------------------------------------------------*
+ inverse work to make sure that the following is valid
+ index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d;
+ *----------------------------------------------------------*/
+
+ enum {BLOCK_A = MAX_PP48_INDEX*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+ index_t a, b, c, d, r;
+ SQUARE m, n;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r / BLOCK_C;
+ r -= c * BLOCK_C;
+ d = r;
+
+ m = pp48_sq_x [b];
+ n = pp48_sq_y [b];
+
+ pw[0] = (SQUARE)c;
+ pw[1] = flipWE(flipNS(m+8));
+ pw[2] = flipWE(flipNS(n+8));
+ pw[3] = NOSQUARE;
+
+ pb[0] = (SQUARE)d;
+ pb[1] = (SQUARE)unmap24_b (a);
+ pb[2] = NOSQUARE;
+
+
+ assert (A2 <= pw[1] && pw[1] < A8);
+ assert (A2 <= pw[2] && pw[2] < A8);
+ assert (A2 <= pb[1] && pb[1] < A8);
+ assert (kppkp_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kppkp_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out)
+{
+ enum {BLOCK_A = MAX_PP48_INDEX*64*64, BLOCK_B = 64*64, BLOCK_C = 64};
+ index_t pp48_slice;
+
+ SQUARE wk = pw[0];
+ SQUARE pawn_a = pw[1];
+ SQUARE pawn_b = pw[2];
+ SQUARE bk = pb[0];
+ SQUARE pawn_c = pb[1];
+ SQUARE i, j, k;
+
+ assert (A2 <= pawn_a && pawn_a < A8);
+ assert (A2 <= pawn_b && pawn_b < A8);
+ assert (A2 <= pawn_c && pawn_c < A8);
+
+ if ((pawn_c & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */
+ wk = flipWE (wk);
+ pawn_a = flipWE (pawn_a);
+ pawn_b = flipWE (pawn_b);
+ bk = flipWE (bk);
+ pawn_c = flipWE (pawn_c);
+ }
+
+ i = flipWE( flipNS (pawn_a) ) - 8;
+ j = flipWE( flipNS (pawn_b) ) - 8;
+ k = map24_b (pawn_c); /* black pawn, so low indexes mean more advanced 0 == A2 */
+
+ pp48_slice = pp48_idx [i] [j];
+
+ if (IDX_is_empty(pp48_slice)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+
+ assert (pp48_slice < MAX_PP48_INDEX );
+
+ *out = (index_t)k * (index_t)BLOCK_A + pp48_slice * (index_t)BLOCK_B + (index_t)wk * (index_t)BLOCK_C + (index_t)bk;
+
+ return TRUE;
+}
+
+static sq_t
+map24_b (sq_t s)
+{
+ s -= 8;
+ return ((s&3)+s)>>1;
+}
+
+static sq_t
+unmap24_b (index_t i)
+{
+ return (sq_t) ((i&(4+8+16)) + i + 8);
+}
+
+/********************** end KPP/KP ************************************/
+
+/********************** KPPP/K ************************************/
+
+static const sq_t itosq[48] = {
+ H7,G7,F7,E7,
+ H6,G6,F6,E6,
+ H5,G5,F5,E5,
+ H4,G4,F4,E4,
+ H3,G3,F3,E3,
+ H2,G2,F2,E2,
+ D7,C7,B7,A7,
+ D6,C6,B6,A6,
+ D5,C5,B5,A5,
+ D4,C4,B4,A4,
+ D3,C3,B3,A3,
+ D2,C2,B2,A2
+};
+
+static bool_t test_kpppk (void);
+static bool_t kpppk_pctoindex (const SQUARE *inp_pw, const SQUARE *inp_pb, index_t *out);
+static void kpppk_indextopc (index_t i, SQUARE *pw, SQUARE *pb);
+
+static index_t
+init_ppp48_idx (void)
+/* modifies ppp48_idx[][], ppp48_sq_x[], ppp48_sq_y[], ppp48_sq_z[] */
+{
+ enum {MAX_I = 48, MAX_J = 48, MAX_K = 48};
+ SQUARE i, j, k;
+ index_t idx = 0;
+ SQUARE a, b, c;
+ int x, y, z;
+
+ /* default is noindex */
+ for (i = 0; i < MAX_I; i++) {
+ for (j = 0; j < MAX_J; j++) {
+ for (k = 0; k < MAX_K; k++) {
+ IDX_set_empty(ppp48_idx [i][j][k]);
+ }
+ }
+ }
+
+ for (idx = 0; idx < MAX_PPP48_INDEX; idx++) {
+ ppp48_sq_x [idx] = (uint8_t)NOSQUARE;
+ ppp48_sq_y [idx] = (uint8_t)NOSQUARE;
+ ppp48_sq_z [idx] = (uint8_t)NOSQUARE;
+ }
+
+ idx = 0;
+ for (x = 0; x < 48; x++) {
+ for (y = x+1; y < 48; y++) {
+ for (z = y+1; z < 48; z++) {
+
+ a = itosq [x];
+ b = itosq [y];
+ c = itosq [z];
+
+ if (!in_queenside(b) || !in_queenside(c))
+ continue;
+
+ i = a - 8;
+ j = b - 8;
+ k = c - 8;
+
+ if (IDX_is_empty(ppp48_idx [i] [j] [k])) {
+
+ ppp48_idx [i][j][k] = idx;
+ ppp48_idx [i][k][j] = idx;
+ ppp48_idx [j][i][k] = idx;
+ ppp48_idx [j][k][i] = idx;
+ ppp48_idx [k][i][j] = idx;
+ ppp48_idx [k][j][i] = idx;
+ ppp48_sq_x [idx] = (uint8_t) i; assert (i < MAX_I);
+ ppp48_sq_y [idx] = (uint8_t) j; assert (j < MAX_J);
+ ppp48_sq_z [idx] = (uint8_t) k; assert (k < MAX_K);
+ idx++;
+ }
+ }
+ }
+ }
+
+/* assert (idx == MAX_PPP48_INDEX);*/
+ return idx;
+}
+
+static bool_t
+test_kpppk (void)
+{
+
+ enum {MAXPC = 16+1};
+ char str[] = "kpppk";
+ SQUARE a, b, c, d, e;
+ SQUARE pw[MAXPC], pb[MAXPC];
+ SQUARE px[MAXPC], py[MAXPC];
+
+ index_t i, j;
+ bool_t err = FALSE;
+
+ printf ("%8s ", str);
+
+ for (a = 0; a < 64; a++) {
+ for (b = 0; b < 64; b++) {
+ for (c = 0; c < 64; c++) {
+ for (d = 0; d < 64; d++) {
+ for (e = 0; e < 64; e++) {
+
+ if (c <= H1 || c >= A8)
+ continue;
+ if (b <= H1 || b >= A8)
+ continue;
+ if (d <= H1 || d >= A8)
+ continue;
+
+ pw[0] = a;
+ pw[1] = b;
+ pw[2] = c;
+ pw[3] = d;
+ pw[4] = NOSQUARE;
+
+ pb[0] = e;
+ pb[1] = NOSQUARE;
+
+ if (kpppk_pctoindex (pw, pb, &i)) {
+ kpppk_indextopc (i, px, py);
+ kpppk_pctoindex (px, py, &j);
+ if (i != j) {
+ err = TRUE;
+ }
+ assert (i == j);
+ }
+
+ }
+ }
+ }
+ }
+
+ if ((a&1)==0) {
+ printf(".");
+ fflush(stdout);
+ }
+ }
+
+ if (err)
+ printf ("> %s NOT passed\n", str);
+ else
+ printf ("> %s PASSED\n", str);
+ return !err;
+}
+
+
+static void
+kpppk_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ /*---------------------------------------------------------*
+ inverse work to make sure that the following is valid
+ index = a * BLOCK_A + b * BLOCK_B + c * BLOCK_C + d;
+ *----------------------------------------------------------*/
+
+ enum {BLOCK_A = 64*64, BLOCK_B = 64};
+ index_t a, b, c, r;
+ SQUARE m, n, o;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r;
+
+ m = ppp48_sq_x [a];
+ n = ppp48_sq_y [a];
+ o = ppp48_sq_z [a];
+
+
+ pw[0] = (SQUARE)b;
+ pw[1] = m + 8;
+ pw[2] = n + 8;
+ pw[3] = o + 8;
+ pw[4] = NOSQUARE;
+
+ pb[0] = (SQUARE)c;
+ pb[1] = NOSQUARE;
+
+
+ assert (A2 <= pw[1] && pw[1] < A8);
+ assert (A2 <= pw[2] && pw[2] < A8);
+ assert (A2 <= pw[3] && pw[3] < A8);
+ assert (kpppk_pctoindex (pw, pb, &a) && a == i);
+
+ return;
+}
+
+
+static bool_t
+kpppk_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out)
+{
+ enum {BLOCK_A = 64*64, BLOCK_B = 64};
+ index_t ppp48_slice;
+
+ SQUARE wk = pw[0];
+ SQUARE pawn_a = pw[1];
+ SQUARE pawn_b = pw[2];
+ SQUARE pawn_c = pw[3];
+
+ SQUARE bk = pb[0];
+
+ SQUARE i, j, k;
+
+ assert (A2 <= pawn_a && pawn_a < A8);
+ assert (A2 <= pawn_b && pawn_b < A8);
+ assert (A2 <= pawn_c && pawn_c < A8);
+
+ i = pawn_a - 8;
+ j = pawn_b - 8;
+ k = pawn_c - 8;
+
+ ppp48_slice = ppp48_idx [i] [j] [k];
+
+ if (IDX_is_empty(ppp48_slice)) {
+ wk = flipWE (wk);
+ pawn_a = flipWE (pawn_a);
+ pawn_b = flipWE (pawn_b);
+ pawn_c = flipWE (pawn_c);
+ bk = flipWE (bk);
+ }
+
+ i = pawn_a - 8;
+ j = pawn_b - 8;
+ k = pawn_c - 8;
+
+ ppp48_slice = ppp48_idx [i] [j] [k];
+
+ if (IDX_is_empty(ppp48_slice)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+
+ assert (ppp48_slice < MAX_PPP48_INDEX );
+
+ *out = (index_t)ppp48_slice * BLOCK_A + (index_t)wk * BLOCK_B + (index_t)bk;
+
+ return TRUE;
+}
+
+
+/********************** end KPPP/K ************************************/
+
+
+static bool_t
+kpkp_pctoindex (const SQUARE *pw, const SQUARE *pb, index_t *out)
+{
+ enum {BLOCK_A = 64*64, BLOCK_B = 64};
+ SQUARE pp_slice;
+ SQUARE anchor, loosen;
+
+ SQUARE wk = pw[0];
+ SQUARE bk = pb[0];
+ SQUARE pawn_a = pw[1];
+ SQUARE pawn_b = pb[1];
+
+ SQUARE m, n;
+
+ #ifdef DEBUG
+ if (!(A2 <= pawn_a && pawn_a < A8)) {
+ printf ("\n\nsquare of pawn_a: %s\n", Square_str[pawn_a]);
+ printf(" wk %s\n p1 %s\n p2 %s\n bk %s\n"
+ , Square_str[wk]
+ , Square_str[pawn_a]
+ , Square_str[pawn_b]
+ , Square_str[bk]
+ );
+ }
+ #endif
+
+ assert (A2 <= pawn_a && pawn_a < A8);
+ assert (A2 <= pawn_b && pawn_b < A8);
+ assert (pw[2] == NOSQUARE && pb[2] == NOSQUARE);
+
+ /*pp_putanchorfirst (pawn_a, pawn_b, &anchor, &loosen);*/
+ anchor = pawn_a;
+ loosen = pawn_b;
+
+ if ((anchor & 07) > 3) { /* column is more than 3. e.g. = e,f,g, or h */
+ anchor = flipWE (anchor);
+ loosen = flipWE (loosen);
+ wk = flipWE (wk);
+ bk = flipWE (bk);
+ }
+
+ m = (SQUARE)wsq_to_pidx24 (anchor);
+ n = loosen - 8;
+
+ pp_slice = m * 48 + n;
+
+ if (IDX_is_empty(pp_slice)) {
+ *out = NOINDEX;
+ return FALSE;
+ }
+
+ assert (pp_slice < MAX_PpINDEX );
+
+ *out = (index_t) (pp_slice * BLOCK_A + wk * BLOCK_B + bk);
+
+ return TRUE;
+}
+
+
+static void
+kpkp_indextopc (index_t i, SQUARE *pw, SQUARE *pb)
+{
+ /*---------------------------------------------------------*
+ inverse work to make sure that the following is valid
+ index = a * BLOCK_A + b * BLOCK_B + c;
+ *----------------------------------------------------------*/
+ enum {B11100 = 7u << 2};
+ enum {BLOCK_A = 64*64, BLOCK_B = 64};
+ enum {block_m = 48};
+ index_t a, b, c, r;
+ index_t m, n;
+ SQUARE sq_m, sq_n;
+
+ r = i;
+ a = r / BLOCK_A;
+ r -= a * BLOCK_A;
+ b = r / BLOCK_B;
+ r -= b * BLOCK_B;
+ c = r;
+
+ /* unpack a, which is pslice, into m and n */
+ r = a;
+ m = r / block_m;
+ r -= m * block_m;
+ n = r ;
+
+ sq_m = pidx24_to_wsq (m);
+ sq_n = (SQUARE)n + 8;
+
+ pw[0] = (SQUARE)b;
+ pb[0] = (SQUARE)c;
+ pw[1] = sq_m;
+ pb[1] = sq_n;
+ pw[2] = NOSQUARE;
+ pb[2] = NOSQUARE;
+
+ assert (A2 <= pw[1] && pw[1] < A8);
+ assert (A2 <= pb[1] && pb[1] < A8);
+
+ return;
+}
+
+
+/****************************************************************************\
+ *
+ *
+ * DEBUG ZONE
+ *
+ *
+ ****************************************************************************/
+
+#if defined(DEBUG)
+static void
+print_pos (const sq_t *ws, const sq_t *bs, const pc_t *wp, const pc_t *bp)
+{
+ int i;
+ printf ("White: ");
+ for (i = 0; ws[i] != NOSQUARE; i++) {
+ printf ("%s%s ", P_str[wp[i]], Square_str[ws[i]]);
+ }
+ printf ("\nBlack: ");
+ for (i = 0; bs[i] != NOSQUARE; i++) {
+ printf ("%s%s ", P_str[bp[i]], Square_str[bs[i]]);
+ }
+ printf ("\n");
+}
+#endif
+
+#if defined(DEBUG) || defined(FOLLOW_EGTB)
+static void
+output_state (unsigned stm, const SQUARE *wSQ, const SQUARE *bSQ,
+ const SQ_CONTENT *wPC, const SQ_CONTENT *bPC)
+{
+ int i;
+ assert (stm == WH || stm == BL);
+
+ printf("\n%s to move\n", stm==WH?"White":"Black");
+ printf("W: ");
+ for (i = 0; wSQ[i] != NOSQUARE; i++) {
+ printf("%s%s ", P_str[wPC[i]], Square_str[wSQ[i]]);
+ }
+ printf("\n");
+ printf("B: ");
+ for (i = 0; bSQ[i] != NOSQUARE; i++) {
+ printf("%s%s ", P_str[bPC[i]], Square_str[bSQ[i]]);
+ }
+ printf("\n\n");
+}
+#endif
+
+static void
+list_index (void)
+{
+ enum {START_GTB = 0, END_GTB = (MAX_EGKEYS)};
+ int i;
+ index_t accum = 0;
+ printf ("\nIndex for each GTB\n");
+ printf ("%3s: %7s %7s %7s %7s\n" , "i", "TB", "RAM-slice", "RAM-max", "HD-cumulative");
+ for (i = START_GTB; i < END_GTB; i++) {
+ index_t indiv_k = egkey[i].maxindex * (index_t)sizeof(dtm_t) * 2/1024;
+ accum += indiv_k;
+ printf ("%3d: %7s %8luk %8luk %8luM\n", i, egkey[i].str, (long unsigned)(indiv_k/egkey[i].slice_n),
+ (long unsigned)indiv_k, (long unsigned)accum/1024/2);
+ }
+ printf ("\n");
+ return;
+}
+
+/**************************************************************************************************************
+
+ NEW_WDL
+
+**************************************************************************************************************/
+
+/*---------------------------------------------------------------------*\
+| WDL CACHE Implementation ZONE
+\*---------------------------------------------------------------------*/
+
+/*
+| WDL CACHE Statics
+\*---------------------------------------------------------------------*/
+
+/*--------------------------------------------------------------------------*/
+static unsigned int wdl_extract (unit_t *uarr, index_t x);
+static wdl_block_t * wdl_point_block_to_replace (void);
+static void wdl_movetotop (wdl_block_t *t);
+
+#if 0
+static bool_t wdl_cache_init (size_t cache_mem);
+static void wdl_cache_flush (void);
+static bool_t get_WDL (tbkey_t key, unsigned side, index_t idx, unsigned int *info_out, bool_t probe_hard_flag);
+#endif
+
+static bool_t wdl_cache_is_on (void);
+static void wdl_cache_reset_counters (void);
+static void wdl_cache_done (void);
+
+static wdl_block_t * wdl_point_block_to_replace (void);
+static bool_t get_WDL_from_cache (tbkey_t key, unsigned side, index_t idx, unsigned int *out);
+static void wdl_movetotop (wdl_block_t *t);
+static bool_t wdl_preload_cache (tbkey_t key, unsigned side, index_t idx);
+
+/*--------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------*\
+| WDL CACHE Maintainance
+\*---------------------------------------------------------------------*/
+
+
+static size_t
+wdl_cache_init (size_t cache_mem)
+{
+ unsigned int i;
+ wdl_block_t *p;
+ size_t entries_per_block;
+ size_t max_blocks;
+ size_t block_mem;
+
+ if (WDL_CACHE_INITIALIZED)
+ wdl_cache_done();
+
+ entries_per_block = 16 * 1024; /* fixed, needed for the compression schemes */
+
+ WDL_units_per_block = entries_per_block / WDL_entries_per_unit;
+ block_mem = WDL_units_per_block * sizeof(unit_t);
+
+ max_blocks = cache_mem / block_mem;
+ cache_mem = max_blocks * block_mem;
+
+
+ wdl_cache_reset_counters ();
+
+ wdl_cache.entries_per_block = entries_per_block;
+ wdl_cache.max_blocks = max_blocks;
+ wdl_cache.cached = TRUE;
+ wdl_cache.top = NULL;
+ wdl_cache.bot = NULL;
+ wdl_cache.n = 0;
+
+ if (0 == cache_mem || NULL == (wdl_cache.buffer = (unit_t *) malloc (cache_mem))) {
+ wdl_cache.cached = FALSE;
+ return 0;
+ }
+
+ if (0 == max_blocks|| NULL == (wdl_cache.blocks = (wdl_block_t *) malloc (max_blocks * sizeof(wdl_block_t)))) {
+ wdl_cache.cached = FALSE;
+ free (wdl_cache.buffer);
+ return 0;
+ }
+
+ for (i = 0; i < max_blocks; i++) {
+ p = &wdl_cache.blocks[i];
+ p->key = -1;
+ p->side = gtbNOSIDE;
+ p->offset = gtbNOINDEX;
+ p->p_arr = wdl_cache.buffer + i * WDL_units_per_block;
+ p->prev = NULL;
+ p->next = NULL;
+ }
+
+ WDL_CACHE_INITIALIZED = TRUE;
+
+ return cache_mem;
+}
+
+
+static void
+wdl_cache_done (void)
+{
+ assert(WDL_CACHE_INITIALIZED);
+
+ wdl_cache.cached = FALSE;
+ wdl_cache.hard = 0;
+ wdl_cache.soft = 0;
+ wdl_cache.hardmisses = 0;
+ wdl_cache.hits = 0;
+ wdl_cache.softmisses = 0;
+ wdl_cache.comparisons = 0;
+ wdl_cache.max_blocks = 0;
+ wdl_cache.entries_per_block = 0;
+
+ wdl_cache.top = NULL;
+ wdl_cache.bot = NULL;
+ wdl_cache.n = 0;
+
+ if (wdl_cache.buffer != NULL)
+ free (wdl_cache.buffer);
+ wdl_cache.buffer = NULL;
+
+ if (wdl_cache.blocks != NULL)
+ free (wdl_cache.blocks);
+ wdl_cache.blocks = NULL;
+
+ WDL_CACHE_INITIALIZED = FALSE;
+ return;
+}
+
+
+static void
+wdl_cache_flush (void)
+{
+ unsigned int i;
+ wdl_block_t *p;
+ size_t max_blocks = wdl_cache.max_blocks;
+
+ wdl_cache.top = NULL;
+ wdl_cache.bot = NULL;
+ wdl_cache.n = 0;
+
+ for (i = 0; i < max_blocks; i++) {
+ p = &wdl_cache.blocks[i];
+ p->key = -1;
+ p->side = gtbNOSIDE;
+ p->offset = gtbNOINDEX;
+ p->p_arr = wdl_cache.buffer + i * WDL_units_per_block;
+ p->prev = NULL;
+ p->next = NULL;
+ }
+
+ wdl_cache_reset_counters ();
+
+ return;
+}
+
+
+static void
+wdl_cache_reset_counters (void)
+{
+ wdl_cache.hard = 0;
+ wdl_cache.soft = 0;
+ wdl_cache.hardmisses = 0;
+ wdl_cache.hits = 0;
+ wdl_cache.softmisses = 0;
+ wdl_cache.comparisons = 0;
+ return;
+}
+
+
+static bool_t
+wdl_cache_is_on (void)
+{
+ return wdl_cache.cached;
+}
+
+/****************************************************************************\
+| Replacement
+\****************************************************************************/
+
+static wdl_block_t *
+wdl_point_block_to_replace (void)
+{
+ wdl_block_t *p, *t, *s;
+
+ assert (0 == wdl_cache.n || wdl_cache.top != NULL);
+ assert (0 == wdl_cache.n || wdl_cache.bot != NULL);
+ assert (0 == wdl_cache.n || wdl_cache.bot->prev == NULL);
+ assert (0 == wdl_cache.n || wdl_cache.top->next == NULL);
+
+ if (wdl_cache.n > 0 && -1 == wdl_cache.top->key) {
+
+ /* top blocks is unusable, should be the one to replace*/
+ p = wdl_cache.top;
+
+ } else
+ if (wdl_cache.n == 0) {
+
+ p = &wdl_cache.blocks[wdl_cache.n++];
+ wdl_cache.top = p;
+ wdl_cache.bot = p;
+
+ p->prev = NULL;
+ p->next = NULL;
+
+ } else
+ if (wdl_cache.n < wdl_cache.max_blocks) { /* add */
+
+ s = wdl_cache.top;
+ p = &wdl_cache.blocks[wdl_cache.n++];
+ wdl_cache.top = p;
+
+ s->next = p;
+ p->prev = s;
+ p->next = NULL;
+
+ } else { /* replace*/
+
+ t = wdl_cache.bot;
+ s = wdl_cache.top;
+ wdl_cache.bot = t->next;
+ wdl_cache.top = t;
+
+ s->next = t;
+ t->prev = s;
+ wdl_cache.top->next = NULL;
+ wdl_cache.bot->prev = NULL;
+
+ p = t;
+ }
+
+ /* make the information content unusable, it will be replaced */
+ p->key = -1;
+ p->side = gtbNOSIDE;
+ p->offset = gtbNOINDEX;
+
+ return p;
+}
+
+/****************************************************************************\
+|
+| NEW PROBING ZONE
+|
+\****************************************************************************/
+
+static unsigned int wdl_extract (unit_t *uarr, index_t x);
+static bool_t get_WDL_from_cache (tbkey_t key, unsigned side, index_t idx, unsigned int *info_out);
+static unsigned dtm2WDL(dtm_t dtm);
+static void wdl_movetotop (wdl_block_t *t);
+static bool_t wdl_preload_cache (tbkey_t key, unsigned side, index_t idx);
+static void dtm_block_2_wdl_block(dtm_block_t *g, wdl_block_t *w, size_t n);
+
+static bool_t
+get_WDL (tbkey_t key, unsigned side, index_t idx, unsigned int *info_out, bool_t probe_hard_flag)
+{
+ dtm_t dtm;
+ bool_t found;
+
+ found = get_WDL_from_cache (key, side, idx, info_out);
+
+ if (found) {
+ wdl_cache.hits++;
+ } else {
+ /* may probe soft */
+ found = get_dtm (key, side, idx, &dtm, probe_hard_flag);
+ if (found) {
+ *info_out = dtm2WDL(dtm);
+ /* move cache info from dtm_cache to WDL_cache */
+ if (wdl_cache_is_on())
+ wdl_preload_cache (key, side, idx);
+ }
+ }
+
+ if (probe_hard_flag) {
+ wdl_cache.hard++;
+ if (!found) {
+ wdl_cache.hardmisses++;
+ }
+ } else {
+ wdl_cache.soft++;
+ if (!found) {
+ wdl_cache.softmisses++;
+ }
+ }
+
+ return found;
+}
+
+static bool_t
+get_WDL_from_cache (tbkey_t key, unsigned side, index_t idx, unsigned int *out)
+{
+ index_t offset;
+ index_t remainder;
+ wdl_block_t *p;
+ wdl_block_t *ret;
+
+ if (!wdl_cache_is_on())
+ return FALSE;
+
+ split_index (wdl_cache.entries_per_block, idx, &offset, &remainder);
+
+ ret = NULL;
+ for (p = wdl_cache.top; p != NULL; p = p->prev) {
+
+ wdl_cache.comparisons++;
+
+ if (key == p->key && side == p->side && offset == p->offset) {
+ ret = p;
+ break;
+ }
+ }
+
+ if (ret != NULL) {
+ *out = wdl_extract (ret->p_arr, remainder);
+ wdl_movetotop(ret);
+ }
+
+ FOLLOW_LU("get_wdl_from_cache ok?",(ret != NULL))
+
+ return ret != NULL;
+}
+
+static unsigned int
+wdl_extract (unit_t *uarr, index_t x)
+{
+ index_t width = 2;
+ index_t nu = x/WDL_entries_per_unit;
+ index_t y = x - (nu * WDL_entries_per_unit);
+ return (uarr[nu] >> (y*width)) & WDL_entry_mask;
+}
+
+static void
+wdl_movetotop (wdl_block_t *t)
+{
+ wdl_block_t *s, *nx, *pv;
+
+ assert (t != NULL);
+
+ if (t->next == NULL) /* at the top already */
+ return;
+
+ /* detach */
+ pv = t->prev;
+ nx = t->next;
+
+ if (pv == NULL) /* at the bottom */
+ wdl_cache.bot = nx;
+ else
+ pv->next = nx;
+
+ if (nx == NULL) /* at the top */
+ wdl_cache.top = pv;
+ else
+ nx->prev = pv;
+
+ /* relocate */
+ s = wdl_cache.top;
+ assert (s != NULL);
+ if (s == NULL)
+ wdl_cache.bot = t;
+ else
+ s->next = t;
+
+ t->next = NULL;
+ t->prev = s;
+ wdl_cache.top = t;
+
+ return;
+}
+
+/****************************************************************************************************/
+
+static bool_t
+wdl_preload_cache (tbkey_t key, unsigned side, index_t idx)
+/* output to the least used block of the cache */
+{
+ dtm_block_t *dtm_block;
+ wdl_block_t *to_modify;
+ bool_t ok;
+
+ FOLLOW_label("wdl preload_cache starts")
+
+ if (idx >= egkey[key].maxindex) {
+ FOLLOW_LULU("Wrong index", __LINE__, idx)
+ return FALSE;
+ }
+
+ /* find fresh block in dtm cache */
+ dtm_block = dtm_cache_pointblock (key, side, idx);
+
+ /* find aged blocked in wdl cache */
+ to_modify = wdl_point_block_to_replace ();
+
+ ok = !(NULL == dtm_block || NULL == to_modify);
+
+ if (!ok)
+ return FALSE;
+
+ /* transform and move a block */
+ dtm_block_2_wdl_block(dtm_block, to_modify, dtm_cache.entries_per_block);
+
+ if (ok) {
+ index_t offset;
+ index_t remainder;
+ split_index (wdl_cache.entries_per_block, idx, &offset, &remainder);
+
+ to_modify->key = key;
+ to_modify->side = side;
+ to_modify->offset = offset;
+ } else {
+ /* make it unusable */
+ to_modify->key = -1;
+ to_modify->side = gtbNOSIDE;
+ to_modify->offset = gtbNOINDEX;
+ }
+
+ FOLLOW_LU("wdl preload_cache?", ok)
+
+ return ok;
+}
+
+/****************************************************************************************************/
+
+static void
+dtm_block_2_wdl_block(dtm_block_t *g, wdl_block_t *w, size_t n)
+{
+ int width = 2;
+ int shifting;
+ size_t i;
+ int j;
+ unsigned int x ,y;
+ dtm_t *s = g->p_arr;
+ unit_t *d = w->p_arr;
+
+ for (i = 0, y = 0; i < n; i++) {
+ j = i & 3; /* modulo WDL_entries_per_unit */
+ x = dtm2WDL(s[i]);
+ shifting = j * width;
+ y |= (x << shifting);
+
+ if (j == 3) {
+ d[i/WDL_entries_per_unit] = (unit_t) y;
+ y = 0;
+ }
+ }
+
+ if (0 != (n & 3)) { /* not multiple of 4 */
+ d[(n-1)/WDL_entries_per_unit] = (unit_t) y; /* save the rest */
+ y = 0;
+ }
+
+ return;
+}
+
+static unsigned
+dtm2WDL(dtm_t dtm)
+{
+ return (unsigned) dtm & 3;
+}
+
+
+/**************************/
+#ifdef WDL_PROBE
+
+static unsigned int inv_wdl(unsigned w);
+static bool_t egtb_get_wdl (tbkey_t k, unsigned stm, const SQUARE *wS, const SQUARE *bS, bool_t probe_hard_flag, unsigned int *wdl);
+
+static bool_t
+tb_probe_wdl
+ (unsigned stm,
+ const SQUARE *inp_wSQ,
+ const SQUARE *inp_bSQ,
+ const SQ_CONTENT *inp_wPC,
+ const SQ_CONTENT *inp_bPC,
+ bool_t probingtype,
+ /*@out@*/ unsigned *res)
+{
+ tbkey_t id = -1;
+ unsigned int wdl = iUNKNOWN;
+
+ SQUARE storage_ws [MAX_LISTSIZE], storage_bs [MAX_LISTSIZE];
+ SQ_CONTENT storage_wp [MAX_LISTSIZE], storage_bp [MAX_LISTSIZE];
+
+ SQUARE *ws = storage_ws;
+ SQUARE *bs = storage_bs;
+ SQ_CONTENT *wp = storage_wp;
+ SQ_CONTENT *bp = storage_bp;
+ SQUARE tmp_ws [MAX_LISTSIZE], tmp_bs [MAX_LISTSIZE];
+ SQ_CONTENT tmp_wp [MAX_LISTSIZE], tmp_bp [MAX_LISTSIZE];
+
+ SQUARE *temps;
+ bool_t straight = FALSE;
+
+ bool_t okcall = TRUE;
+ unsigned ply_;
+ unsigned *ply = &ply_;
+
+ /************************************/
+
+ assert (stm == WH || stm == BL);
+
+ /* VALID ONLY FOR KK!! */
+ if (inp_wPC[1] == NOPIECE && inp_bPC[1] == NOPIECE) {
+ index_t dummy_i;
+ bool_t b = kxk_pctoindex (inp_wSQ, inp_bSQ, &dummy_i);
+ *res = b? iDRAW: iFORBID;
+ *ply = 0;
+ return TRUE;
+ }
+
+ /* copy input */
+ list_pc_copy (inp_wPC, wp);
+ list_pc_copy (inp_bPC, bp);
+ list_sq_copy (inp_wSQ, ws);
+ list_sq_copy (inp_bSQ, bs);
+
+ sortlists (ws, wp);
+ sortlists (bs, bp);
+
+ FOLLOW_label("EGTB_PROBE")
+
+ if (egtb_get_id (wp, bp, &id)) {
+ FOLLOW_LU("got ID",id)
+ straight = TRUE;
+ } else if (egtb_get_id (bp, wp, &id)) {
+ FOLLOW_LU("rev ID",id)
+ straight = FALSE;
+ list_sq_flipNS (ws);
+ list_sq_flipNS (bs);
+ temps = ws;
+ ws = bs;
+ bs = temps;
+ stm = Opp(stm);
+ /* no enpassant in this fuction, so no adjustment */
+ {SQ_CONTENT *tempp = wp; wp = bp; bp = tempp;} /* added */
+ } else {
+ #if defined(DEBUG)
+ printf("did not get id...\n");
+ output_state (stm, ws, bs, wp, bp);
+ #endif
+ unpackdist (iFORBID, res, ply);
+ return FALSE;
+ }
+
+ /* store position... */
+ list_pc_copy (wp, tmp_wp);
+ list_pc_copy (bp, tmp_bp);
+ list_sq_copy (ws, tmp_ws);
+ list_sq_copy (bs, tmp_bs);
+
+ /* x will be stm and y will be stw */
+/*
+ if (stm == WH) {
+ xs = ws;
+ xp = wp;
+ ys = bs;
+ yp = bp;
+ } else {
+ xs = bs;
+ xp = bp;
+ ys = ws;
+ yp = wp;
+ }
+*/
+ okcall = egtb_get_wdl (id, stm, ws, bs, probingtype, &wdl);
+
+ FOLLOW_LU("dtmok?",okcall)
+ FOLLOW_DTM("wdl", wdl)
+
+ if (okcall) {
+
+ /*assert(epsq == NOSQUARE); */
+
+ if (straight) {
+ *res = wdl;
+ } else {
+ *res = inv_wdl (wdl);
+ }
+ } else {
+ unpackdist (iFORBID, res, ply);
+ }
+
+ return okcall;
+}
+
+static unsigned int
+inv_wdl(unsigned w)
+{
+ unsigned r = tb_UNKNOWN;
+ switch (w) {
+ case tb_DRAW: r = tb_DRAW; break;
+ case tb_WMATE: r = tb_BMATE; break;
+ case tb_BMATE: r = tb_WMATE; break;
+ case tb_FORBID: r = tb_FORBID; break;
+ case tb_UNKNOWN: r = tb_UNKNOWN; break;
+ default: r = tb_UNKNOWN; break;
+ }
+ return r;
+}
+
+static bool_t
+egtb_get_wdl (tbkey_t k, unsigned stm, const SQUARE *wS, const SQUARE *bS, bool_t probe_hard_flag, unsigned int *wdl)
+{
+ bool_t idxavail;
+ index_t idx;
+ dtm_t *tab[2];
+ bool_t (*pc2idx) (const SQUARE *, const SQUARE *, index_t *);
+
+ FOLLOW_label("egtb_get_wdl --> starts")
+
+ if (egkey[k].status == STATUS_MALLOC || egkey[k].status == STATUS_STATICRAM) {
+
+ tab[WH] = egkey[k].egt_w;
+ tab[BL] = egkey[k].egt_b;
+ pc2idx = egkey[k].pctoi;
+
+ idxavail = pc2idx (wS, bS, &idx);
+
+ FOLLOW_LU("indexavail (RAM)",idxavail)
+
+ if (idxavail) {
+ *wdl = dtm2WDL(tab[stm][idx]);
+ } else {
+ *wdl = dtm2WDL(iFORBID);
+ }
+
+ return FALSE;
+
+ } else if (egkey[k].status == STATUS_ABSENT) {
+
+ pc2idx = egkey[k].pctoi;
+ idxavail = pc2idx (wS, bS, &idx);
+
+ FOLLOW_LU("indexavail (HD)",idxavail)
+
+ if (idxavail) {
+ bool_t success;
+
+ /*
+ | LOCK
+ *-------------------------------*/
+ mythread_mutex_lock (&Egtb_lock);
+
+ success = get_WDL (k, stm, idx, wdl, probe_hard_flag);
+ FOLLOW_LU("get_wld (succ)",success)
+ FOLLOW_LU("get_wld (wdl )",*wdl)
+
+ /* this may not be needed */
+ if (!success) {
+ dtm_t dtm;
+ unsigned res, ply;
+ if (probe_hard_flag && Uncompressed) {
+ assert(Uncompressed);
+ success = egtb_filepeek (k, stm, idx, &dtm);
+ unpackdist (dtm, &res, &ply);
+ *wdl = res;
+ }
+ else
+ success = FALSE;
+ }
+
+ mythread_mutex_unlock (&Egtb_lock);
+ /*------------------------------*\
+ | UNLOCK
+ */
+
+ if (success) {
+ return TRUE;
+ } else {
+ if (probe_hard_flag) /* after probing hard and failing, no chance to succeed later */
+ egkey[k].status = STATUS_REJECT;
+ *wdl = dtm2WDL(iUNKNOWN);
+ return FALSE;
+ }
+
+ } else {
+ *wdl = dtm2WDL(iFORBID);
+ return TRUE;
+ }
+ } else if (egkey[k].status == STATUS_REJECT) {
+ FOLLOW_label("STATUS_REJECT")
+ *wdl = dtm2WDL(iFORBID);
+ return FALSE;
+ } else {
+ FOLLOW_label("STATUS_WRONG!")
+ assert(0);
+ *wdl = dtm2WDL(iFORBID);
+ return FALSE;
+ }
+
+}
+#endif
+
+
+
diff --git a/DroidFish/jni/gtb/gtb-probe.h b/DroidFish/jni/gtb/gtb-probe.h
new file mode 100644
index 0000000..cf98470
--- /dev/null
+++ b/DroidFish/jni/gtb/gtb-probe.h
@@ -0,0 +1,234 @@
+/*
+This Software is distributed with the following X11 License,
+sometimes also known as MIT license.
+
+Copyright (c) 2010 Miguel A. Ballicora
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#if !defined(H_GTBPROBE)
+#define H_GTBPROBE
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
+
+#include
+
+#define tb_MAXPATHLEN 1024
+
+/*----------------------------------*\
+| CONSTANTS
+\*----------------------------------*/
+
+enum TB_mask_values { tb_RESMASK = 3, tb_INFOMASK = 7, tb_PLYSHIFT = 3 };
+
+enum TB_return_values {
+ tb_DRAW = 0,
+ tb_WMATE = 1,
+ tb_BMATE = 2,
+ tb_FORBID = 3,
+ tb_UNKNOWN = 7
+};
+
+enum TB_pieces {
+ tb_NOPIECE, tb_PAWN, tb_KNIGHT, tb_BISHOP, tb_ROOK, tb_QUEEN, tb_KING
+};
+
+enum TB_sides {
+ tb_WHITE_TO_MOVE, tb_BLACK_TO_MOVE
+};
+
+enum TB_squares {
+ tb_A1, tb_B1, tb_C1, tb_D1, tb_E1, tb_F1, tb_G1, tb_H1,
+ tb_A2, tb_B2, tb_C2, tb_D2, tb_E2, tb_F2, tb_G2, tb_H2,
+ tb_A3, tb_B3, tb_C3, tb_D3, tb_E3, tb_F3, tb_G3, tb_H3,
+ tb_A4, tb_B4, tb_C4, tb_D4, tb_E4, tb_F4, tb_G4, tb_H4,
+ tb_A5, tb_B5, tb_C5, tb_D5, tb_E5, tb_F5, tb_G5, tb_H5,
+ tb_A6, tb_B6, tb_C6, tb_D6, tb_E6, tb_F6, tb_G6, tb_H6,
+ tb_A7, tb_B7, tb_C7, tb_D7, tb_E7, tb_F7, tb_G7, tb_H7,
+ tb_A8, tb_B8, tb_C8, tb_D8, tb_E8, tb_F8, tb_G8, tb_H8,
+ tb_NOSQUARE
+};
+
+enum TB_castling {
+ tb_NOCASTLE = 0,
+ tb_WOO = 8,
+ tb_WOOO = 4,
+ tb_BOO = 2,
+ tb_BOOO = 1
+};
+
+enum TB_compression_scheme {
+ tb_UNCOMPRESSED, tb_CP1, tb_CP2, tb_CP3, tb_CP4
+};
+
+/*----------------------------------*\
+| FUNCTIONS
+\*----------------------------------*/
+
+extern char * tb_init (int verbosity, int compression_scheme, const char **paths);
+
+extern char * tb_restart(int verbosity, int compression_scheme, const char **paths);
+
+extern void tb_done (void);
+
+extern int /*bool*/ tb_probe_hard
+ (unsigned stm,
+ unsigned epsq,
+ unsigned castles,
+ const unsigned *inp_wSQ,
+ const unsigned *inp_bSQ,
+ const unsigned char *inp_wPC,
+ const unsigned char *inp_bPC,
+ /*@out@*/ unsigned *tbinfo,
+ /*@out@*/ unsigned *plies);
+
+extern int /*bool*/ tb_probe_soft
+ (unsigned stm,
+ unsigned epsq,
+ unsigned castles,
+ const unsigned *inp_wSQ,
+ const unsigned *inp_bSQ,
+ const unsigned char *inp_wPC,
+ const unsigned char *inp_bPC,
+ /*@out@*/ unsigned *tbinfo,
+ /*@out@*/ unsigned *plies);
+
+extern int /*bool*/ tb_probe_WDL_hard
+ (unsigned stm,
+ unsigned epsq,
+ unsigned castles,
+ const unsigned *inp_wSQ,
+ const unsigned *inp_bSQ,
+ const unsigned char *inp_wPC,
+ const unsigned char *inp_bPC,
+ /*@out@*/ unsigned *tbinfo);
+
+extern int /*bool*/ tb_probe_WDL_soft
+ (unsigned stm,
+ unsigned epsq,
+ unsigned castles,
+ const unsigned *inp_wSQ,
+ const unsigned *inp_bSQ,
+ const unsigned char *inp_wPC,
+ const unsigned char *inp_bPC,
+ /*@out@*/ unsigned *tbinfo);
+
+extern int /*bool*/ tb_is_initialized (void);
+
+/*
+| tb_availability() returns 0 if no TBs available
+| Otherwise, the following bits are turned 'on' if...
+| ----------------------------------
+| bit: meaning
+| ----------------------------------
+| 0: at least one 3-pc TB is present
+| 1: 3-pc TBs are complete
+| 2: at least one 4-pc TB is present
+| 3: 4-pc TBs are complete
+| 4: at least one 5-pc TB is present
+| 5: 5-pc TBs are complete
+| 6: at least one 6-pc TB is present
+| 7: 6-pc TBs are complete
+| Example: if 63 is returned, it means all 3-4-5-pc TBs are present
+| Bits 6 and 7 will be always off, of course, until 6-piece TBs
+| are supported.
+*/
+
+extern unsigned int tb_availability(void);
+
+/*
+| tb_indexmemory ()returns
+| how much memory has been allocated for indexes
+*/
+
+extern size_t tb_indexmemory (void);
+
+/*----------------------------------*\
+| cache
+\*----------------------------------*/
+
+extern int /*bool*/ tbcache_init (size_t cache_mem, int wdl_fraction);
+extern int /*bool*/ tbcache_restart (size_t cache_mem, int wdl_fraction);
+extern void tbcache_done (void);
+extern int /*bool*/ tbcache_is_on (void);
+extern void tbcache_flush (void);
+
+/*----------------------------------*\
+| STATS
+\*----------------------------------*/
+
+/*
+| For maximum portability, some stats are provided
+| in two 32 bits integers rather than a single 64 bit number.
+| For intance, prob_hard_hits[0] contains the less significant 32 bits
+| (0 to 31), and prob_hard_hits[1] the most significant ones (32 to 63).
+| The 64-bit number can be recreated like this:
+| uint64_t x;
+| x = (uint64_t)probe_hard_hits[0]|((uint64_t)probe_hard_hits[1]<<32);
+| The user has the responsibility to combine the numbers and use the
+| proper 64 bit integers.
+*/
+
+struct TB_STATS {
+ long unsigned int wdl_easy_hits [2]; /* hits that were found in own wdl cache */
+ long unsigned int wdl_hard_prob [2]; /* hard probes to the wdl cache: if fail, they will go to HD */
+ long unsigned int wdl_soft_prob [2]; /* soft probes to the wdl cache: if fail, they won't go to HD */
+ size_t wdl_cachesize ; /* size allocated for wdl cache */
+ double wdl_occupancy ; /* % of slots filled in wdl cache */
+
+ long unsigned int dtm_easy_hits [2]; /* hits that were found in own dtm cache */
+ long unsigned int dtm_hard_prob [2]; /* hard probes to the dtm cache: if fail, they will go to HD */
+ long unsigned int dtm_soft_prob [2]; /* soft probes to the dtm cache: if fail, they won't go to HD */
+ size_t dtm_cachesize ; /* size allocated for dtm cache */
+ double dtm_occupancy ; /* % of slots filled in dtm cache */
+
+ long unsigned int total_hits [2]; /* succesful probes */
+ long unsigned int memory_hits [2]; /* succesful probes to memory */
+ long unsigned int drive_hits [2]; /* succesful probes to the Hard drive */
+ long unsigned int drive_miss [2]; /* failing probes to the Hard drive */
+ long unsigned int bytes_read [2]; /* bytes read from Hard drive */
+ long unsigned int files_opened ; /* number of files newly opened */
+ double memory_efficiency ; /* % hits from memory over total hits */
+};
+
+extern void tbstats_reset (void);
+extern void tbstats_get (struct TB_STATS *stats);
+
+
+/*----------------------------------*\
+| PATH MANAGEMENT
+\*----------------------------------*/
+
+extern const char ** tbpaths_init (void);
+extern const char ** tbpaths_add (const char **ps, const char *newpath);
+extern const char ** tbpaths_done (const char **ps);
+
+extern const char * tbpaths_getmain (void);
+
+/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/DroidFish/jni/gtb/gtb-types.h b/DroidFish/jni/gtb/gtb-types.h
new file mode 100644
index 0000000..01cc69d
--- /dev/null
+++ b/DroidFish/jni/gtb/gtb-types.h
@@ -0,0 +1,25 @@
+#if !defined(H_GTBTYPES)
+#define H_GTBTYPES
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
+#include "sysport.h"
+
+typedef uint32_t sq_t;
+typedef uint8_t pc_t;
+typedef uint32_t mv_t;
+typedef int32_t tbkey_t;
+typedef uint16_t dtm_t;
+typedef int32_t index_t;
+
+#define MAXINDEX_T ((1ul << 31)-1ul)
+
+/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
+
diff --git a/DroidFish/jni/gtb/license.txt b/DroidFish/jni/gtb/license.txt
new file mode 100644
index 0000000..57b5fd8
--- /dev/null
+++ b/DroidFish/jni/gtb/license.txt
@@ -0,0 +1,100 @@
+ Gaviota Tablebases Probing Code API
+ Copyright (c) 2010 Miguel A. Ballicora
+-----------------------------------------------------------------------------
+
+ LICENSES
+
+-----------------------------------------------------------------------------
+This Software is distributed with the following X11 License,
+sometimes also known as MIT license.
+
+Copyright (c) 2010 Miguel A. Ballicora
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+
+-----------------------------------------------------------------------------
+This Software also contain the following compression libraries:
+-----------------------------------------------------------------------------
+LZMA:
+2009-02-02 : Igor Pavlov : Public domain
+-----------------------------------------------------------------------------
+ZLIB License
+
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.3, July 18th, 2005
+
+ Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+----------------------------------------------------------------------------
+LZF:
+
+Copyright (c) 2000-2007 Marc Alexander Lehmann
+
+Redistribution and use in source and binary forms, with or without modifica-
+tion, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
+CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
+CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
+ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Alternatively, the following files carry an additional notice that
+explicitly allows relicensing under the GPLv2: lzf.c lzf.h lzfP.h lzf_c.c
+lzf_d.c
+-----------------------------------------------------------------------------
diff --git a/DroidFish/jni/gtb/progname.h b/DroidFish/jni/gtb/progname.h
new file mode 100644
index 0000000..d5f1734
--- /dev/null
+++ b/DroidFish/jni/gtb/progname.h
@@ -0,0 +1 @@
+#define PROGRAM_NAME "tbprobe"
diff --git a/DroidFish/jni/gtb/readme.txt b/DroidFish/jni/gtb/readme.txt
new file mode 100644
index 0000000..9029ec3
--- /dev/null
+++ b/DroidFish/jni/gtb/readme.txt
@@ -0,0 +1,147 @@
+ Gaviota Tablebases Probing Code API
+ Copyright (c) 2010-2011 Miguel A. Ballicora
+-----------------------------------------------------------------------------
+
+This software provides C code to probe the Gaviota Endgame Tablebases.
+It is released under then X11 ("MIT") license (see license.txt).
+
+This API (Application Programming Interface) is designed to be as portable
+as possible. Functions could be called from Linux or Windows.
+Most likely it will work in other operating systems but that has not been
+tested. This API is a beta version and as such, it is not guaranteed any
+type of backward compatibility or to remain untouched, at least until
+version 1.0 is released.
+
+A very small set of tablebase files is included in this distribution
+for testing purposes (only 3 pieces). They are compressed with four
+different compression schemes. For a more complete set, please download
+Gaviota from
+
+http://sites.google.com/site/gaviotachessengine/
+
+and generate the 4 and 5 piece tablebases. Instructions how to generate
+and compressed them are in the website. More information can always be found:
+
+http://sites.google.com/site/gaviotachessengine/Home/endgame-tablebases-1
+
+Alternatively, already compressed tablebase files (ready to go!) can be
+downloaded from
+
+http://www.olympuschess.com/egtb/gaviota/ (Many thanks to Josh Shriver)
+
+"tbprobe" is distributed here as a tablebase probing example. The current API
+is relatively "low level" to optimize performance. We hope the small program
+tbprobe is self explanatory. A thorough and detailed documentation may be
+released later. However, it seems that everybody who attempted to implement
+this probing code was successful relatively easy.
+
+We plan to support an interface with a FEN notation; thus, it is expected
+that some other functions maybe added to this API.
+
+Four different types of compression are included. It is possible that in the
+future some other compression schemes could be provided, but only if they
+represent a serious improvement in speed or memory size. To maximize
+backward compatibility between versions of programs and TBs, it is strongly
+recommended that engine developers always support at least scheme 4 (tb_CP4),
+which is considered the default at this point. For that reason, it is
+suggested that testers always have a set of TBs compressed with scheme 4.
+
+This API is designed to be multithreading friendly. Regions where different
+threads could access data from this API were protected with a mutex to avoid
+problems.
+
+-------------------------- How to use this API ------------------------------
+
+To include this code in any engine or GUI, the following files should be
+compiled and linked:
+
+gtb-probe.c
+gtb-dec.c
+gtb-att.c
+sysport/sysport.c
+compression/wrap.c
+compression/huffman/hzip.c
+compression/liblzf/lzf_c.c
+compression/liblzf/lzf_d.c
+compression/zlib/zcompress.c
+compression/zlib/uncompr.c
+compression/zlib/inflate.c
+compression/zlib/deflate.c
+compression/zlib/adler32.c
+compression/zlib/crc32.c
+compression/zlib/infback.c
+compression/zlib/inffast.c
+compression/zlib/inftrees.c
+compression/zlib/trees.c
+compression/zlib/zutil.c
+compression/lzma/LzmaEnc.c
+compression/lzma/LzmaDec.c
+compression/lzma/Alloc.c
+compression/lzma/LzFind.c
+compression/lzma/Lzma86Enc.c
+compression/lzma/Lzma86Dec.c
+compression/lzma/Bra86.c
+
+The following files will be "included"
+gtb-probe.h
+gtb-dec.h
+gtb-att.h
+gtb-types.h
+
+plus all the *.h files in the folders, so set the proper -I flags:
+sysport/
+compression/
+compression/huffman/
+compression/liblzf/
+compression/zlib/
+compression/lzma/
+
+The following libraries should be linked in Linux
+-lpthread
+-lm
+
+In Windows, the appropriate MT (multithreaded library should be linked too)
+
+These switches should be set in the compiler
+-D NDEBUG
+-D Z_PREFIX
+
+The first one removes the assert code, and the second
+one makes sure that there is no collision between some names in the
+zlib library and names in other compression libraries.
+
+-------------------------- COMPILATION EXAMPLE ------------------------------
+
+The file compile.sh is an example of how tbprobe can be
+compiled in Linux using gcc.
+
+Rakefile.rb is the ruby version of Makefile. You have to install 'rake'
+to execute it. This is what I use but you don't have to. It is provided
+out of laziness. I should probably remove it.
+
+------------------ COMPILING A STATIC LIBRARY (optional) --------------------
+
+Aaron Becker wrote a Makefile to compile a static library --> libgtb.a
+I just applied this modification from his fork.
+For now, this for Linux only. Type 'make' to compile it.
+Some people may find this approach more convenient since the library
+has to be compiled only once. Of course, this library needs to be included
+at linking time, when you compile your own program
+
+---------------------------- For UCI Authors --------------------------------
+
+Generally, UCI (Universal Chess Interface) GUIs use standard labels for
+Tablebase paths and cache sizes. For instance, NalimovPath and NalimovCache
+are used for the Nalimov tablebases. Therefore, engine authors are strongly
+encouraged (Please!) to follow a common standard to simplify the life of GUI
+developers and users. For that reason, it is suggested to implement as
+parameters: GaviotaTbPath and GaviotaTbCache in their communication with a
+UCI graphical user interface.
+
+-----------------------------------------------------------------------------
+
+Good luck with the tablebases!
+
+Miguel
+
+*****************************************************************************
diff --git a/DroidFish/jni/gtb/sysport/sysport.c b/DroidFish/jni/gtb/sysport/sysport.c
new file mode 100644
index 0000000..af44f17
--- /dev/null
+++ b/DroidFish/jni/gtb/sysport/sysport.c
@@ -0,0 +1,274 @@
+#include
+#include
+#include
+#include "sysport.h"
+
+/**** CLOCK *************************************************************************/
+
+#if defined(USECLOCK)
+
+ #include
+ extern myclock_t myclock(void) {return (myclock_t)clock();}
+ extern myclock_t ticks_per_sec (void) {return CLOCKS_PER_SEC;}
+
+#elif defined(USEWINCLOCK)
+
+ #define WIN32_LEAN_AND_MEAN
+ #include
+ extern myclock_t myclock(void) {return (myclock_t)GetTickCount();}
+ extern myclock_t ticks_per_sec (void) {return 1000;}
+
+
+#elif defined(USELINCLOCK)
+
+ #include
+ extern myclock_t myclock(void)
+ {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (myclock_t)tv.tv_sec * 1000 + (myclock_t)tv.tv_usec/1000;
+ }
+ extern myclock_t ticks_per_sec (void) {return 1000;}
+
+#else
+
+ #error No Clock specified in compilation
+
+#endif
+
+/**** PATH NAMES *************************************************************************/
+
+#if defined(GCCLINUX)
+ extern int isfoldersep (int x) { return x == '/';}
+#elif defined(MVSC)
+ extern int isfoldersep (int x) { return x == '\\' || x == ':';}
+#else
+ extern int isfoldersep (int x) { return x == '/' || x == '\\' || x == ':';}
+#endif
+
+/**** Maximum Files Open *****************************************************************/
+
+#if defined(GCCLINUX)
+ #include
+ #if 0
+ struct rlimit {
+ rlim_t rlim_cur; /* Soft limit */
+ rlim_t rlim_max; /* Hard limit (ceiling for rlim_cur) */
+ };
+ #endif
+ extern int mysys_fopen_max (void)
+ {
+ int ok;
+ struct rlimit rl;
+ ok = 0 == getrlimit(RLIMIT_NOFILE, &rl);
+ if (ok)
+ return (int)rl.rlim_cur;
+ else
+ return FOPEN_MAX;
+ }
+#elif defined(MVSC)
+ extern int mysys_fopen_max (void) { return FOPEN_MAX;}
+#else
+ extern int mysys_fopen_max (void) { return FOPEN_MAX;}
+#endif
+
+
+#if defined(MULTI_THREADED_INTERFACE)
+/**** THREADS ****************************************************************************/
+
+/*
+|
+| POSIX
+|
+\*-------------------------*/
+#if defined (POSIX_THREADS)
+
+#include
+
+extern int /* boolean */
+mythread_create (/*@out@*/ mythread_t *thread, routine_t start_routine, void *arg, /*@out@*/ int *ret_error)
+{
+ const pthread_attr_t *attr = NULL; /* default attributes */
+ int ret;
+ ret = pthread_create (thread, attr, start_routine, arg);
+ *ret_error = ret;
+ return 0 == ret;
+}
+
+extern int /* boolean */
+mythread_join (mythread_t thread)
+{
+ void *p; /* value return from pthread_exit, not used */
+ int ret = pthread_join (thread, &p);
+ return 0 == ret;
+}
+
+extern void
+mythread_exit (void)
+{
+ pthread_exit (NULL);
+}
+
+
+extern const char *
+mythread_create_error (int err)
+{
+ const char *s;
+ switch (err) {
+ case 0 : s = "Success"; break;
+ case EAGAIN: s = "EAGAIN" ; break;
+ case EINVAL: s = "EINVAL" ; break;
+ case EPERM : s = "EPERM" ; break;
+ default : s = "Unknown error"; break;
+ }
+ return s;
+}
+
+extern void mythread_mutex_init (mythread_mutex_t *m) { pthread_mutex_init (m,NULL);}
+extern void mythread_mutex_destroy (mythread_mutex_t *m) { pthread_mutex_destroy(m) ;}
+extern void mythread_mutex_lock (mythread_mutex_t *m) { pthread_mutex_lock (m) ;}
+extern void mythread_mutex_unlock (mythread_mutex_t *m) { pthread_mutex_unlock (m) ;}
+
+#ifdef SPINLOCKS
+extern void mythread_spinx_init (mythread_spinx_t *m) { pthread_spin_init (m,0);} /**/
+extern void mythread_spinx_destroy (mythread_spinx_t *m) { pthread_spin_destroy(m) ;} /**/
+extern void mythread_spinx_lock (mythread_spinx_t *m) { pthread_spin_lock (m) ;} /**/
+extern void mythread_spinx_unlock (mythread_spinx_t *m) { pthread_spin_unlock (m) ;} /**/
+#else
+extern void mythread_spinx_init (mythread_spinx_t *m) { pthread_mutex_init (m,NULL);} /**/
+extern void mythread_spinx_destroy (mythread_spinx_t *m) { pthread_mutex_destroy(m) ;} /**/
+extern void mythread_spinx_lock (mythread_spinx_t *m) { pthread_mutex_lock (m) ;} /**/
+extern void mythread_spinx_unlock (mythread_spinx_t *m) { pthread_mutex_unlock (m) ;} /**/
+#endif
+
+/* semaphores */
+extern int /* boolean */
+mysem_init (mysem_t *sem, unsigned int value)
+ { return -1 != sem_init (sem, 0 /*not shared with processes*/, value);}
+
+extern int /* boolean */
+mysem_wait (mysem_t *sem)
+ { return 0 == sem_wait (sem);}
+
+extern int /* boolean */
+mysem_post (mysem_t *sem)
+ { return 0 == sem_post (sem);}
+
+extern int /* boolean */
+mysem_destroy (mysem_t *sem)
+ { return 0 == sem_destroy (sem);}
+
+/*
+|
+| NT_THREADS
+|
+\*-------------------------*/
+#elif defined(NT_THREADS)
+
+#define WIN32_LEAN_AND_MEAN
+#include
+#include
+
+extern int /* boolean */
+mythread_create (/*@out@*/ mythread_t *thread, routine_t start_routine, void *arg, /*@out@*/ int *ret_error)
+{
+ static unsigned int thread_id;
+ mythread_t t;
+ int /* boolean */ is_ok;
+
+ t = (mythread_t) _beginthreadex (NULL, 0, start_routine, arg, 0, &thread_id );
+ is_ok = (t != 0);
+ *thread = t;
+ *ret_error = is_ok? 0: errno;
+ return is_ok;
+}
+
+extern int /* boolean */
+mythread_join (mythread_t thread)
+{
+ unsigned long int ret;
+ ret = WaitForSingleObject (thread, INFINITE);
+ CloseHandle(thread);
+ return ret != WAIT_FAILED;
+}
+
+extern void
+mythread_exit (void)
+{
+ return;
+}
+
+extern const char *
+mythread_create_error (int err)
+{
+ const char *s;
+ switch (err) {
+ case 0 : s = "Success"; break;
+ case EAGAIN: s = "EAGAIN" ; break;
+ case EINVAL: s = "EINVAL" ; break;
+ case EPERM : s = "EPERM" ; break;
+ default : s = "Unknown error"; break;
+ }
+ return s;
+}
+
+extern void mythread_mutex_init (mythread_mutex_t *m) { *m = CreateMutex(0, FALSE, 0) ;}
+extern void mythread_mutex_destroy (mythread_mutex_t *m) { CloseHandle(*m) ;}
+extern void mythread_mutex_lock (mythread_mutex_t *m) { WaitForSingleObject(*m, INFINITE) ;}
+extern void mythread_mutex_unlock (mythread_mutex_t *m) { ReleaseMutex(*m) ;}
+
+extern void mythread_spinx_init (mythread_spinx_t *m) { InitializeCriticalSection(m) ;} /**/
+extern void mythread_spinx_destroy (mythread_spinx_t *m) { DeleteCriticalSection(m) ;} /**/
+extern void mythread_spinx_lock (mythread_spinx_t *m) { EnterCriticalSection (m) ;} /**/
+extern void mythread_spinx_unlock (mythread_spinx_t *m) { LeaveCriticalSection (m) ;} /**/
+
+/* semaphores */
+extern int /* boolean */
+mysem_init (mysem_t *sem, unsigned int value)
+{
+ mysem_t h =
+ CreateSemaphore(
+ NULL, /* cannot be inherited */
+ (LONG)value,/* Initial Count */
+ 256, /* Maximum Count */
+ NULL /* Name --> NULL, not shared among threads */
+ );
+
+ if (h != NULL) *sem = h;
+
+ return h != NULL;
+}
+
+extern int /* boolean */
+mysem_wait (mysem_t *sem)
+{
+ HANDLE h = *sem;
+ return WAIT_FAILED != WaitForSingleObject (h, INFINITE);
+}
+
+extern int /* boolean */
+mysem_post (mysem_t *sem)
+{
+ HANDLE h = *sem;
+ return 0 != ReleaseSemaphore(h, 1, NULL);
+}
+
+extern int /* boolean */
+mysem_destroy (mysem_t *sem)
+{
+ return 0 != CloseHandle( *sem);
+}
+
+/**** THREADS ****************************************************************************/
+#else
+ #error Definition of threads not present
+#endif
+
+/* MULTI_THREADED_INTERFACE */
+#endif
+
+
+
+
+
+
diff --git a/DroidFish/jni/gtb/sysport/sysport.h b/DroidFish/jni/gtb/sysport/sysport.h
new file mode 100644
index 0000000..15c8ef3
--- /dev/null
+++ b/DroidFish/jni/gtb/sysport/sysport.h
@@ -0,0 +1,237 @@
+#if !defined(H_SYSPOR)
+#define H_SYSPOR
+
+/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
+
+/*
+| Define
+| MONOTHREAD: if SMP functions are not going to be used nor linked with -lpthread
+|
+*/
+
+#if defined(MINGW)
+ #include
+ #if !defined(MVSC)
+ #define MVSC
+ #endif
+#endif
+
+#ifdef _MSC_VER
+ #include
+ #if !defined(MVSC)
+ #define MVSC
+ #endif
+#else
+ #include
+#endif
+
+
+#if defined(__linux__) || defined(__GNUC__)
+ #if !defined(GCCLINUX)
+ #define GCCLINUX
+ #endif
+#endif
+
+#if defined(MINGW)
+ #undef GCCLINUX
+#endif
+
+/*
+|
+| To allow multithreaded functions, MULTI_THREADED_INTERFACE should be defined
+|
+\*--------------------------------------------------------------------------------*/
+
+
+#if defined(CYGWIN)
+ #define USECLOCK
+ #define MULTI_THREADED_INTERFACE
+ #undef NT_THREADS
+ #define POSIX_THREADS
+ #define GCCLINUX_INTEGERS
+#elif defined(MINGW)
+ #define USEWINCLOCK
+ #define MULTI_THREADED_INTERFACE
+ #define NT_THREADS
+ #undef POSIX_THREADS
+ #define MSWINDOWS_INTEGERS
+#elif defined(GCCLINUX)
+ #define USELINCLOCK
+ #define MULTI_THREADED_INTERFACE
+ #undef NT_THREADS
+ #define POSIX_THREADS
+ #define GCCLINUX_INTEGERS
+#elif defined(MVSC)
+ #define USEWINCLOCK
+ #define MULTI_THREADED_INTERFACE
+ #define NT_THREADS
+ #undef POSIX_THREADS
+ #define MSWINDOWS_INTEGERS
+#else
+ #error COMPILER NOT DEFINED
+#endif
+
+#if defined(MONOTHREAD)
+ #undef MULTI_THREADED_INTERFACE
+#endif
+
+
+#if defined(GCCLINUX) || defined(MINGW)
+ #define U64(x) (x##ull)
+#elif defined(MVSC)
+ #define U64(x) (x##ui64)
+#else
+ #error OS not defined properly
+#endif
+
+
+#if defined(GCCLINUX) || defined(MINGW)
+/*
+ typedef unsigned long long int uint64_t;
+ typedef long long int int64_t;
+ typedef unsigned char uint8_t;
+ typedef unsigned short int uint16_t;
+ typedef unsigned int uint32_t;
+*/
+
+ #include
+
+#elif defined(MVSC)
+
+ typedef unsigned char uint8_t;
+ typedef unsigned short int uint16_t;
+ typedef unsigned int uint32_t;
+ typedef unsigned __int64 uint64_t;
+
+ typedef signed char int8_t;
+ typedef short int int16_t;
+ typedef int int32_t;
+ typedef __int64 int64_t;
+
+#else
+ #error OS not defined properly for 64 bit integers
+#endif
+
+
+/*-----------------
+ PATH NAMES
+------------------*/
+
+#if defined(GCCLINUX)
+ #define FOLDERSEP "/"
+#elif defined(MVSC)
+ #define FOLDERSEP "\\"
+#else
+ #define FOLDERSEP "/"
+#endif
+
+/* path names */
+extern int isfoldersep (int x);
+
+/*-----------------
+ FOPEN MAX
+------------------*/
+
+extern int mysys_fopen_max (void);
+
+/*------------
+ TIMER
+-------------*/
+
+typedef int64_t myclock_t;
+
+extern myclock_t myclock(void);
+extern myclock_t ticks_per_sec (void);
+
+#define MYCLOCKS_PER_SEC (ticks_per_sec())
+#define GET_TICK (myclock())
+
+
+/*********************************************************************/
+#if defined(MULTI_THREADED_INTERFACE)
+
+/*------------
+ THREADS
+-------------*/
+
+#if defined (POSIX_THREADS)
+
+ #include
+ #include
+
+ #define THREAD_CALL
+
+ typedef void * thread_return_t;
+ typedef pthread_t mythread_t;
+ typedef thread_return_t (THREAD_CALL *routine_t) (void *);
+ typedef pthread_mutex_t mythread_mutex_t;
+
+ #ifdef SPINLOCKS
+ typedef pthread_spinlock_t mythread_spinx_t;
+ #else
+ typedef pthread_mutex_t mythread_spinx_t;
+ #endif
+
+ typedef sem_t mysem_t;
+
+
+#elif defined(NT_THREADS)
+
+ #define WIN32_LEAN_AND_MEAN
+
+ #include
+ #include
+
+ #define THREAD_CALL __stdcall
+
+ typedef unsigned thread_return_t;
+ typedef HANDLE mythread_t;
+ typedef thread_return_t (THREAD_CALL *routine_t) (void *);
+ typedef HANDLE mythread_mutex_t;
+
+ #define SPINLOCKS
+
+ #ifdef SPINLOCKS
+ typedef CRITICAL_SECTION mythread_spinx_t;
+ #else
+ typedef HANDLE mythread_spinx_t;
+ #endif
+
+ typedef HANDLE mysem_t;
+
+#else
+ #error Definition of threads not present
+#endif
+
+
+
+extern int /*boolean*/ mythread_create (/*@out@*/ mythread_t *thread, routine_t start_routine, void *arg, /*@out@*/ int *ret_error);
+extern int /*boolean*/ mythread_join (mythread_t thread);
+extern void mythread_exit (void);
+extern const char * mythread_create_error (int err);
+
+extern void mythread_mutex_init (mythread_mutex_t *m);
+extern void mythread_mutex_destroy (mythread_mutex_t *m);
+extern void mythread_mutex_lock (mythread_mutex_t *m);
+extern void mythread_mutex_unlock (mythread_mutex_t *m);
+
+extern void mythread_spinx_init (mythread_spinx_t *m); /**/
+extern void mythread_spinx_destroy (mythread_spinx_t *m); /**/
+extern void mythread_spinx_lock (mythread_spinx_t *m); /**/
+extern void mythread_spinx_unlock (mythread_spinx_t *m); /**/
+
+/* semaphores*/
+extern int /*boolean*/ mysem_init (mysem_t *sem, unsigned int value);
+extern int /*boolean*/ mysem_wait (mysem_t *sem);
+extern int /*boolean*/ mysem_post (mysem_t *sem);
+extern int /*boolean*/ mysem_destroy (mysem_t *sem);
+#endif
+
+
+
+
+
+/* end MULTI_THREADED_INTERFACE*/
+#endif
+
+/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
diff --git a/DroidFish/jni/gtb/version.h b/DroidFish/jni/gtb/version.h
new file mode 100644
index 0000000..4a7b0ec
--- /dev/null
+++ b/DroidFish/jni/gtb/version.h
@@ -0,0 +1,2 @@
+#define VERSION "0.4.3"
+
diff --git a/DroidFish/jni/gtb/version.txt b/DroidFish/jni/gtb/version.txt
new file mode 100644
index 0000000..17b2ccd
--- /dev/null
+++ b/DroidFish/jni/gtb/version.txt
@@ -0,0 +1 @@
+0.4.3
diff --git a/DroidFish/res/values/strings.xml b/DroidFish/res/values/strings.xml
index 3b997ee..27075b8 100644
--- a/DroidFish/res/values/strings.xml
+++ b/DroidFish/res/values/strings.xml
@@ -188,6 +188,7 @@ combined with the very strong Stockfish 2.2.2 chess engine.\n\
* Extensive PGN support\n\
* Adjustable playing strength\n\
* Third party UCI engines\n\
+* Gaviota endgame tablebases\n\
\n\
Hints\n\
* In game mode, long press chess board to activate copy/paste menu.\n\
@@ -243,6 +244,11 @@ DroidFish can use third party UCI engines. To use this feature:\n\
Note! The binaries must be compiled for Android.\n\
2. From the menu, choose Select Chess Engine and select the engine to use.\n\
\n\
+Gaviota endgame tablebases\n\
+To use Gaviota endgame tablebases:\n\
+1. Copy .gtb files to the DroidFish/gtb directory on the SD card.\n\
+2. Use the Endgame Tablebases preferences screen to control how the tablebases are used.\n\
+\n\
License\n\
GNU GPL v3\n\
\n\
@@ -251,6 +257,11 @@ GNU GPL v3\n\
* Droidfish is developed by Peter Österlund.\n\
* User interface improvements by Aaro Korhonen.\n\
\n\
+* Gaviota Tablebases Probing Code API, Copyright \u00a9 2010 Miguel A. Ballicora.\n\
+* LZMA compression by Igor Pavlov.\n\
+* ZLIB compression, Copyright \u00a9 1995-2005 Jean-loup Gailly and Mark Adler.\n\
+* LZF compression, Copyright \u00a9 2000-2007 Marc Alexander Lehmann.\n\
+\n\
Translations\n\
* German translation by Uwe Walschus.\n\
* Spanish translation by Amador Cuesta.\n\
@@ -503,6 +514,7 @@ you are not actively using the program.\
Arrow 5
Arrow 6
Square Labels
+ Tablebase hints
Move List
Current Move
Other
@@ -546,4 +558,15 @@ you are not actively using the program.\
Include information about draw and resign actions
Clock
Include time information for each move
+ Endgame Tablebases
+ Show Hints
+ When touching a piece, show EGTB value for all possible moves by that piece
+ Edit Board Hints
+ When touching a piece, show EGTB value for all possible alternate positions of that piece
+ Probe at Root
+ Filter out non-optimal moves before starting search
+ Engine Probing
+ Enable EGTB probing in engine, when supported. Takes effect next time engine is started
+ GTB Directory
+ Directory where Gaviota tablebases are installed. Leave blank to use default directory
diff --git a/DroidFish/res/xml/preferences.xml b/DroidFish/res/xml/preferences.xml
index 70eab2e..ce8aa87 100644
--- a/DroidFish/res/xml/preferences.xml
+++ b/DroidFish/res/xml/preferences.xml
@@ -231,7 +231,12 @@
android:title="@string/prefs_color_squareLabel_title"
android:defaultValue="#FFFF0000">
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DroidFish/src/org/petero/droidfish/ChessBoard.java b/DroidFish/src/org/petero/droidfish/ChessBoard.java
index f631466..2b16e9d 100644
--- a/DroidFish/src/org/petero/droidfish/ChessBoard.java
+++ b/DroidFish/src/org/petero/droidfish/ChessBoard.java
@@ -53,6 +53,17 @@ public class ChessBoard extends View {
List moveHints;
+ /** Decoration for a square. Currently the only possible decoration is a number. */
+ public final static class SquareDecoration {
+ int sq;
+ int number;
+ public SquareDecoration(int sq, int number) {
+ this.sq = sq;
+ this.number = number;
+ }
+ }
+ private ArrayList decorations;
+
protected Paint darkPaint;
protected Paint brightPaint;
private Paint selectedSquarePaint;
@@ -60,6 +71,7 @@ public class ChessBoard extends View {
private Paint whitePiecePaint;
private Paint blackPiecePaint;
private Paint labelPaint;
+ private Paint decorationPaint;
private ArrayList moveMarkPaint;
public ChessBoard(Context context, AttributeSet attrs) {
@@ -93,6 +105,9 @@ public class ChessBoard extends View {
labelPaint = new Paint();
labelPaint.setAntiAlias(true);
+
+ decorationPaint = new Paint();
+ decorationPaint.setAntiAlias(true);
moveMarkPaint = new ArrayList();
for (int i = 0; i < 6; i++) {
@@ -122,6 +137,7 @@ public class ChessBoard extends View {
whitePiecePaint.setColor(ct.getColor(ColorTheme.BRIGHT_PIECE));
blackPiecePaint.setColor(ct.getColor(ColorTheme.DARK_PIECE));
labelPaint.setColor(ct.getColor(ColorTheme.SQUARE_LABEL));
+ decorationPaint.setColor(ct.getColor(ColorTheme.DECORATION));
for (int i = 0; i < 6; i++)
moveMarkPaint.get(i).setColor(ct.getColor(ColorTheme.ARROW_0 + i));
@@ -130,7 +146,7 @@ public class ChessBoard extends View {
private Handler handlerTimer = new Handler();
- final class AnimInfo {
+ private final class AnimInfo {
AnimInfo() { startTime = -1; }
boolean paused;
long posHash; // Position the animation is valid for
@@ -183,7 +199,7 @@ public class ChessBoard extends View {
drawPiece(canvas, xCrd, yCrd, piece);
}
}
- AnimInfo anim = new AnimInfo();
+ private AnimInfo anim = new AnimInfo();
/**
* Set up move animation. The animation will start the next time setPosition is called.
@@ -191,7 +207,7 @@ public class ChessBoard extends View {
* @param move The move leading to the target position.
* @param forward True if forward direction, false for undo move.
*/
- public void setAnimMove(Position sourcePos, Move move, boolean forward) {
+ public final void setAnimMove(Position sourcePos, Move move, boolean forward) {
anim.startTime = -1;
anim.paused = true; // Animation starts at next position update
if (forward) {
@@ -366,6 +382,7 @@ public class ChessBoard extends View {
blackPiecePaint.setTextSize(sqSize);
whitePiecePaint.setTextSize(sqSize);
labelPaint.setTextSize(sqSize/4.0f);
+ decorationPaint.setTextSize(sqSize/3.0f);
computeOrigin(width, height);
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
@@ -406,8 +423,10 @@ public class ChessBoard extends View {
cursorSquarePaint.setStrokeWidth(sqSize/(float)16);
canvas.drawRect(x0, y0, x0 + sqSize, y0 + sqSize, cursorSquarePaint);
}
- if (!animActive)
+ if (!animActive) {
drawMoveHints(canvas);
+ drawDecorations(canvas);
+ }
anim.draw(canvas);
// long t1 = System.currentTimeMillis();
@@ -511,8 +530,7 @@ public class ChessBoard extends View {
private final void drawLabel(Canvas canvas, int xCrd, int yCrd, boolean right,
boolean bottom, char c) {
- String s = "";
- s += c;
+ String s = Character.toString(c);
if (labelBounds == null) {
labelBounds = new Rect();
labelPaint.getTextBounds("f", 0, 1, labelBounds);
@@ -556,7 +574,7 @@ public class ChessBoard extends View {
return sq;
}
- final private boolean myColor(int piece) {
+ private final boolean myColor(int piece) {
return (piece != Piece.EMPTY) && (Piece.isWhite(piece) == pos.whiteMove);
}
@@ -667,4 +685,48 @@ public class ChessBoard extends View {
invalidate();
}
}
+
+ public final void setSquareDecorations(ArrayList decorations) {
+ boolean equal = false;
+ if ((this.decorations == null) || (decorations == null)) {
+ equal = this.decorations == decorations;
+ } else {
+ equal = this.decorations.equals(decorations);
+ }
+ if (!equal) {
+ this.decorations = decorations;
+ invalidate();
+ }
+ }
+
+ private final void drawDecorations(Canvas canvas) {
+ if (decorations == null)
+ return;
+ for (SquareDecoration sd : decorations) {
+ int sq = sd.sq;
+ if ((sd.sq < 0) || (sd.sq >= 64))
+ continue;
+ int xCrd = getXCrd(Position.getX(sq));
+ int yCrd = getYCrd(Position.getY(sq));
+
+ int num = sd.number;
+ String s;
+ if (num > 0)
+ s = "+" + String.valueOf(num);
+ else if (num < 0)
+ s = String.valueOf(num);
+ else
+ s = "0";
+
+ Rect bounds = new Rect();
+ decorationPaint.getTextBounds(s, 0, s.length(), bounds);
+ xCrd += (sqSize - (bounds.left + bounds.right)) / 2;
+ yCrd += (sqSize - (bounds.top + bounds.bottom)) / 2;
+ canvas.drawText(s, xCrd, yCrd, decorationPaint);
+ }
+ }
+
+ public final int getSelectedSquare() {
+ return selectedSquare;
+ }
}
diff --git a/DroidFish/src/org/petero/droidfish/ColorTheme.java b/DroidFish/src/org/petero/droidfish/ColorTheme.java
index 823c696..82e2061 100644
--- a/DroidFish/src/org/petero/droidfish/ColorTheme.java
+++ b/DroidFish/src/org/petero/droidfish/ColorTheme.java
@@ -46,13 +46,14 @@ public class ColorTheme {
final static int ARROW_4 = 11;
final static int ARROW_5 = 12;
final static int SQUARE_LABEL = 13;
- private final static int numColors = 14;
+ final static int DECORATION = 14;
+ private final static int numColors = 15;
private int colorTable[] = new int[numColors];
private static final String[] prefNames = {
"darkSquare", "brightSquare", "selectedSquare", "cursorSquare", "darkPiece", "brightPiece", "currentMove",
- "arrow0", "arrow1", "arrow2", "arrow3", "arrow4", "arrow5", "squareLabel"
+ "arrow0", "arrow1", "arrow2", "arrow3", "arrow4", "arrow5", "squareLabel", "decoration"
};
private static final String prefPrefix = "color_";
@@ -61,19 +62,23 @@ public class ColorTheme {
private final static String themeColors[][] = {
{
"#FF808080", "#FFBEBE5A", "#FFFF0000", "#FF00FF00", "#FF000000", "#FFFFFFFF", "#FF888888",
- "#A01F1FFF", "#A0FF1F1F", "#501F1FFF", "#50FF1F1F", "#1E1F1FFF", "#28FF1F1F", "#FFFF0000"
+ "#A01F1FFF", "#A0FF1F1F", "#501F1FFF", "#50FF1F1F", "#1E1F1FFF", "#28FF1F1F", "#FFFF0000",
+ "#FF9F9F66"
},
{
"#FF77A26D", "#FFC8C365", "#FFFFFF00", "#FF00FF00", "#FF202020", "#FFFFFFCC", "#FF6B9262",
- "#A01F1FFF", "#A0FF1F1F", "#501F1FFF", "#50FF1F1F", "#1E1F1FFF", "#28FF1F1F", "#FFFF0000"
+ "#A01F1FFF", "#A0FF1F1F", "#501F1FFF", "#50FF1F1F", "#1E1F1FFF", "#28FF1F1F", "#FFFF0000",
+ "#FF808080"
},
{
"#FF83A5D2", "#FFFFFFFA", "#FF3232D1", "#FF5F5FFD", "#FF282828", "#FFF0F0F0", "#FF3333FF",
- "#A01F1FFF", "#A01FFF1F", "#501F1FFF", "#501FFF1F", "#1E1F1FFF", "#281FFF1F", "#FFFF0000"
+ "#A01F1FFF", "#A01FFF1F", "#501F1FFF", "#501FFF1F", "#1E1F1FFF", "#281FFF1F", "#FFFF0000",
+ "#FF808080"
},
{
"#FF666666", "#FFDDDDDD", "#FFFF0000", "#FF0000FF", "#FF000000", "#FFFFFFFF", "#FF888888",
- "#A01F1FFF", "#A0FF1F1F", "#501F1FFF", "#50FF1F1F", "#1E1F1FFF", "#28FF1F1F", "#FFFF0000"
+ "#A01F1FFF", "#A0FF1F1F", "#501F1FFF", "#50FF1F1F", "#1E1F1FFF", "#28FF1F1F", "#FFFF0000",
+ "#FF909090"
}
};
diff --git a/DroidFish/src/org/petero/droidfish/DroidFish.java b/DroidFish/src/org/petero/droidfish/DroidFish.java
index f8fadf1..ccaba57 100644
--- a/DroidFish/src/org/petero/droidfish/DroidFish.java
+++ b/DroidFish/src/org/petero/droidfish/DroidFish.java
@@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.TreeMap;
+import org.petero.droidfish.ChessBoard.SquareDecoration;
import org.petero.droidfish.activities.CPUWarning;
import org.petero.droidfish.activities.EditBoard;
import org.petero.droidfish.activities.EditPGNLoad;
@@ -39,10 +40,12 @@ import org.petero.droidfish.engine.EngineUtil;
import org.petero.droidfish.gamelogic.DroidChessController;
import org.petero.droidfish.gamelogic.ChessParseError;
import org.petero.droidfish.gamelogic.Move;
+import org.petero.droidfish.gamelogic.Pair;
import org.petero.droidfish.gamelogic.Position;
import org.petero.droidfish.gamelogic.TextIO;
import org.petero.droidfish.gamelogic.PgnToken;
import org.petero.droidfish.gamelogic.GameTree.Node;
+import org.petero.droidfish.gtb.Probe;
import android.app.Activity;
import android.app.AlertDialog;
@@ -163,8 +166,10 @@ public class DroidFish extends Activity implements GUIInterface {
private final static String bookDir = "DroidFish";
private final static String pgnDir = "DroidFish" + File.separator + "pgn";
private final static String engineDir = "DroidFish" + File.separator + "uci";
+ private final static String gtbDefaultDir = "DroidFish" + File.separator + "gtb";
private BookOptions bookOptions = new BookOptions();
private PGNOptions pgnOptions = new PGNOptions();
+ private EGTBOptions egtbOptions = new EGTBOptions();
private long lastVisibleMillis; // Time when GUI became invisible. 0 if currently visible.
private long lastComputationMillis; // Time when engine last showed that it was computing.
@@ -235,6 +240,7 @@ public class DroidFish extends Activity implements GUIInterface {
new File(extDir + sep + bookDir).mkdirs();
new File(extDir + sep + pgnDir).mkdirs();
new File(extDir + sep + engineDir).mkdirs();
+ new File(extDir + sep + gtbDefaultDir).mkdirs();
}
private String getPgnIntent() {
@@ -404,6 +410,7 @@ public class DroidFish extends Activity implements GUIInterface {
Move m = cb.mousePressed(sq);
if (m != null)
ctrl.makeHumanMove(m);
+ setEgtbHints(cb.getSelectedSquare());
}
}
});
@@ -416,9 +423,9 @@ public class DroidFish extends Activity implements GUIInterface {
public void onTrackballEvent(MotionEvent event) {
if (ctrl.humansTurn()) {
Move m = cb.handleTrackballEvent(event);
- if (m != null) {
+ if (m != null)
ctrl.makeHumanMove(m);
- }
+ setEgtbHints(cb.getSelectedSquare());
}
}
});
@@ -609,6 +616,20 @@ public class DroidFish extends Activity implements GUIInterface {
bookOptions.random = (settings.getInt("bookRandom", 500) - 500) * (3.0 / 500);
setBookOptions();
+ egtbOptions.hints = settings.getBoolean("tbHints", false);
+ egtbOptions.hintsEdit = settings.getBoolean("tbHintsEdit", false);
+ egtbOptions.rootProbe = settings.getBoolean("tbRootProbe", false);
+ egtbOptions.engineProbe = settings.getBoolean("tbEngineProbe", true);
+ String gtbPath = settings.getString("gtbPath", "");
+ if (gtbPath.length() == 0) {
+ File extDir = Environment.getExternalStorageDirectory();
+ String sep = File.separator;
+ gtbPath = extDir.getAbsolutePath() + sep + gtbDefaultDir;
+ }
+ egtbOptions.gtbPath = gtbPath;
+ setEgtbOptions();
+ setEgtbHints(cb.getSelectedSquare());
+
updateThinkingInfo();
pgnOptions.view.variations = settings.getBoolean("viewVariations", true);
@@ -679,6 +700,29 @@ public class DroidFish extends Activity implements GUIInterface {
ctrl.setBookOptions(options);
}
+ private final void setEgtbOptions() {
+ ctrl.setEgtbOptions(new EGTBOptions(egtbOptions));
+ }
+
+ private final void setEgtbHints(int sq) {
+ if (!egtbOptions.hints || (sq < 0)) {
+ cb.setSquareDecorations(null);
+ return;
+ }
+
+ Probe gtbProbe = Probe.getInstance();
+ ArrayList> x = gtbProbe.movePieceProbe(cb.pos, sq);
+ if (x == null) {
+ cb.setSquareDecorations(null);
+ return;
+ }
+
+ ArrayList sd = new ArrayList();
+ for (Pair p : x)
+ sd.add(new SquareDecoration(p.first, p.second));
+ cb.setSquareDecorations(sd);
+ }
+
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.options_menu, menu);
@@ -841,6 +885,7 @@ public class DroidFish extends Activity implements GUIInterface {
@Override
public void setSelection(int sq) {
cb.setSelection(sq);
+ setEgtbHints(sq);
}
@Override
@@ -940,12 +985,13 @@ public class DroidFish extends Activity implements GUIInterface {
}
@Override
- public void setPosition(Position pos, String variantInfo, List variantMoves) {
+ public void setPosition(Position pos, String variantInfo, ArrayList variantMoves) {
variantStr = variantInfo;
this.variantMoves = variantMoves;
cb.setPosition(pos);
setBoardFlip();
updateThinkingInfo();
+ setEgtbHints(cb.getSelectedSquare());
}
private String thinkingStr1 = "";
@@ -953,12 +999,12 @@ public class DroidFish extends Activity implements GUIInterface {
private String bookInfoStr = "";
private String variantStr = "";
private ArrayList> pvMoves = new ArrayList>();
- private List bookMoves = null;
- private List variantMoves = null;
+ private ArrayList bookMoves = null;
+ private ArrayList variantMoves = null;
@Override
public void setThinkingInfo(String pvStr, String statStr, String bookInfo,
- ArrayList> pvMoves, List bookMoves) {
+ ArrayList> pvMoves, ArrayList bookMoves) {
thinkingStr1 = pvStr;
thinkingStr2 = statStr;
bookInfoStr = bookInfo;
diff --git a/DroidFish/src/org/petero/droidfish/EGTBOptions.java b/DroidFish/src/org/petero/droidfish/EGTBOptions.java
new file mode 100644
index 0000000..73f902d
--- /dev/null
+++ b/DroidFish/src/org/petero/droidfish/EGTBOptions.java
@@ -0,0 +1,44 @@
+package org.petero.droidfish;
+
+/** Endgame tablebase probing options. */
+public final class EGTBOptions {
+ public boolean hints; // Hints when playing/analyzing
+ public boolean hintsEdit; // Hints in "edit board" mode
+ public boolean rootProbe; // Only search optimal moves at root
+ public boolean engineProbe; // Let engine use EGTB
+ public String gtbPath; // GTB directory path
+
+ public EGTBOptions() {
+ hints = false;
+ hintsEdit = false;
+ rootProbe = false;
+ engineProbe = false;
+ gtbPath = "";
+ }
+
+ public EGTBOptions(EGTBOptions other) {
+ hints = other.hints;
+ hintsEdit = other.hintsEdit;
+ rootProbe = other.rootProbe;
+ engineProbe = other.engineProbe;
+ gtbPath = other.gtbPath;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if ((o == null) || (o.getClass() != this.getClass()))
+ return false;
+ EGTBOptions other = (EGTBOptions)o;
+
+ return ((hints == other.hints) &&
+ (hintsEdit == other.hintsEdit) &&
+ (rootProbe == other.rootProbe) &&
+ (engineProbe == other.engineProbe) &&
+ gtbPath.equals(other.gtbPath));
+ }
+
+ @Override
+ public int hashCode() {
+ return 0;
+ }
+}
diff --git a/DroidFish/src/org/petero/droidfish/GUIInterface.java b/DroidFish/src/org/petero/droidfish/GUIInterface.java
index 3126110..cbfa105 100644
--- a/DroidFish/src/org/petero/droidfish/GUIInterface.java
+++ b/DroidFish/src/org/petero/droidfish/GUIInterface.java
@@ -19,7 +19,6 @@
package org.petero.droidfish;
import java.util.ArrayList;
-import java.util.List;
import org.petero.droidfish.gamelogic.Game;
import org.petero.droidfish.gamelogic.Move;
@@ -31,7 +30,7 @@ import android.content.Context;
public interface GUIInterface {
/** Update the displayed board position. */
- public void setPosition(Position pos, String variantInfo, List variantMoves);
+ public void setPosition(Position pos, String variantInfo, ArrayList variantMoves);
/** Mark square sq as selected. Set to -1 to clear selection. */
public void setSelection(int sq);
@@ -55,7 +54,7 @@ public interface GUIInterface {
/** Update the computer thinking information. */
public void setThinkingInfo(String pvStr, String statStr, String bookInfo,
- ArrayList> pvMoves, List bookMoves);
+ ArrayList> pvMoves, ArrayList bookMoves);
/** Ask what to promote a pawn to. Should call reportPromotePiece() when done. */
public void requestPromotePiece();
diff --git a/DroidFish/src/org/petero/droidfish/activities/ChessBoardEdit.java b/DroidFish/src/org/petero/droidfish/activities/ChessBoardEdit.java
index 8b8ebd0..aff4a2b 100644
--- a/DroidFish/src/org/petero/droidfish/activities/ChessBoardEdit.java
+++ b/DroidFish/src/org/petero/droidfish/activities/ChessBoardEdit.java
@@ -58,7 +58,7 @@ public class ChessBoardEdit extends ChessBoard {
y0 = (height - (sqSize * 10 + gap)) / 2;
}
- int extraPieces(int x, int y) {
+ private final int extraPieces(int x, int y) {
if (y == -1) { // White pieces
switch (x) {
case 0: return Piece.WKING;
diff --git a/DroidFish/src/org/petero/droidfish/activities/EditBoard.java b/DroidFish/src/org/petero/droidfish/activities/EditBoard.java
index c6850c4..2cf5d32 100644
--- a/DroidFish/src/org/petero/droidfish/activities/EditBoard.java
+++ b/DroidFish/src/org/petero/droidfish/activities/EditBoard.java
@@ -18,21 +18,28 @@
package org.petero.droidfish.activities;
+import java.util.ArrayList;
+
import org.petero.droidfish.ChessBoard;
import org.petero.droidfish.R;
+import org.petero.droidfish.ChessBoard.SquareDecoration;
import org.petero.droidfish.gamelogic.ChessParseError;
import org.petero.droidfish.gamelogic.Move;
+import org.petero.droidfish.gamelogic.Pair;
import org.petero.droidfish.gamelogic.Piece;
import org.petero.droidfish.gamelogic.Position;
import org.petero.droidfish.gamelogic.TextIO;
+import org.petero.droidfish.gtb.Probe;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
+import android.preference.PreferenceManager;
import android.text.ClipboardManager;
import android.view.GestureDetector;
import android.view.KeyEvent;
@@ -53,12 +60,17 @@ public class EditBoard extends Activity {
private Button okButton;
private Button cancelButton;
+ boolean egtbHints;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initUI();
+ SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
+ egtbHints = settings.getBoolean("tbHintsEdit", false);
+
Intent i = getIntent();
Position pos;
try {
@@ -78,7 +90,7 @@ public class EditBoard extends Activity {
cb.cursorY = oldCB.cursorY;
cb.cursorVisible = oldCB.cursorVisible;
cb.setPosition(oldCB.pos);
- cb.setSelection(oldCB.selectedSquare);
+ setSelection(oldCB.selectedSquare);
status.setText(statusStr);
}
@@ -128,6 +140,7 @@ public class EditBoard extends Activity {
Move m = cb.mousePressed(sq);
if (m != null)
doMove(m);
+ setEgtbHints(cb.getSelectedSquare());
}
});
cb.setOnTouchListener(new OnTouchListener() {
@@ -138,9 +151,9 @@ public class EditBoard extends Activity {
cb.setOnTrackballListener(new ChessBoard.OnTrackballListener() {
public void onTrackballEvent(MotionEvent event) {
Move m = cb.handleTrackballEvent(event);
- if (m != null) {
+ if (m != null)
doMove(m);
- }
+ setEgtbHints(cb.getSelectedSquare());
}
});
cb.setOnLongClickListener(new OnLongClickListener() {
@@ -152,10 +165,34 @@ public class EditBoard extends Activity {
});
}
+ private final void setSelection(int sq) {
+ cb.setSelection(sq);
+ setEgtbHints(sq);
+ }
+
+ private final void setEgtbHints(int sq) {
+ if (!egtbHints || (sq < 0)) {
+ cb.setSquareDecorations(null);
+ return;
+ }
+
+ Probe gtbProbe = Probe.getInstance();
+ ArrayList> x = gtbProbe.relocatePieceProbe(cb.pos, sq);
+ if (x == null) {
+ cb.setSquareDecorations(null);
+ return;
+ }
+
+ ArrayList sd = new ArrayList();
+ for (Pair p : x)
+ sd.add(new SquareDecoration(p.first, p.second));
+ cb.setSquareDecorations(sd);
+ }
+
private void doMove(Move m) {
if (m.to < 0) {
if ((m.from < 0) || (cb.pos.getPiece(m.from) == Piece.EMPTY)) {
- cb.setSelection(m.to);
+ setSelection(m.to);
return;
}
}
@@ -172,9 +209,9 @@ public class EditBoard extends Activity {
pos.setPiece(m.from, Piece.EMPTY);
cb.setPosition(pos);
if (m.from >= 0)
- cb.setSelection(-1);
+ setSelection(-1);
else
- cb.setSelection(m.from);
+ setSelection(m.from);
checkValid();
}
@@ -263,13 +300,13 @@ public class EditBoard extends Activity {
switch (item) {
case 0: // Edit side to move
showDialog(SIDE_DIALOG);
- cb.setSelection(-1);
+ setSelection(-1);
checkValid();
break;
case 1: { // Clear board
Position pos = new Position();
cb.setPosition(pos);
- cb.setSelection(-1);
+ setSelection(-1);
checkValid();
break;
}
@@ -277,7 +314,7 @@ public class EditBoard extends Activity {
try {
Position pos = TextIO.readFEN(TextIO.startPosFEN);
cb.setPosition(pos);
- cb.setSelection(-1);
+ setSelection(-1);
checkValid();
} catch (ChessParseError e) {
}
@@ -286,19 +323,19 @@ public class EditBoard extends Activity {
case 3: // Edit castling flags
removeDialog(CASTLE_DIALOG);
showDialog(CASTLE_DIALOG);
- cb.setSelection(-1);
+ setSelection(-1);
checkValid();
break;
case 4: // Edit en passant file
removeDialog(EP_DIALOG);
showDialog(EP_DIALOG);
- cb.setSelection(-1);
+ setSelection(-1);
checkValid();
break;
case 5: // Edit move counters
removeDialog(MOVCNT_DIALOG);
showDialog(MOVCNT_DIALOG);
- cb.setSelection(-1);
+ setSelection(-1);
checkValid();
break;
case 6: { // Copy position
@@ -306,7 +343,7 @@ public class EditBoard extends Activity {
String fen = TextIO.toFEN(cb.pos) + "\n";
ClipboardManager clipboard = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
clipboard.setText(fen);
- cb.setSelection(-1);
+ setSelection(-1);
break;
}
case 7: { // Paste position
@@ -321,7 +358,7 @@ public class EditBoard extends Activity {
cb.setPosition(e.pos);
Toast.makeText(getApplicationContext(), getParseErrString(e), Toast.LENGTH_SHORT).show();
}
- cb.setSelection(-1);
+ setSelection(-1);
checkValid();
}
break;
diff --git a/DroidFish/src/org/petero/droidfish/book/BookOptions.java b/DroidFish/src/org/petero/droidfish/book/BookOptions.java
index d175a8f..18bfc08 100644
--- a/DroidFish/src/org/petero/droidfish/book/BookOptions.java
+++ b/DroidFish/src/org/petero/droidfish/book/BookOptions.java
@@ -19,7 +19,7 @@
package org.petero.droidfish.book;
/** Settings controlling opening book usage */
-public class BookOptions {
+public final class BookOptions {
public String filename = "";
public int maxLength = 1000000;
diff --git a/DroidFish/src/org/petero/droidfish/engine/DroidComputerPlayer.java b/DroidFish/src/org/petero/droidfish/engine/DroidComputerPlayer.java
index 4b22e74..caeb84a 100644
--- a/DroidFish/src/org/petero/droidfish/engine/DroidComputerPlayer.java
+++ b/DroidFish/src/org/petero/droidfish/engine/DroidComputerPlayer.java
@@ -23,6 +23,7 @@ import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
+import org.petero.droidfish.EGTBOptions;
import org.petero.droidfish.book.BookOptions;
import org.petero.droidfish.book.DroidBook;
import org.petero.droidfish.gamelogic.Move;
@@ -33,6 +34,8 @@ import org.petero.droidfish.gamelogic.SearchListener;
import org.petero.droidfish.gamelogic.TextIO;
import org.petero.droidfish.gamelogic.UndoInfo;
import org.petero.droidfish.gamelogic.SearchListener.PvInfo;
+import org.petero.droidfish.gtb.Probe;
+import org.petero.droidfish.gtb.Probe.ProbeResult;
import android.content.Context;
@@ -45,6 +48,8 @@ public class DroidComputerPlayer {
private final Context context;
private final SearchListener listener;
private final DroidBook book;
+ private EGTBOptions egtbOptions;
+ private final Probe gtbProbe;
/** Set when "ucinewgame" needs to be sent. */
private boolean newGame = false;
@@ -118,6 +123,7 @@ public class DroidComputerPlayer {
long[] posHashList; // For draw decision after completed search
int posHashListSize; // For draw decision after completed search
+ ArrayList searchMoves; // Moves to search, or null to search all moves
/**
* Create a request to start an engine.
@@ -238,6 +244,8 @@ public class DroidComputerPlayer {
this.context = context;
this.listener = listener;
book = DroidBook.getInstance();
+ egtbOptions = new EGTBOptions();
+ gtbProbe = Probe.getInstance();
engineState = new EngineState();
searchRequest = null;
}
@@ -264,12 +272,21 @@ public class DroidComputerPlayer {
public final void setBookOptions(BookOptions options) {
book.setOptions(options);
}
+
+ public final void setEgtbOptions(EGTBOptions options) {
+ egtbOptions = options;
+ gtbProbe.setPath(options.gtbPath);
+ }
/** Return all book moves, both as a formatted string and as a list of moves. */
public final Pair> getBookHints(Position pos) {
return book.getAllBookMoves(pos);
}
+ public final ProbeResult egtbProbe(Position pos) {
+ return gtbProbe.probeHard(pos);
+ }
+
/** Get engine reported name. */
public final synchronized String getEngineName() {
return engineName;
@@ -319,6 +336,22 @@ public class DroidComputerPlayer {
handleQueue();
}
+ /** Decide what moves to search. Filters out non-optimal moves if tablebases are used. */
+ private final ArrayList movesToSearch(SearchRequest sr) {
+ ArrayList moves = null;
+ if (egtbOptions.rootProbe) {
+ moves = gtbProbe.findOptimal(sr.currPos);
+ }
+ if (moves != null) {
+ sr.searchMoves = moves;
+ } else {
+ moves = new MoveGen().pseudoLegalMoves(sr.currPos);
+ moves = MoveGen.removeIllegal(sr.currPos, moves);
+ sr.searchMoves = null;
+ }
+ return moves;
+ }
+
/**
* Start a search. Search result is returned to the search listener object.
* The result can be a valid move string, in which case the move is played
@@ -352,9 +385,8 @@ public class DroidComputerPlayer {
}
}
- // If only one legal move, play it without searching
- ArrayList moves = new MoveGen().pseudoLegalMoves(sr.currPos);
- moves = MoveGen.removeIllegal(sr.currPos, moves);
+ // If only one move to search, play it without searching
+ ArrayList moves = movesToSearch(sr);
if (moves.size() == 0) {
listener.notifySearchResult(sr.searchId, "", null); // User set up a position where computer has no valid moves.
return;
@@ -381,8 +413,7 @@ public class DroidComputerPlayer {
stopSearch();
// If no legal moves, there is nothing to analyze
- ArrayList moves = new MoveGen().pseudoLegalMoves(sr.currPos);
- moves = MoveGen.removeIllegal(sr.currPos, moves);
+ ArrayList moves = movesToSearch(sr);
if (moves.size() == 0)
return;
@@ -485,7 +516,7 @@ public class DroidComputerPlayer {
engineState.searchId = searchRequest.searchId;
- // Reduce remaining time there was an engine delay
+ // Reduce remaining time if there was an engine delay
if (isSearch) {
long now = System.currentTimeMillis();
int delay = (int)(now - searchRequest.startTime);
@@ -530,6 +561,13 @@ public class DroidComputerPlayer {
goStr.append(String.format(" movestogo %d", sr.movesToGo));
if (sr.ponderMove != null)
goStr.append(" ponder");
+ if (sr.searchMoves != null) {
+ goStr.append(" searchmoves");
+ for (Move m : sr.searchMoves) {
+ goStr.append(' ');
+ goStr.append(TextIO.moveToUCIString(m));
+ }
+ }
uciEngine.writeLineToEngine(goStr.toString());
engineState.setState((sr.ponderMove == null) ? MainState.SEARCH : MainState.PONDER);
} else { // Analyze
@@ -547,7 +585,16 @@ public class DroidComputerPlayer {
uciEngine.writeLineToEngine(posStr.toString());
uciEngine.setOption("UCI_AnalyseMode", true);
uciEngine.setOption("Threads", sr.engineThreads > 0 ? sr.engineThreads : numCPUs);
- uciEngine.writeLineToEngine("go infinite");
+ StringBuilder goStr = new StringBuilder(96);
+ goStr.append("go infinite");
+ if (sr.searchMoves != null) {
+ goStr.append(" searchmoves");
+ for (Move m : sr.searchMoves) {
+ goStr.append(' ');
+ goStr.append(TextIO.moveToUCIString(m));
+ }
+ }
+ uciEngine.writeLineToEngine(goStr.toString());
engineState.setState(MainState.ANALYZE);
}
}
@@ -624,7 +671,7 @@ public class DroidComputerPlayer {
switch (engineState.state) {
case READ_OPTIONS: {
if (readUCIOption(uci, s)) {
- uci.initOptions();
+ uci.initOptions(egtbOptions);
uci.writeLineToEngine("ucinewgame");
uci.writeLineToEngine("isready");
engineState.setState(MainState.WAIT_READY);
diff --git a/DroidFish/src/org/petero/droidfish/engine/ExternalEngine.java b/DroidFish/src/org/petero/droidfish/engine/ExternalEngine.java
index c531553..b4c4d67 100644
--- a/DroidFish/src/org/petero/droidfish/engine/ExternalEngine.java
+++ b/DroidFish/src/org/petero/droidfish/engine/ExternalEngine.java
@@ -27,6 +27,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.channels.FileChannel;
+import org.petero.droidfish.EGTBOptions;
import org.petero.droidfish.R;
import android.content.Context;
@@ -160,9 +161,13 @@ public class ExternalEngine extends UCIEngineBase {
/** @inheritDoc */
@Override
- public void initOptions() {
- super.initOptions();
+ public void initOptions(EGTBOptions egtbOptions) {
+ super.initOptions(egtbOptions);
setOption("Hash", 16);
+ if (egtbOptions.engineProbe) {
+ setOption("GaviotaTbPath", egtbOptions.gtbPath);
+ setOption("GaviotaTbCache", 8);
+ }
}
/** @inheritDoc */
diff --git a/DroidFish/src/org/petero/droidfish/engine/UCIEngine.java b/DroidFish/src/org/petero/droidfish/engine/UCIEngine.java
index c9ed733..c5bedd5 100644
--- a/DroidFish/src/org/petero/droidfish/engine/UCIEngine.java
+++ b/DroidFish/src/org/petero/droidfish/engine/UCIEngine.java
@@ -18,6 +18,8 @@
package org.petero.droidfish.engine;
+import org.petero.droidfish.EGTBOptions;
+
public interface UCIEngine {
/** For reporting engine error messages. */
@@ -30,7 +32,7 @@ public interface UCIEngine {
public void initialize();
/** Initialize default options. */
- public void initOptions();
+ public void initOptions(EGTBOptions egtbOptions);
/** Shut down engine. */
public void shutDown();
diff --git a/DroidFish/src/org/petero/droidfish/engine/UCIEngineBase.java b/DroidFish/src/org/petero/droidfish/engine/UCIEngineBase.java
index 1c3e702..0af6b49 100644
--- a/DroidFish/src/org/petero/droidfish/engine/UCIEngineBase.java
+++ b/DroidFish/src/org/petero/droidfish/engine/UCIEngineBase.java
@@ -21,6 +21,7 @@ package org.petero.droidfish.engine;
import java.util.HashMap;
import java.util.HashSet;
+import org.petero.droidfish.EGTBOptions;
import org.petero.droidfish.engine.cuckoochess.CuckooChessEngine;
import android.content.Context;
@@ -61,7 +62,7 @@ public abstract class UCIEngineBase implements UCIEngine {
}
@Override
- public void initOptions() {
+ public void initOptions(EGTBOptions egtbOptions) {
isUCI = true;
}
diff --git a/DroidFish/src/org/petero/droidfish/engine/cuckoochess/CuckooChessEngine.java b/DroidFish/src/org/petero/droidfish/engine/cuckoochess/CuckooChessEngine.java
index 9d09d6e..08c06d7 100644
--- a/DroidFish/src/org/petero/droidfish/engine/cuckoochess/CuckooChessEngine.java
+++ b/DroidFish/src/org/petero/droidfish/engine/cuckoochess/CuckooChessEngine.java
@@ -25,6 +25,7 @@ import chess.Position;
import chess.TextIO;
import java.util.ArrayList;
+import org.petero.droidfish.EGTBOptions;
import org.petero.droidfish.engine.LocalPipe;
import org.petero.droidfish.engine.UCIEngineBase;
@@ -73,8 +74,8 @@ public class CuckooChessEngine extends UCIEngineBase {
/** @inheritDoc */
@Override
- public final void initOptions() {
- super.initOptions();
+ public final void initOptions(EGTBOptions egtbOptions) {
+ super.initOptions(egtbOptions);
}
/** @inheritDoc */
diff --git a/DroidFish/src/org/petero/droidfish/gamelogic/DroidChessController.java b/DroidFish/src/org/petero/droidfish/gamelogic/DroidChessController.java
index c6da2c6..645c89e 100644
--- a/DroidFish/src/org/petero/droidfish/gamelogic/DroidChessController.java
+++ b/DroidFish/src/org/petero/droidfish/gamelogic/DroidChessController.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import org.petero.droidfish.EGTBOptions;
import org.petero.droidfish.GUIInterface;
import org.petero.droidfish.GameMode;
import org.petero.droidfish.PGNOptions;
@@ -40,6 +41,7 @@ public class DroidChessController {
private DroidComputerPlayer computerPlayer = null;
private PgnToken.PgnTokenReceiver gameTextListener = null;
private BookOptions bookOptions = new BookOptions();
+ private EGTBOptions egtbOptions = new EGTBOptions();
private Game game = null;
private Move ponderMove = null;
private GUIInterface gui;
@@ -81,6 +83,7 @@ public class DroidChessController {
if (computerPlayer == null) {
computerPlayer = new DroidComputerPlayer(gui.getContext(), listener);
computerPlayer.setBookOptions(bookOptions);
+ computerPlayer.setEgtbOptions(egtbOptions);
}
computerPlayer.queueStartEngine(searchId, engine);
searchId++;
@@ -139,6 +142,14 @@ public class DroidChessController {
}
}
+ public final synchronized void setEgtbOptions(EGTBOptions options) {
+ if (!egtbOptions.equals(options)) {
+ egtbOptions = options;
+ if (computerPlayer != null)
+ computerPlayer.setEgtbOptions(egtbOptions);
+ }
+ }
+
/** Set engine and engine strength. Restart computer thinking if appropriate.
* @param engine Name of engine.
* @param strength Engine strength, 0 - 1000. */
@@ -560,7 +571,7 @@ public class DroidChessController {
private boolean whiteMove = true;
private String bookInfo = "";
- private List bookMoves = null;
+ private ArrayList bookMoves = null;
private Move ponderMove = null;
private ArrayList pvInfoV = new ArrayList();
@@ -676,7 +687,7 @@ public class DroidChessController {
}
@Override
- public void notifyBookInfo(int id, String bookInfo, List moveList) {
+ public void notifyBookInfo(int id, String bookInfo, ArrayList moveList) {
this.bookInfo = bookInfo;
bookMoves = moveList;
setSearchInfo(id);
@@ -944,7 +955,7 @@ public class DroidChessController {
}
private final synchronized void setThinkingInfo(int id, ArrayList> pvMoves, String pvStr,
- String statStr, String bookInfo, List bookMoves) {
+ String statStr, String bookInfo, ArrayList bookMoves) {
if (id == searchId)
gui.setThinkingInfo(pvStr, statStr, bookInfo, pvMoves, bookMoves);
}
diff --git a/DroidFish/src/org/petero/droidfish/gamelogic/GameTree.java b/DroidFish/src/org/petero/droidfish/gamelogic/GameTree.java
index 520df7b..66d8f8b 100644
--- a/DroidFish/src/org/petero/droidfish/gamelogic/GameTree.java
+++ b/DroidFish/src/org/petero/droidfish/gamelogic/GameTree.java
@@ -674,10 +674,10 @@ public class GameTree {
}
/** List of possible continuation moves. */
- public final List variations() {
+ public final ArrayList variations() {
if (currentNode.verifyChildren(currentPos))
updateListener();
- List ret = new ArrayList();
+ ArrayList ret = new ArrayList();
for (Node child : currentNode.children)
ret.add(child.move);
return ret;
diff --git a/DroidFish/src/org/petero/droidfish/gamelogic/SearchListener.java b/DroidFish/src/org/petero/droidfish/gamelogic/SearchListener.java
index 4de4755..3d6afba 100644
--- a/DroidFish/src/org/petero/droidfish/gamelogic/SearchListener.java
+++ b/DroidFish/src/org/petero/droidfish/gamelogic/SearchListener.java
@@ -19,7 +19,6 @@
package org.petero.droidfish.gamelogic;
import java.util.ArrayList;
-import java.util.List;
/**
@@ -83,7 +82,7 @@ public interface SearchListener {
public void notifyStats(int id, int nodes, int nps, int time);
/** Report opening book information. */
- public void notifyBookInfo(int id, String bookInfo, List moveList);
+ public void notifyBookInfo(int id, String bookInfo, ArrayList moveList);
/** Report move (or command, such as "resign") played by the engine. */
public void notifySearchResult(int id, String cmd, Move ponder);
diff --git a/DroidFish/src/org/petero/droidfish/gtb/GtbProbe.java b/DroidFish/src/org/petero/droidfish/gtb/GtbProbe.java
new file mode 100644
index 0000000..885f8f2
--- /dev/null
+++ b/DroidFish/src/org/petero/droidfish/gtb/GtbProbe.java
@@ -0,0 +1,83 @@
+/*
+ GtbProbe - Java interface to Gaviota endgame tablebases.
+ Copyright (C) 2011-2012 Peter Österlund, peterosterlund2@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+package org.petero.droidfish.gtb;
+
+/** Interface to native gtb probing code. */
+class GtbProbe {
+ static {
+ System.loadLibrary("gtb");
+ }
+
+ private String currTbPath = "";
+
+ GtbProbe() {
+ }
+
+ final synchronized void setPath(String tbPath) {
+ if (!currTbPath.equals(tbPath)) {
+ currTbPath = tbPath;
+ init(tbPath);
+ }
+ }
+
+ final static int NOPIECE = 0;
+ final static int PAWN = 1;
+ final static int KNIGHT = 2;
+ final static int BISHOP = 3;
+ final static int ROOK = 4;
+ final static int QUEEN = 5;
+ final static int KING = 6;
+
+ final static int NOSQUARE = 64;
+
+ // Castle masks
+ final static int H1_CASTLE = 8;
+ final static int A1_CASTLE = 4;
+ final static int H8_CASTLE = 2;
+ final static int A8_CASTLE = 1;
+
+ // tbinfo values
+ final static int DRAW = 0;
+ final static int WMATE = 1;
+ final static int BMATE = 2;
+ final static int FORBID = 3;
+ final static int UNKNOWN = 7;
+
+ /**
+ * Probe table bases.
+ * @param wtm True if white to move.
+ * @param epSq En passant square, or NOSQUARE.
+ * @param castleMask Castle mask.
+ * @param whiteSquares Array of squares occupied by white pieces, terminated with NOSQUARE.
+ * @param blackSquares Array of squares occupied by black pieces, terminated with NOSQUARE.
+ * @param whitePieces Array of white pieces, terminated with NOPIECE.
+ * @param blackPieces Array of black pieces, terminated with NOPIECE.
+ * @param result Two element array. Set to [tbinfo, plies].
+ * @return True if success.
+ */
+ public final native boolean probeHard(boolean wtm, int epSq,
+ int castleMask,
+ int[] whiteSquares,
+ int[] blackSquares,
+ byte[] whitePieces,
+ byte[] blackPieces,
+ int[] result);
+
+ private final native static boolean init(String tbPath);
+}
diff --git a/DroidFish/src/org/petero/droidfish/gtb/Probe.java b/DroidFish/src/org/petero/droidfish/gtb/Probe.java
new file mode 100644
index 0000000..92338d5
--- /dev/null
+++ b/DroidFish/src/org/petero/droidfish/gtb/Probe.java
@@ -0,0 +1,278 @@
+/*
+ GtbCuckoo - Interface to Gaviota endgame tablebases.
+ Copyright (C) 2011-2012 Peter Österlund, peterosterlund2@gmail.com
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+package org.petero.droidfish.gtb;
+
+import java.util.ArrayList;
+
+import org.petero.droidfish.gamelogic.Move;
+import org.petero.droidfish.gamelogic.MoveGen;
+import org.petero.droidfish.gamelogic.Pair;
+import org.petero.droidfish.gamelogic.Piece;
+import org.petero.droidfish.gamelogic.Position;
+import org.petero.droidfish.gamelogic.UndoInfo;
+
+/** Interface between Position class and GTB probing code. */
+public class Probe {
+ private final GtbProbe gtb;
+ private final int whiteSquares[];
+ private final int blackSquares[];
+ private final byte whitePieces[];
+ private final byte blackPieces[];
+
+ private static final Probe INSTANCE = new Probe();
+
+ /** Get singleton instance. */
+ public static Probe getInstance() {
+ return INSTANCE;
+ }
+
+ /** Constructor. */
+ private Probe() {
+ gtb = new GtbProbe();
+ whiteSquares = new int[65];
+ blackSquares = new int[65];
+ whitePieces = new byte[65];
+ blackPieces = new byte[65];
+ }
+
+ public void setPath(String tbPath) {
+ gtb.setPath(tbPath);
+ }
+
+ public static final class ProbeResult {
+ public final static int DRAW = 0;
+ public final static int WMATE = 1;
+ public final static int BMATE = 2;
+ public final static int UNKNOWN = 3;
+
+ public int result;
+ public int movesToMate; // Full moves to mate, or 0 if DRAW or UNKNOWN.
+ }
+
+ /**
+ * Probe table bases.
+ * @param pos The position to probe.
+ * @param result Two element array. Set to [tbinfo, plies].
+ * @return True if success.
+ */
+ public final ProbeResult probeHard(Position pos) {
+ int castleMask = 0;
+ if (pos.a1Castle()) castleMask |= GtbProbe.A1_CASTLE;
+ if (pos.h1Castle()) castleMask |= GtbProbe.H1_CASTLE;
+ if (pos.a8Castle()) castleMask |= GtbProbe.A8_CASTLE;
+ if (pos.h8Castle()) castleMask |= GtbProbe.H8_CASTLE;
+
+ int nWhite = 0;
+ int nBlack = 0;
+ for (int sq = 0; sq < 64; sq++) {
+ int p = pos.getPiece(sq);
+ switch (p) {
+ case Piece.WKING:
+ whiteSquares[nWhite] = sq;
+ whitePieces[nWhite++] = GtbProbe.KING;
+ break;
+ case Piece.WQUEEN:
+ whiteSquares[nWhite] = sq;
+ whitePieces[nWhite++] = GtbProbe.QUEEN;
+ break;
+ case Piece.WROOK:
+ whiteSquares[nWhite] = sq;
+ whitePieces[nWhite++] = GtbProbe.ROOK;
+ break;
+ case Piece.WBISHOP:
+ whiteSquares[nWhite] = sq;
+ whitePieces[nWhite++] = GtbProbe.BISHOP;
+ break;
+ case Piece.WKNIGHT:
+ whiteSquares[nWhite] = sq;
+ whitePieces[nWhite++] = GtbProbe.KNIGHT;
+ break;
+ case Piece.WPAWN:
+ whiteSquares[nWhite] = sq;
+ whitePieces[nWhite++] = GtbProbe.PAWN;
+ break;
+
+ case Piece.BKING:
+ blackSquares[nBlack] = sq;
+ blackPieces[nBlack++] = GtbProbe.KING;
+ break;
+ case Piece.BQUEEN:
+ blackSquares[nBlack] = sq;
+ blackPieces[nBlack++] = GtbProbe.QUEEN;
+ break;
+ case Piece.BROOK:
+ blackSquares[nBlack] = sq;
+ blackPieces[nBlack++] = GtbProbe.ROOK;
+ break;
+ case Piece.BBISHOP:
+ blackSquares[nBlack] = sq;
+ blackPieces[nBlack++] = GtbProbe.BISHOP;
+ break;
+ case Piece.BKNIGHT:
+ blackSquares[nBlack] = sq;
+ blackPieces[nBlack++] = GtbProbe.KNIGHT;
+ break;
+ case Piece.BPAWN:
+ blackSquares[nBlack] = sq;
+ blackPieces[nBlack++] = GtbProbe.PAWN;
+ break;
+ }
+ }
+ whiteSquares[nWhite] = GtbProbe.NOSQUARE;
+ blackSquares[nBlack] = GtbProbe.NOSQUARE;
+ whitePieces[nWhite] = GtbProbe.NOPIECE;
+ blackPieces[nBlack] = GtbProbe.NOPIECE;
+ int epSquare = pos.getEpSquare();
+ if (epSquare == -1)
+ epSquare = GtbProbe.NOSQUARE;
+
+ int[] result = new int[2];
+ boolean res = gtb.probeHard(pos.whiteMove, epSquare, castleMask,
+ whiteSquares, blackSquares, whitePieces, blackPieces,
+ result);
+ ProbeResult ret = new ProbeResult();
+ if (res) {
+ switch (result[0]) {
+ case GtbProbe.DRAW:
+ ret.result = ProbeResult.DRAW;
+ ret.movesToMate = 0;
+ break;
+ case GtbProbe.WMATE:
+ ret.result = ProbeResult.WMATE;
+ ret.movesToMate = (result[1] + 1) / 2;
+ break;
+ case GtbProbe.BMATE:
+ ret.result = ProbeResult.BMATE;
+ ret.movesToMate = (result[1] + 1) / 2;
+ break;
+ default:
+ ret.result = ProbeResult.UNKNOWN;
+ ret.movesToMate = 0;
+ break;
+ }
+ } else {
+ ret.result = ProbeResult.UNKNOWN;
+ ret.movesToMate = 0;
+ }
+ return ret;
+ }
+
+ /** Return a list of all legal moves that are not known to be non-optimal.
+ * Returns null if no legal move could be excluded. */
+ public final ArrayList findOptimal(Position pos) {
+ ArrayList moveList = new MoveGen().pseudoLegalMoves(pos);
+ moveList = MoveGen.removeIllegal(pos, moveList);
+ ArrayList optimalMoves = new ArrayList();
+ ArrayList unknownMoves = new ArrayList();
+ final int MATE0 = 100000;
+ int bestScore = -1000000;
+ UndoInfo ui = new UndoInfo();
+ for (Move m : moveList) {
+ pos.makeMove(m, ui);
+ ProbeResult res = probeHard(pos);
+ pos.unMakeMove(m, ui);
+ if (res.result == ProbeResult.UNKNOWN) {
+ unknownMoves.add(m);
+ } else {
+ int wScore;
+ if (res.result == ProbeResult.WMATE)
+ wScore = MATE0 - res.movesToMate;
+ else if (res.result == ProbeResult.BMATE)
+ wScore = -(MATE0 - res.movesToMate);
+ else
+ wScore = 0;
+ int score = pos.whiteMove ? wScore : -wScore;
+ if (score > bestScore) {
+ optimalMoves.clear();
+ optimalMoves.add(m);
+ bestScore = score;
+ } else if (score == bestScore) {
+ optimalMoves.add(m);
+ } else {
+ // Ignore move
+ }
+ }
+ }
+ for (Move m : unknownMoves)
+ optimalMoves.add(m);
+ return (optimalMoves.size() < moveList.size()) ? optimalMoves : null;
+ }
+
+ /** For a given position and from square, return EGTB information
+ * about all legal destination squares. Return null if no information available. */
+ public final ArrayList> movePieceProbe(Position pos, int fromSq) {
+ int p = pos.getPiece(fromSq);
+ if ((p == Piece.EMPTY) || (pos.whiteMove != Piece.isWhite(p)))
+ return null;
+ ArrayList> ret = new ArrayList>();
+
+ ArrayList moveList = new MoveGen().pseudoLegalMoves(pos);
+ moveList = MoveGen.removeIllegal(pos, moveList);
+ UndoInfo ui = new UndoInfo();
+ for (Move m : moveList) {
+ if (m.from != fromSq)
+ continue;
+ pos.makeMove(m, ui);
+ ProbeResult res = probeHard(pos);
+ pos.unMakeMove(m, ui);
+ if (res.result == ProbeResult.UNKNOWN)
+ continue;
+ int score = 0;
+ if (res.result == ProbeResult.WMATE) {
+ score = pos.whiteMove ? res.movesToMate + 1 : -res.movesToMate;
+ } else if (res.result == ProbeResult.BMATE) {
+ score = pos.whiteMove ? -res.movesToMate : res.movesToMate + 1;
+ }
+ ret.add(new Pair(m.to, score));
+ }
+ return ret;
+ }
+
+ /** For a given position and from square, return EGTB information
+ * about all legal alternative positions for the piece on from square.
+ * Return null if no information is available. */
+ public final ArrayList> relocatePieceProbe(Position pos, int fromSq) {
+ int p = pos.getPiece(fromSq);
+ if (p == Piece.EMPTY)
+ return null;
+ boolean isPawn = (Piece.makeWhite(p) == Piece.WPAWN);
+ ArrayList> ret = new ArrayList>();
+ for (int sq = 0; sq < 64; sq++) {
+ if ((sq != fromSq) && (pos.getPiece(sq) != Piece.EMPTY))
+ continue;
+ if (isPawn && ((sq < 8) || (sq >= 56)))
+ continue;
+ pos.setPiece(fromSq, Piece.EMPTY);
+ pos.setPiece(sq, p);
+ ProbeResult res = probeHard(pos);
+ pos.setPiece(sq, Piece.EMPTY);
+ pos.setPiece(fromSq, p);
+ if (res.result == ProbeResult.UNKNOWN)
+ continue;
+ int score = 0;
+ if (res.result == ProbeResult.WMATE) {
+ score = res.movesToMate;
+ } else if (res.result == ProbeResult.BMATE) {
+ score = -res.movesToMate;
+ }
+ ret.add(new Pair(sq, score));
+ }
+ return ret;
+ }
+}