aboutsummaryrefslogtreecommitdiff
path: root/redist
diff options
context:
space:
mode:
authorJoshua Allen <axlecrusher@gmail.com>2017-03-15 19:26:46 -0400
committerJoshua Allen <axlecrusher@gmail.com>2017-03-15 19:26:46 -0400
commit1388d54117ff780b7fadd4fd682b6def569838fa (patch)
tree3737760c889eeaf0bd7305becc943d859ae65d96 /redist
parent62cef8aec06638bd006eaef46700f491750fc108 (diff)
parent9bd0a0d949639b516d28091f57862ac5e59e65da (diff)
downloadlibsurvive-1388d54117ff780b7fadd4fd682b6def569838fa.tar.gz
libsurvive-1388d54117ff780b7fadd4fd682b6def569838fa.tar.bz2
Merge branch 'master' of github.com:cnlohr/libsurvive
Conflicts: src/survive_data.c
Diffstat (limited to 'redist')
-rw-r--r--redist/glutil.c9
-rw-r--r--redist/glutil.h14
-rw-r--r--redist/linmath.c2
-rw-r--r--redist/linmath.h9
-rw-r--r--redist/mymath.c550
-rw-r--r--redist/os_generic.h2
-rw-r--r--redist/puff.c955
-rw-r--r--redist/puff.h31
-rw-r--r--redist/symbol_enumerator.c241
-rw-r--r--redist/symbol_enumerator.h12
10 files changed, 1821 insertions, 4 deletions
diff --git a/redist/glutil.c b/redist/glutil.c
new file mode 100644
index 0000000..6b0d0f3
--- /dev/null
+++ b/redist/glutil.c
@@ -0,0 +1,9 @@
+//
+// glutil.c
+//
+//
+// Created by user on 2/4/17.
+//
+//
+
+#include "glutil.h"
diff --git a/redist/glutil.h b/redist/glutil.h
new file mode 100644
index 0000000..bb40174
--- /dev/null
+++ b/redist/glutil.h
@@ -0,0 +1,14 @@
+//
+// glutil.h
+//
+//
+// Created by user on 2/4/17.
+//
+//
+
+#ifndef glutil_h
+#define glutil_h
+
+#include <stdio.h>
+
+#endif /* glutil_h */
diff --git a/redist/linmath.c b/redist/linmath.c
index 41fa18f..dd6bd15 100644
--- a/redist/linmath.c
+++ b/redist/linmath.c
@@ -1,7 +1,7 @@
//Copyright 2013,2016 <>< C. N. Lohr. This file licensed under the terms of the MIT license.
-#include "linmath.h"
#include <math.h>
+#include "linmath.h"
#include <float.h>
#include <string.h>
diff --git a/redist/linmath.h b/redist/linmath.h
index 66a38ed..4e0cb77 100644
--- a/redist/linmath.h
+++ b/redist/linmath.h
@@ -25,7 +25,7 @@
#define FLT_ACOS acos
#define FLT_ASIN asin
#define FLT_ATAN2 atan2
-#define FLT_FABS fabs
+#define FLT_FABS__ fabs
#else
@@ -37,10 +37,15 @@
#define FLT_ACOS acosf
#define FLT_ASIN asinf
#define FLT_ATAN2 atan2f
-#define FLT_FABS fabsf
+#define FLT_FABS__ fabsf
#endif
+#ifdef TCC
+#define FLT_FABS(x) (((x)<0)?(-(x)):(x))
+#else
+#define FLT_FABS FLT_FABS__
+#endif
//NOTE: Inputs may never be output with cross product.
diff --git a/redist/mymath.c b/redist/mymath.c
new file mode 100644
index 0000000..17dcc96
--- /dev/null
+++ b/redist/mymath.c
@@ -0,0 +1,550 @@
+//Copyright 2013,2016 <>< C. N. Lohr. This file licensed under the terms of the MIT license.
+
+#include <math.h>
+#include <float.h>
+#include <string.h>
+#include "linmath.h"
+
+#define FLT float
+#define LINMATHPI ((FLT)3.141592653589)
+#define DEFAULT_EPSILON 0.001
+void quatnormalize( FLT * qout, const FLT * qin );
+void quatscale( FLT * qout, const FLT * qin, FLT s );
+void quatfrom2vectors(FLT *q, const FLT *src, const FLT *dest);
+
+
+void cross3d( FLT * out, const FLT * a, const FLT * b )
+{
+ out[0] = a[1]*b[2] - a[2]*b[1];
+ out[1] = a[2]*b[0] - a[0]*b[2];
+ out[2] = a[0]*b[1] - a[1]*b[0];
+}
+
+void sub3d( FLT * out, const FLT * a, const FLT * b )
+{
+ out[0] = a[0] - b[0];
+ out[1] = a[1] - b[1];
+ out[2] = a[2] - b[2];
+}
+
+void add3d( FLT * out, const FLT * a, const FLT * b )
+{
+ out[0] = a[0] + b[0];
+ out[1] = a[1] + b[1];
+ out[2] = a[2] + b[2];
+}
+
+void scale3d( FLT * out, const FLT * a, FLT scalar )
+{
+ out[0] = a[0] * scalar;
+ out[1] = a[1] * scalar;
+ out[2] = a[2] * scalar;
+}
+
+void normalize3d( FLT * out, const FLT * in )
+{
+ FLT r = ((FLT)1.) / FLT_SQRT(in[0] * in[0] + in[1] * in[1] + in[2] * in[2]);
+ out[0] = in[0] * r;
+ out[1] = in[1] * r;
+ out[2] = in[2] * r;
+}
+
+FLT dot3d( const FLT * a, const FLT * b )
+{
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
+}
+
+int compare3d( const FLT * a, const FLT * b, FLT epsilon )
+{
+ if( !a || !b ) return 0;
+ if( a[2] - b[2] > epsilon ) return 1;
+ if( b[2] - a[2] > epsilon ) return -1;
+ if( a[1] - b[1] > epsilon ) return 1;
+ if( b[1] - a[1] > epsilon ) return -1;
+ if( a[0] - b[0] > epsilon ) return 1;
+ if( b[0] - a[0] > epsilon ) return -1;
+ return 0;
+}
+
+void copy3d( FLT * out, const FLT * in )
+{
+ out[0] = in[0];
+ out[1] = in[1];
+ out[2] = in[2];
+}
+
+FLT magnitude3d(const FLT * a )
+{
+ return FLT_SQRT(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
+}
+
+FLT anglebetween3d( FLT * a, FLT * b )
+{
+ FLT an[3];
+ FLT bn[3];
+ normalize3d( an, a );
+ normalize3d( bn, b );
+ FLT dot = dot3d(an, bn);
+ if( dot < -0.9999999 ) return LINMATHPI;
+ if( dot > 0.9999999 ) return 0;
+ return FLT_ACOS(dot);
+}
+
+/////////////////////////////////////QUATERNIONS//////////////////////////////////////////
+//Originally from Mercury (Copyright (C) 2009 by Joshua Allen, Charles Lohr, Adam Lowman)
+//Under the mit/X11 license.
+
+
+
+
+void quatsetnone(FLT * q)
+{
+ q[0] = 1; q[1] = 0; q[2] = 0; q[3] = 0;
+}
+
+void quatcopy(FLT * qout, const FLT * qin)
+{
+ qout[0] = qin[0];
+ qout[1] = qin[1];
+ qout[2] = qin[2];
+ qout[3] = qin[3];
+}
+
+void quatfromeuler( FLT * q, const FLT * euler )
+{
+ FLT X = euler[0]/2.0f; //roll
+ FLT Y = euler[1]/2.0f; //pitch
+ FLT Z = euler[2]/2.0f; //yaw
+
+ FLT cx = FLT_COS(X);
+ FLT sx = FLT_SIN(X);
+ FLT cy = FLT_COS(Y);
+ FLT sy = FLT_SIN(Y);
+ FLT cz = FLT_COS(Z);
+ FLT sz = FLT_SIN(Z);
+
+ //Correct according to
+ //http://en.wikipedia.org/wiki/Conversion_between_MQuaternions_and_Euler_angles
+ q[0] = cx*cy*cz+sx*sy*sz;//q1
+ q[1] = sx*cy*cz-cx*sy*sz;//q2
+ q[2] = cx*sy*cz+sx*cy*sz;//q3
+ q[3] = cx*cy*sz-sx*sy*cz;//q4
+ quatnormalize( q, q );
+}
+
+void quattoeuler( FLT * euler, const FLT * q )
+{
+ //According to http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles (Oct 26, 2009)
+ euler[0] = FLT_ATAN2(2 * (q[0] * q[1] + q[2] * q[3]), 1 - 2 * (q[1] * q[1] + q[2] * q[2]));
+ euler[1] = FLT_ASIN(2 * (q[0] * q[2] - q[3] * q[1]));
+ euler[2] = FLT_ATAN2(2 * (q[0] * q[3] + q[1] * q[2]), 1 - 2 * (q[2] * q[2] + q[3] * q[3]));
+}
+
+void quatfromaxisangle( FLT * q, const FLT * axis, FLT radians )
+{
+ FLT v[3];
+ normalize3d( v, axis );
+
+ FLT sn = FLT_SIN(radians / 2.0f);
+ q[0] = FLT_COS(radians / 2.0f);
+ q[1] = sn * v[0];
+ q[2] = sn * v[1];
+ q[3] = sn * v[2];
+
+ quatnormalize( q, q );
+}
+
+FLT quatmagnitude( const FLT * q )
+{
+ return FLT_SQRT((q[0] * q[0]) + (q[1] * q[1]) + (q[2] * q[2]) + (q[3] * q[3]));
+}
+
+FLT quatinvsqmagnitude( const FLT * q )
+{
+ return ((FLT)1.)/FLT_SQRT((q[0]*q[0])+(q[1]*q[1])+(q[2]*q[2])+(q[3]*q[3]));
+}
+
+
+void quatnormalize( FLT * qout, const FLT * qin )
+{
+ FLT imag = quatinvsqmagnitude( qin );
+ quatscale( qout, qin, imag );
+}
+
+void quattomatrix(FLT * matrix44, const FLT * qin)
+{
+ FLT q[4];
+ quatnormalize(q, qin);
+
+ //Reduced calulation for speed
+ FLT xx = 2 * q[1] * q[1];
+ FLT xy = 2 * q[1] * q[2];
+ FLT xz = 2 * q[1] * q[3];
+ FLT xw = 2 * q[1] * q[0];
+
+ FLT yy = 2 * q[2] * q[2];
+ FLT yz = 2 * q[2] * q[3];
+ FLT yw = 2 * q[2] * q[0];
+
+ FLT zz = 2 * q[3] * q[3];
+ FLT zw = 2 * q[3] * q[0];
+
+ //opengl major
+ matrix44[0] = 1 - yy - zz;
+ matrix44[1] = xy - zw;
+ matrix44[2] = xz + yw;
+ matrix44[3] = 0;
+
+ matrix44[4] = xy + zw;
+ matrix44[5] = 1 - xx - zz;
+ matrix44[6] = yz - xw;
+ matrix44[7] = 0;
+
+ matrix44[8] = xz - yw;
+ matrix44[9] = yz + xw;
+ matrix44[10] = 1 - xx - yy;
+ matrix44[11] = 0;
+
+ matrix44[12] = 0;
+ matrix44[13] = 0;
+ matrix44[14] = 0;
+ matrix44[15] = 1;
+}
+
+
+void quatfrommatrix( FLT * q, const FLT * matrix44 )
+{
+ //Algorithm from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/
+ float tr = matrix44[0] + matrix44[5] + matrix44[10];
+
+ if (tr > 0) {
+ float S = sqrt(tr+1.0) * 2; // S=4*qw
+ q[0] = 0.25 * S;
+ q[1] = (matrix44[9] - matrix44[6]) / S;
+ q[2] = (matrix44[2] - matrix44[8]) / S;
+ q[3] = (matrix44[4] - matrix44[1]) / S;
+ } else if ((matrix44[0] > matrix44[5])&(matrix44[0] > matrix44[10])) {
+ float S = sqrt(1.0 + matrix44[0] - matrix44[5] - matrix44[10]) * 2; // S=4*qx
+ q[0] = (matrix44[9] - matrix44[6]) / S;
+ q[1] = 0.25 * S;
+ q[2] = (matrix44[1] + matrix44[4]) / S;
+ q[3] = (matrix44[2] + matrix44[8]) / S;
+ } else if (matrix44[5] > matrix44[10]) {
+ float S = sqrt(1.0 + matrix44[5] - matrix44[0] - matrix44[10]) * 2; // S=4*qy
+ q[0] = (matrix44[2] - matrix44[8]) / S;
+ q[1] = (matrix44[1] + matrix44[4]) / S;
+ q[2] = 0.25 * S;
+ q[3] = (matrix44[6] + matrix44[9]) / S;
+ } else {
+ float S = sqrt(1.0 + matrix44[10] - matrix44[0] - matrix44[5]) * 2; // S=4*qz
+ q[0] = (matrix44[4] - matrix44[1]) / S;
+ q[1] = (matrix44[2] + matrix44[8]) / S;
+ q[2] = (matrix44[6] + matrix44[9]) / S;
+ q[3] = 0.25 * S;
+ }
+}
+
+
+void quattomatrix33(FLT * matrix33, const FLT * qin)
+{
+ FLT q[4];
+ quatnormalize(q, qin);
+
+ //Reduced calulation for speed
+ FLT xx = 2 * q[0] * q[0];
+ FLT xy = 2 * q[0] * q[1];
+ FLT xz = 2 * q[0] * q[2];
+ FLT xw = 2 * q[0] * q[3];
+
+ FLT yy = 2 * q[1] * q[1];
+ FLT yz = 2 * q[1] * q[2];
+ FLT yw = 2 * q[1] * q[3];
+
+ FLT zz = 2 * q[2] * q[2];
+ FLT zw = 2 * q[2] * q[3];
+
+ //opengl major
+ matrix33[0] = 1 - yy - zz;
+ matrix33[1] = xy - zw;
+ matrix33[2] = xz + yw;
+
+ matrix33[3] = xy + zw;
+ matrix33[4] = 1 - xx - zz;
+ matrix33[5] = yz - xw;
+
+ matrix33[6] = xz - yw;
+ matrix33[7] = yz + xw;
+ matrix33[8] = 1 - xx - yy;
+}
+
+void quatgetconjugate(FLT * qout, const FLT * qin)
+{
+ qout[0] = qin[0];
+ qout[1] = -qin[1];
+ qout[2] = -qin[2];
+ qout[3] = -qin[3];
+}
+
+void quatgetreciprocal( FLT * qout, const FLT * qin )
+{
+ FLT m = quatinvsqmagnitude(qin);
+ quatgetconjugate( qout, qin );
+ quatscale( qout, qout, m );
+}
+
+void quatsub( FLT * qout, const FLT * a, const FLT * b )
+{
+ qout[0] = a[0] - b[0];
+ qout[1] = a[1] - b[1];
+ qout[2] = a[2] - b[2];
+ qout[3] = a[3] - b[3];
+}
+
+void quatadd( FLT * qout, const FLT * a, const FLT * b )
+{
+ qout[0] = a[0] + b[0];
+ qout[1] = a[1] + b[1];
+ qout[2] = a[2] + b[2];
+ qout[3] = a[3] + b[3];
+}
+
+void quatrotateabout( FLT * qout, const FLT * q1, const FLT * q2 )
+{
+ //NOTE: Does not normalize
+ qout[0] = (q1[0]*q2[0])-(q1[1]*q2[1])-(q1[2]*q2[2])-(q1[3]*q2[3]);
+ qout[1] = (q1[0]*q2[1])+(q1[1]*q2[0])+(q1[2]*q2[3])-(q1[3]*q2[2]);
+ qout[2] = (q1[0]*q2[2])-(q1[1]*q2[3])+(q1[2]*q2[0])+(q1[3]*q2[1]);
+ qout[3] = (q1[0]*q2[3])+(q1[1]*q2[2])-(q1[2]*q2[1])+(q1[3]*q2[0]);
+}
+
+void quatscale( FLT * qout, const FLT * qin, FLT s )
+{
+ qout[0] = qin[0] * s;
+ qout[1] = qin[1] * s;
+ qout[2] = qin[2] * s;
+ qout[3] = qin[3] * s;
+}
+
+
+FLT quatinnerproduct( const FLT * qa, const FLT * qb )
+{
+ return (qa[0]*qb[0])+(qa[1]*qb[1])+(qa[2]*qb[2])+(qa[3]*qb[3]);
+}
+
+void quatouterproduct( FLT * outvec3, FLT * qa, FLT * qb )
+{
+ outvec3[0] = (qa[0]*qb[1])-(qa[1]*qb[0])-(qa[2]*qb[3])+(qa[3]*qb[2]);
+ outvec3[1] = (qa[0]*qb[2])+(qa[1]*qb[3])-(qa[2]*qb[0])-(qa[3]*qb[1]);
+ outvec3[2] = (qa[0]*qb[3])-(qa[1]*qb[2])+(qa[2]*qb[1])-(qa[3]*qb[0]);
+}
+
+void quatevenproduct( FLT * q, FLT * qa, FLT * qb )
+{
+ q[0] = (qa[0]*qb[0])-(qa[1]*qb[1])-(qa[2]*qb[2])-(qa[3]*qb[3]);
+ q[1] = (qa[0]*qb[1])+(qa[1]*qb[0]);
+ q[2] = (qa[0]*qb[2])+(qa[2]*qb[0]);
+ q[3] = (qa[0]*qb[3])+(qa[3]*qb[0]);
+}
+
+void quatoddproduct( FLT * outvec3, FLT * qa, FLT * qb )
+{
+ outvec3[0] = (qa[2]*qb[3])-(qa[3]*qb[2]);
+ outvec3[1] = (qa[3]*qb[1])-(qa[1]*qb[3]);
+ outvec3[2] = (qa[1]*qb[2])-(qa[2]*qb[1]);
+}
+
+void quatslerp( FLT * q, const FLT * qa, const FLT * qb, FLT t )
+{
+ FLT an[4];
+ FLT bn[4];
+ quatnormalize( an, qa );
+ quatnormalize( bn, qb );
+ FLT cosTheta = quatinnerproduct(an,bn);
+ FLT sinTheta;
+
+ //Careful: If cosTheta is exactly one, or even if it's infinitesimally over, it'll
+ // cause SQRT to produce not a number, and screw everything up.
+ if ( 1 - (cosTheta*cosTheta) <= 0 )
+ sinTheta = 0;
+ else
+ sinTheta = FLT_SQRT(1 - (cosTheta*cosTheta));
+
+ FLT Theta = FLT_ACOS(cosTheta); //Theta is half the angle between the 2 MQuaternions
+
+ if (FLT_FABS(Theta) < DEFAULT_EPSILON)
+ quatcopy( q, qa );
+ else if (FLT_FABS(sinTheta) < DEFAULT_EPSILON)
+ {
+ quatadd( q, qa, qb );
+ quatscale( q, q, 0.5 );
+ }
+ else
+ {
+ FLT aside[4];
+ FLT bside[4];
+ quatscale( bside, qb, FLT_SIN(t * Theta));
+ quatscale( aside, qa, FLT_SIN((1 - t)*Theta));
+ quatadd( q, aside, bside );
+ quatscale( q, q, ((FLT)1.)/sinTheta );
+ }
+}
+
+void quatrotatevector( FLT * vec3out, const FLT * quat, const FLT * vec3in )
+{
+ FLT tquat[4];
+ FLT vquat[4];
+ FLT qrecp[4];
+ vquat[0] = 0;
+ vquat[1] = vec3in[0];
+ vquat[2] = vec3in[1];
+ vquat[3] = vec3in[2];
+
+ quatrotateabout( tquat, quat, vquat );
+ quatgetconjugate( qrecp, quat );
+ quatrotateabout( vquat, tquat, qrecp );
+
+ vec3out[0] = vquat[1];
+ vec3out[1] = vquat[2];
+ vec3out[2] = vquat[3];
+}
+
+
+// Matrix Stuff
+
+Matrix3x3 inverseM33(const Matrix3x3 mat)
+{
+ Matrix3x3 newMat;
+ for (int a = 0; a < 3; a++)
+ {
+ for (int b = 0; b < 3; b++)
+ {
+ newMat.val[a][b] = mat.val[a][b];
+ }
+ }
+
+ for (int i = 0; i < 3; i++)
+ {
+ for (int j = i + 1; j < 3; j++)
+ {
+ FLT tmp = newMat.val[i][j];
+ newMat.val[i][j] = newMat.val[j][i];
+ newMat.val[j][i] = tmp;
+ }
+ }
+
+ return newMat;
+}
+
+void rotation_between_vecs_to_m3(Matrix3x3 *m, const FLT v1[3], const FLT v2[3])
+{
+ FLT q[4];
+
+ quatfrom2vectors(q, v1, v2);
+
+ quattomatrix33(&(m->val[0][0]), q);
+}
+
+void rotate_vec(FLT *out, const FLT *in, Matrix3x3 rot)
+{
+ out[0] = rot.val[0][0] * in[0] + rot.val[1][0] * in[1] + rot.val[2][0] * in[2];
+ out[1] = rot.val[0][1] * in[0] + rot.val[1][1] * in[1] + rot.val[2][1] * in[2];
+ out[2] = rot.val[0][2] * in[0] + rot.val[1][2] * in[1] + rot.val[2][2] * in[2];
+
+ return;
+}
+
+
+// This function based on code from Object-oriented Graphics Rendering Engine
+// Copyright(c) 2000 - 2012 Torus Knot Software Ltd
+// under MIT license
+// http://www.ogre3d.org/docs/api/1.9/_ogre_vector3_8h_source.html
+
+/** Gets the shortest arc quaternion to rotate this vector to the destination
+vector.
+@remarks
+If you call this with a dest vector that is close to the inverse
+of this vector, we will rotate 180 degrees around a generated axis if
+since in this case ANY axis of rotation is valid.
+*/
+void quatfrom2vectors(FLT *q, const FLT *src, const FLT *dest)
+{
+ // Based on Stan Melax's article in Game Programming Gems
+
+ // Copy, since cannot modify local
+ FLT v0[3];
+ FLT v1[3];
+ normalize3d(v0, src);
+ normalize3d(v1, dest);
+
+ FLT d = dot3d(v0, v1);// v0.dotProduct(v1);
+ // If dot == 1, vectors are the same
+ if (d >= 1.0f)
+ {
+ quatsetnone(q);
+ return;
+ }
+ if (d < (1e-6f - 1.0f))
+ {
+ // Generate an axis
+ FLT unitX[3] = { 1, 0, 0 };
+ FLT unitY[3] = { 0, 1, 0 };
+
+ FLT axis[3];
+ cross3d(axis, unitX, src); // pick an angle
+ if ((axis[0] < 1.0e-35f) &&
+ (axis[1] < 1.0e-35f) &&
+ (axis[2] < 1.0e-35f)) // pick another if colinear
+ {
+ cross3d(axis, unitY, src);
+ }
+ normalize3d(axis, axis);
+ quatfromaxisangle(q, axis, LINMATHPI);
+ }
+ else
+ {
+ FLT s = FLT_SQRT((1 + d) * 2);
+ FLT invs = 1 / s;
+
+ FLT c[3];
+ //cross3d(c, v0, v1);
+ cross3d(c, v1, v0);
+
+ q[0] = c[0] * invs;
+ q[1] = c[1] * invs;
+ q[2] = c[2] * invs;
+ q[3] = s * 0.5f;
+
+ quatnormalize(q, q);
+ }
+
+}
+
+void matrix44copy(FLT * mout, const FLT * minm )
+{
+ memcpy( mout, minm, sizeof( FLT ) * 16 );
+}
+
+void matrix44transpose(FLT * mout, const FLT * minm )
+{
+ mout[0] = minm[0];
+ mout[1] = minm[4];
+ mout[2] = minm[8];
+ mout[3] = minm[12];
+
+ mout[4] = minm[1];
+ mout[5] = minm[5];
+ mout[6] = minm[9];
+ mout[7] = minm[13];
+
+ mout[8] = minm[2];
+ mout[9] = minm[6];
+ mout[10] = minm[10];
+ mout[11] = minm[14];
+
+ mout[12] = minm[3];
+ mout[13] = minm[7];
+ mout[14] = minm[11];
+ mout[15] = minm[15];
+
+}
+
diff --git a/redist/os_generic.h b/redist/os_generic.h
index 7ce22f2..aac425b 100644
--- a/redist/os_generic.h
+++ b/redist/os_generic.h
@@ -1,7 +1,7 @@
#ifndef _OS_GENERIC_H
#define _OS_GENERIC_H
-#ifdef WIN32
+#if defined( WIN32 ) || defined (WINDOWS)
#define USE_WINDOWS
#endif
diff --git a/redist/puff.c b/redist/puff.c
new file mode 100644
index 0000000..fdbf6de
--- /dev/null
+++ b/redist/puff.c
@@ -0,0 +1,955 @@
+/*
+ * puff.c
+ * Copyright (C) 2002-2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in puff.h
+ * version 2.1, 4 Apr 2010
+ *
+ * puff.c is a simple inflate written to be an unambiguous way to specify the
+ * deflate format. It is not written for speed but rather simplicity. As a
+ * side benefit, this code might actually be useful when small code is more
+ * important than speed, such as bootstrap applications. For typical deflate
+ * data, zlib's inflate() is about four times as fast as puff(). zlib's
+ * inflate compiles to around 20K on my machine, whereas puff.c compiles to
+ * around 4K on my machine (a PowerPC using GNU cc). If the faster decode()
+ * function here is used, then puff() is only twice as slow as zlib's
+ * inflate().
+ *
+ * All dynamically allocated memory comes from the stack. The stack required
+ * is less than 2K bytes. This code is compatible with 16-bit int's and
+ * assumes that long's are at least 32 bits. puff.c uses the short data type,
+ * assumed to be 16 bits, for arrays in order to to conserve memory. The code
+ * works whether integers are stored big endian or little endian.
+ *
+ * In the comments below are "Format notes" that describe the inflate process
+ * and document some of the less obvious aspects of the format. This source
+ * code is meant to supplement RFC 1951, which formally describes the deflate
+ * format:
+ *
+ * http://www.zlib.org/rfc-deflate.html
+ */
+
+/*
+ * Change history:
+ *
+ * 1.0 10 Feb 2002 - First version
+ * 1.1 17 Feb 2002 - Clarifications of some comments and notes
+ * - Update puff() dest and source pointers on negative
+ * errors to facilitate debugging deflators
+ * - Remove longest from struct huffman -- not needed
+ * - Simplify offs[] index in construct()
+ * - Add input size and checking, using longjmp() to
+ * maintain easy readability
+ * - Use short data type for large arrays
+ * - Use pointers instead of long to specify source and
+ * destination sizes to avoid arbitrary 4 GB limits
+ * 1.2 17 Mar 2002 - Add faster version of decode(), doubles speed (!),
+ * but leave simple version for readabilty
+ * - Make sure invalid distances detected if pointers
+ * are 16 bits
+ * - Fix fixed codes table error
+ * - Provide a scanning mode for determining size of
+ * uncompressed data
+ * 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Jean-loup]
+ * - Add a puff.h file for the interface
+ * - Add braces in puff() for else do [Jean-loup]
+ * - Use indexes instead of pointers for readability
+ * 1.4 31 Mar 2002 - Simplify construct() code set check
+ * - Fix some comments
+ * - Add FIXLCODES #define
+ * 1.5 6 Apr 2002 - Minor comment fixes
+ * 1.6 7 Aug 2002 - Minor format changes
+ * 1.7 3 Mar 2003 - Added test code for distribution
+ * - Added zlib-like license
+ * 1.8 9 Jan 2004 - Added some comments on no distance codes case
+ * 1.9 21 Feb 2008 - Fix bug on 16-bit integer architectures [Pohland]
+ * - Catch missing end-of-block symbol error
+ * 2.0 25 Jul 2008 - Add #define to permit distance too far back
+ * - Add option in TEST code for puff to write the data
+ * - Add option in TEST code to skip input bytes
+ * - Allow TEST code to read from piped stdin
+ * 2.1 4 Apr 2010 - Avoid variable initialization for happier compilers
+ * - Avoid unsigned comparisons for even happier compilers
+ */
+
+#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
+#include "puff.h" /* prototype for puff() */
+
+#define local static /* for local function definitions */
+#define NIL ((unsigned char *)0) /* for no output option */
+
+/*
+ * Maximums for allocations and loops. It is not useful to change these --
+ * they are fixed by the deflate format.
+ */
+#define MAXBITS 15 /* maximum bits in a code */
+#define MAXLCODES 286 /* maximum number of literal/length codes */
+#define MAXDCODES 30 /* maximum number of distance codes */
+#define MAXCODES (MAXLCODES+MAXDCODES) /* maximum codes lengths to read */
+#define FIXLCODES 288 /* number of fixed literal/length codes */
+
+/* input and output state */
+struct state {
+ /* output state */
+ unsigned char *out; /* output buffer */
+ unsigned long outlen; /* available space at out */
+ unsigned long outcnt; /* bytes written to out so far */
+
+ /* input state */
+ const unsigned char *in; /* input buffer */
+ unsigned long inlen; /* available input at in */
+ unsigned long incnt; /* bytes read so far */
+ int bitbuf; /* bit buffer */
+ int bitcnt; /* number of bits in bit buffer */
+
+ /* input limit error return state for bits() and decode() */
+ jmp_buf env;
+};
+
+/*
+ * Return need bits from the input stream. This always leaves less than
+ * eight bits in the buffer. bits() works properly for need == 0.
+ *
+ * Format notes:
+ *
+ * - Bits are stored in bytes from the least significant bit to the most
+ * significant bit. Therefore bits are dropped from the bottom of the bit
+ * buffer, using shift right, and new bytes are appended to the top of the
+ * bit buffer, using shift left.
+ */
+local int bits(struct state *s, int need)
+{
+ long val; /* bit accumulator (can use up to 20 bits) */
+
+ /* load at least need bits into val */
+ val = s->bitbuf;
+ while (s->bitcnt < need) {
+ if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */
+ val |= (long)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */
+ s->bitcnt += 8;
+ }
+
+ /* drop need bits and update buffer, always zero to seven bits left */
+ s->bitbuf = (int)(val >> need);
+ s->bitcnt -= need;
+
+ /* return need bits, zeroing the bits above that */
+ return (int)(val & ((1L << need) - 1));
+}
+
+/*
+ * Process a stored block.
+ *
+ * Format notes:
+ *
+ * - After the two-bit stored block type (00), the stored block length and
+ * stored bytes are byte-aligned for fast copying. Therefore any leftover
+ * bits in the byte that has the last bit of the type, as many as seven, are
+ * discarded. The value of the discarded bits are not defined and should not
+ * be checked against any expectation.
+ *
+ * - The second inverted copy of the stored block length does not have to be
+ * checked, but it's probably a good idea to do so anyway.
+ *
+ * - A stored block can have zero length. This is sometimes used to byte-align
+ * subsets of the compressed data for random access or partial recovery.
+ */
+local int stored(struct state *s)
+{
+ unsigned len; /* length of stored block */
+
+ /* discard leftover bits from current byte (assumes s->bitcnt < 8) */
+ s->bitbuf = 0;
+ s->bitcnt = 0;
+
+ /* get length and check against its one's complement */
+ if (s->incnt + 4 > s->inlen) return 2; /* not enough input */
+ len = s->in[s->incnt++];
+ len |= s->in[s->incnt++] << 8;
+ if (s->in[s->incnt++] != (~len & 0xff) ||
+ s->in[s->incnt++] != ((~len >> 8) & 0xff))
+ return -2; /* didn't match complement! */
+
+ /* copy len bytes from in to out */
+ if (s->incnt + len > s->inlen) return 2; /* not enough input */
+ if (s->out != NIL) {
+ if (s->outcnt + len > s->outlen)
+ return 1; /* not enough output space */
+ while (len--)
+ s->out[s->outcnt++] = s->in[s->incnt++];
+ }
+ else { /* just scanning */
+ s->outcnt += len;
+ s->incnt += len;
+ }
+
+ /* done with a valid stored block */
+ return 0;
+}
+
+/*
+ * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of
+ * each length, which for a canonical code are stepped through in order.
+ * symbol[] are the symbol values in canonical order, where the number of
+ * entries is the sum of the counts in count[]. The decoding process can be
+ * seen in the function decode() below.
+ */
+struct huffman {
+ short *count; /* number of symbols of each length */
+ short *symbol; /* canonically ordered symbols */
+};
+
+/*
+ * Decode a code from the stream s using huffman table h. Return the symbol or
+ * a negative value if there is an error. If all of the lengths are zero, i.e.
+ * an empty code, or if the code is incomplete and an invalid code is received,
+ * then -10 is returned after reading MAXBITS bits.
+ *
+ * Format notes:
+ *
+ * - The codes as stored in the compressed data are bit-reversed relative to
+ * a simple integer ordering of codes of the same lengths. Hence below the
+ * bits are pulled from the compressed data one at a time and used to
+ * build the code value reversed from what is in the stream in order to
+ * permit simple integer comparisons for decoding. A table-based decoding
+ * scheme (as used in zlib) does not need to do this reversal.
+ *
+ * - The first code for the shortest length is all zeros. Subsequent codes of
+ * the same length are simply integer increments of the previous code. When
+ * moving up a length, a zero bit is appended to the code. For a complete
+ * code, the last code of the longest length will be all ones.
+ *
+ * - Incomplete codes are handled by this decoder, since they are permitted
+ * in the deflate format. See the format notes for fixed() and dynamic().
+ */
+#ifdef SLOW
+local int decode(struct state *s, struct huffman *h)
+{
+ int len; /* current number of bits in code */
+ int code; /* len bits being decoded */
+ int first; /* first code of length len */
+ int count; /* number of codes of length len */
+ int index; /* index of first code of length len in symbol table */
+
+ code = first = index = 0;
+ for (len = 1; len <= MAXBITS; len++) {
+ code |= bits(s, 1); /* get next bit */
+ count = h->count[len];
+ if (code - count < first) /* if length len, return symbol */
+ return h->symbol[index + (code - first)];
+ index += count; /* else update for next length */
+ first += count;
+ first <<= 1;
+ code <<= 1;
+ }
+ return -10; /* ran out of codes */
+}
+
+/*
+ * A faster version of decode() for real applications of this code. It's not
+ * as readable, but it makes puff() twice as fast. And it only makes the code
+ * a few percent larger.
+ */
+#else /* !SLOW */
+local int decode(struct state *s, struct huffman *h)
+{
+ int len; /* current number of bits in code */
+ int code; /* len bits being decoded */
+ int first; /* first code of length len */
+ int count; /* number of codes of length len */
+ int index; /* index of first code of length len in symbol table */
+ int bitbuf; /* bits from stream */
+ int left; /* bits left in next or left to process */
+ short *next; /* next number of codes */
+
+ bitbuf = s->bitbuf;
+ left = s->bitcnt;
+ code = first = index = 0;
+ len = 1;
+ next = h->count + 1;
+ while (1) {
+ while (left--) {
+ code |= bitbuf & 1;
+ bitbuf >>= 1;
+ count = *next++;
+ if (code - count < first) { /* if length len, return symbol */
+ s->bitbuf = bitbuf;
+ s->bitcnt = (s->bitcnt - len) & 7;
+ return h->symbol[index + (code - first)];
+ }
+ index += count; /* else update for next length */
+ first += count;
+ first <<= 1;
+ code <<= 1;
+ len++;
+ }
+ left = (MAXBITS+1) - len;
+ if (left == 0) break;
+ if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */
+ bitbuf = s->in[s->incnt++];
+ if (left > 8) left = 8;
+ }
+ return -10; /* ran out of codes */
+}
+#endif /* SLOW */
+
+/*
+ * Given the list of code lengths length[0..n-1] representing a canonical
+ * Huffman code for n symbols, construct the tables required to decode those
+ * codes. Those tables are the number of codes of each length, and the symbols
+ * sorted by length, retaining their original order within each length. The
+ * return value is zero for a complete code set, negative for an over-
+ * subscribed code set, and positive for an incomplete code set. The tables
+ * can be used if the return value is zero or positive, but they cannot be used
+ * if the return value is negative. If the return value is zero, it is not
+ * possible for decode() using that table to return an error--any stream of
+ * enough bits will resolve to a symbol. If the return value is positive, then
+ * it is possible for decode() using that table to return an error for received
+ * codes past the end of the incomplete lengths.
+ *
+ * Not used by decode(), but used for error checking, h->count[0] is the number
+ * of the n symbols not in the code. So n - h->count[0] is the number of
+ * codes. This is useful for checking for incomplete codes that have more than
+ * one symbol, which is an error in a dynamic block.
+ *
+ * Assumption: for all i in 0..n-1, 0 <= length[i] <= MAXBITS
+ * This is assured by the construction of the length arrays in dynamic() and
+ * fixed() and is not verified by construct().
+ *
+ * Format notes:
+ *
+ * - Permitted and expected examples of incomplete codes are one of the fixed
+ * codes and any code with a single symbol which in deflate is coded as one
+ * bit instead of zero bits. See the format notes for fixed() and dynamic().
+ *
+ * - Within a given code length, the symbols are kept in ascending order for
+ * the code bits definition.
+ */
+local int construct(struct huffman *h, short *length, int n)
+{
+ int symbol; /* current symbol when stepping through length[] */
+ int len; /* current length when stepping through h->count[] */
+ int left; /* number of possible codes left of current length */
+ short offs[MAXBITS+1]; /* offsets in symbol table for each length */
+
+ /* count number of codes of each length */
+ for (len = 0; len <= MAXBITS; len++)
+ h->count[len] = 0;
+ for (symbol = 0; symbol < n; symbol++)
+ (h->count[length[symbol]])++; /* assumes lengths are within bounds */
+ if (h->count[0] == n) /* no codes! */
+ return 0; /* complete, but decode() will fail */
+
+ /* check for an over-subscribed or incomplete set of lengths */
+ left = 1; /* one possible code of zero length */
+ for (len = 1; len <= MAXBITS; len++) {
+ left <<= 1; /* one more bit, double codes left */
+ left -= h->count[len]; /* deduct count from possible codes */
+ if (left < 0) return left; /* over-subscribed--return negative */
+ } /* left > 0 means incomplete */
+
+ /* generate offsets into symbol table for each length for sorting */
+ offs[1] = 0;
+ for (len = 1; len < MAXBITS; len++)
+ offs[len + 1] = offs[len] + h->count[len];
+
+ /*
+ * put symbols in table sorted by length, by symbol order within each
+ * length
+ */
+ for (symbol = 0; symbol < n; symbol++)
+ if (length[symbol] != 0)
+ h->symbol[offs[length[symbol]]++] = symbol;
+
+ /* return zero for complete set, positive for incomplete set */
+ return left;
+}
+
+/*
+ * Decode literal/length and distance codes until an end-of-block code.
+ *
+ * Format notes:
+ *
+ * - Compressed data that is after the block type if fixed or after the code
+ * description if dynamic is a combination of literals and length/distance
+ * pairs terminated by and end-of-block code. Literals are simply Huffman
+ * coded bytes. A length/distance pair is a coded length followed by a
+ * coded distance to represent a string that occurs earlier in the
+ * uncompressed data that occurs again at the current location.
+ *
+ * - Literals, lengths, and the end-of-block code are combined into a single
+ * code of up to 286 symbols. They are 256 literals (0..255), 29 length
+ * symbols (257..285), and the end-of-block symbol (256).
+ *
+ * - There are 256 possible lengths (3..258), and so 29 symbols are not enough
+ * to represent all of those. Lengths 3..10 and 258 are in fact represented
+ * by just a length symbol. Lengths 11..257 are represented as a symbol and
+ * some number of extra bits that are added as an integer to the base length
+ * of the length symbol. The number of extra bits is determined by the base
+ * length symbol. These are in the static arrays below, lens[] for the base
+ * lengths and lext[] for the corresponding number of extra bits.
+ *
+ * - The reason that 258 gets its own symbol is that the longest length is used
+ * often in highly redundant files. Note that 258 can also be coded as the
+ * base value 227 plus the maximum extra value of 31. While a good deflate
+ * should never do this, it is not an error, and should be decoded properly.
+ *
+ * - If a length is decoded, including its extra bits if any, then it is
+ * followed a distance code. There are up to 30 distance symbols. Again
+ * there are many more possible distances (1..32768), so extra bits are added
+ * to a base value represented by the symbol. The distances 1..4 get their
+ * own symbol, but the rest require extra bits. The base distances and
+ * corresponding number of extra bits are below in the static arrays dist[]
+ * and dext[].
+ *
+ * - Literal bytes are simply written to the output. A length/distance pair is
+ * an instruction to copy previously uncompressed bytes to the output. The
+ * copy is from distance bytes back in the output stream, copying for length
+ * bytes.
+ *
+ * - Distances pointing before the beginning of the output data are not
+ * permitted.
+ *
+ * - Overlapped copies, where the length is greater than the distance, are
+ * allowed and common. For example, a distance of one and a length of 258
+ * simply copies the last byte 258 times. A distance of four and a length of
+ * twelve copies the last four bytes three times. A simple forward copy
+ * ignoring whether the length is greater than the distance or not implements
+ * this correctly. You should not use memcpy() since its behavior is not
+ * defined for overlapped arrays. You should not use memmove() or bcopy()
+ * since though their behavior -is- defined for overlapping arrays, it is
+ * defined to do the wrong thing in this case.
+ */
+local int codes(struct state *s,
+ struct huffman *lencode,
+ struct huffman *distcode)
+{
+ int symbol; /* decoded symbol */
+ int len; /* length for copy */
+ unsigned dist; /* distance for copy */
+ static const short lens[29] = { /* Size base for length codes 257..285 */
+ 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};
+ static const short lext[29] = { /* Extra bits for length codes 257..285 */
+ 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};
+ static const short dists[30] = { /* Offset base for distance codes 0..29 */
+ 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};
+ static const short dext[30] = { /* Extra bits for distance codes 0..29 */
+ 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};
+
+ /* decode literals and length/distance pairs */
+ do {
+ symbol = decode(s, lencode);
+ if (symbol < 0) return symbol; /* invalid symbol */
+ if (symbol < 256) { /* literal: symbol is the byte */
+ /* write out the literal */
+ if (s->out != NIL) {
+ if (s->outcnt == s->outlen) return 1;
+ s->out[s->outcnt] = symbol;
+ }
+ s->outcnt++;
+ }
+ else if (symbol > 256) { /* length */
+ /* get and compute length */
+ symbol -= 257;
+ if (symbol >= 29) return -10; /* invalid fixed code */
+ len = lens[symbol] + bits(s, lext[symbol]);
+
+ /* get and check distance */
+ symbol = decode(s, distcode);
+ if (symbol < 0) return symbol; /* invalid symbol */
+ dist = dists[symbol] + bits(s, dext[symbol]);
+#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ if (dist > s->outcnt)
+ return -11; /* distance too far back */
+#endif
+
+ /* copy length bytes from distance bytes back */
+ if (s->out != NIL) {
+ if (s->outcnt + len > s->outlen) return 1;
+ while (len--) {
+ s->out[s->outcnt] =
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ dist > s->outcnt ? 0 :
+#endif
+ s->out[s->outcnt - dist];
+ s->outcnt++;
+ }
+ }
+ else
+ s->outcnt += len;
+ }
+ } while (symbol != 256); /* end of block symbol */
+
+ /* done with a valid fixed or dynamic block */
+ return 0;
+}
+
+/*
+ * Process a fixed codes block.
+ *
+ * Format notes:
+ *
+ * - This block type can be useful for compressing small amounts of data for
+ * which the size of the code descriptions in a dynamic block exceeds the
+ * benefit of custom codes for that block. For fixed codes, no bits are
+ * spent on code descriptions. Instead the code lengths for literal/length
+ * codes and distance codes are fixed. The specific lengths for each symbol
+ * can be seen in the "for" loops below.
+ *
+ * - The literal/length code is complete, but has two symbols that are invalid
+ * and should result in an error if received. This cannot be implemented
+ * simply as an incomplete code since those two symbols are in the "middle"
+ * of the code. They are eight bits long and the longest literal/length\
+ * code is nine bits. Therefore the code must be constructed with those
+ * symbols, and the invalid symbols must be detected after decoding.
+ *
+ * - The fixed distance codes also have two invalid symbols that should result
+ * in an error if received. Since all of the distance codes are the same
+ * length, this can be implemented as an incomplete code. Then the invalid
+ * codes are detected while decoding.
+ */
+local int fixed(struct state *s)
+{
+ static int virgin = 1;
+ static short lencnt[MAXBITS+1], lensym[FIXLCODES];
+ static short distcnt[MAXBITS+1], distsym[MAXDCODES];
+ static struct huffman lencode, distcode;
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ int symbol;
+ short lengths[FIXLCODES];
+
+ /* literal/length table */
+ for (symbol = 0; symbol < 144; symbol++)
+ lengths[symbol] = 8;
+ for (; symbol < 256; symbol++)
+ lengths[symbol] = 9;
+ for (; symbol < 280; symbol++)
+ lengths[symbol] = 7;
+ for (; symbol < FIXLCODES; symbol++)
+ lengths[symbol] = 8;
+ construct(&lencode, lengths, FIXLCODES);
+
+ /* distance table */
+ for (symbol = 0; symbol < MAXDCODES; symbol++)
+ lengths[symbol] = 5;
+ construct(&distcode, lengths, MAXDCODES);
+
+ /* construct lencode and distcode */
+ lencode.count = lencnt;
+ lencode.symbol = lensym;
+ distcode.count = distcnt;
+ distcode.symbol = distsym;
+
+ /* do this just once */
+ virgin = 0;
+ }
+
+ /* decode data until end-of-block code */
+ return codes(s, &lencode, &distcode);
+}
+
+/*
+ * Process a dynamic codes block.
+ *
+ * Format notes:
+ *
+ * - A dynamic block starts with a description of the literal/length and
+ * distance codes for that block. New dynamic blocks allow the compressor to
+ * rapidly adapt to changing data with new codes optimized for that data.
+ *
+ * - The codes used by the deflate format are "canonical", which means that
+ * the actual bits of the codes are generated in an unambiguous way simply
+ * from the number of bits in each code. Therefore the code descriptions
+ * are simply a list of code lengths for each symbol.
+ *
+ * - The code lengths are stored in order for the symbols, so lengths are
+ * provided for each of the literal/length symbols, and for each of the
+ * distance symbols.
+ *
+ * - If a symbol is not used in the block, this is represented by a zero as
+ * as the code length. This does not mean a zero-length code, but rather
+ * that no code should be created for this symbol. There is no way in the
+ * deflate format to represent a zero-length code.
+ *
+ * - The maximum number of bits in a code is 15, so the possible lengths for
+ * any code are 1..15.
+ *
+ * - The fact that a length of zero is not permitted for a code has an
+ * interesting consequence. Normally if only one symbol is used for a given
+ * code, then in fact that code could be represented with zero bits. However
+ * in deflate, that code has to be at least one bit. So for example, if
+ * only a single distance base symbol appears in a block, then it will be
+ * represented by a single code of length one, in particular one 0 bit. This
+ * is an incomplete code, since if a 1 bit is received, it has no meaning,
+ * and should result in an error. So incomplete distance codes of one symbol
+ * should be permitted, and the receipt of invalid codes should be handled.
+ *
+ * - It is also possible to have a single literal/length code, but that code
+ * must be the end-of-block code, since every dynamic block has one. This
+ * is not the most efficient way to create an empty block (an empty fixed
+ * block is fewer bits), but it is allowed by the format. So incomplete
+ * literal/length codes of one symbol should also be permitted.
+ *
+ * - If there are only literal codes and no lengths, then there are no distance
+ * codes. This is represented by one distance code with zero bits.
+ *
+ * - The list of up to 286 length/literal lengths and up to 30 distance lengths
+ * are themselves compressed using Huffman codes and run-length encoding. In
+ * the list of code lengths, a 0 symbol means no code, a 1..15 symbol means
+ * that length, and the symbols 16, 17, and 18 are run-length instructions.
+ * Each of 16, 17, and 18 are follwed by extra bits to define the length of
+ * the run. 16 copies the last length 3 to 6 times. 17 represents 3 to 10
+ * zero lengths, and 18 represents 11 to 138 zero lengths. Unused symbols
+ * are common, hence the special coding for zero lengths.
+ *
+ * - The symbols for 0..18 are Huffman coded, and so that code must be
+ * described first. This is simply a sequence of up to 19 three-bit values
+ * representing no code (0) or the code length for that symbol (1..7).
+ *
+ * - A dynamic block starts with three fixed-size counts from which is computed
+ * the number of literal/length code lengths, the number of distance code
+ * lengths, and the number of code length code lengths (ok, you come up with
+ * a better name!) in the code descriptions. For the literal/length and
+ * distance codes, lengths after those provided are considered zero, i.e. no
+ * code. The code length code lengths are received in a permuted order (see
+ * the order[] array below) to make a short code length code length list more
+ * likely. As it turns out, very short and very long codes are less likely
+ * to be seen in a dynamic code description, hence what may appear initially
+ * to be a peculiar ordering.
+ *
+ * - Given the number of literal/length code lengths (nlen) and distance code
+ * lengths (ndist), then they are treated as one long list of nlen + ndist
+ * code lengths. Therefore run-length coding can and often does cross the
+ * boundary between the two sets of lengths.
+ *
+ * - So to summarize, the code description at the start of a dynamic block is
+ * three counts for the number of code lengths for the literal/length codes,
+ * the distance codes, and the code length codes. This is followed by the
+ * code length code lengths, three bits each. This is used to construct the
+ * code length code which is used to read the remainder of the lengths. Then
+ * the literal/length code lengths and distance lengths are read as a single
+ * set of lengths using the code length codes. Codes are constructed from
+ * the resulting two sets of lengths, and then finally you can start
+ * decoding actual compressed data in the block.
+ *
+ * - For reference, a "typical" size for the code description in a dynamic
+ * block is around 80 bytes.
+ */
+local int dynamic(struct state *s)
+{
+ int nlen, ndist, ncode; /* number of lengths in descriptor */
+ int index; /* index of lengths[] */
+ int err; /* construct() return value */
+ short lengths[MAXCODES]; /* descriptor code lengths */
+ short lencnt[MAXBITS+1], lensym[MAXLCODES]; /* lencode memory */
+ short distcnt[MAXBITS+1], distsym[MAXDCODES]; /* distcode memory */
+ struct huffman lencode, distcode; /* length and distance codes */
+ static const short order[19] = /* permutation of code length codes */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ /* construct lencode and distcode */
+ lencode.count = lencnt;
+ lencode.symbol = lensym;
+ distcode.count = distcnt;
+ distcode.symbol = distsym;
+
+ /* get number of lengths in each table, check lengths */
+ nlen = bits(s, 5) + 257;
+ ndist = bits(s, 5) + 1;
+ ncode = bits(s, 4) + 4;
+ if (nlen > MAXLCODES || ndist > MAXDCODES)
+ return -3; /* bad counts */
+
+ /* read code length code lengths (really), missing lengths are zero */
+ for (index = 0; index < ncode; index++)
+ lengths[order[index]] = bits(s, 3);
+ for (; index < 19; index++)
+ lengths[order[index]] = 0;
+
+ /* build huffman table for code lengths codes (use lencode temporarily) */
+ err = construct(&lencode, lengths, 19);
+ if (err != 0) return -4; /* require complete code set here */
+
+ /* read length/literal and distance code length tables */
+ index = 0;
+ while (index < nlen + ndist) {
+ int symbol; /* decoded value */
+ int len; /* last length to repeat */
+
+ symbol = decode(s, &lencode);
+ if (symbol < 16) /* length in 0..15 */
+ lengths[index++] = symbol;
+ else { /* repeat instruction */
+ len = 0; /* assume repeating zeros */
+ if (symbol == 16) { /* repeat last length 3..6 times */
+ if (index == 0) return -5; /* no last length! */
+ len = lengths[index - 1]; /* last length */
+ symbol = 3 + bits(s, 2);
+ }
+ else if (symbol == 17) /* repeat zero 3..10 times */
+ symbol = 3 + bits(s, 3);
+ else /* == 18, repeat zero 11..138 times */
+ symbol = 11 + bits(s, 7);
+ if (index + symbol > nlen + ndist)
+ return -6; /* too many lengths! */
+ while (symbol--) /* repeat last or zero symbol times */
+ lengths[index++] = len;
+ }
+ }
+
+ /* check for end-of-block code -- there better be one! */
+ if (lengths[256] == 0)
+ return -9;
+
+ /* build huffman table for literal/length codes */
+ err = construct(&lencode, lengths, nlen);
+ if (err < 0 || (err > 0 && nlen - lencode.count[0] != 1))
+ return -7; /* only allow incomplete codes if just one code */
+
+ /* build huffman table for distance codes */
+ err = construct(&distcode, lengths + nlen, ndist);
+ if (err < 0 || (err > 0 && ndist - distcode.count[0] != 1))
+ return -8; /* only allow incomplete codes if just one code */
+
+ /* decode data until end-of-block code */
+ return codes(s, &lencode, &distcode);
+}
+
+/*
+ * Inflate source to dest. On return, destlen and sourcelen are updated to the
+ * size of the uncompressed data and the size of the deflate data respectively.
+ * On success, the return value of puff() is zero. If there is an error in the
+ * source data, i.e. it is not in the deflate format, then a negative value is
+ * returned. If there is not enough input available or there is not enough
+ * output space, then a positive error is returned. In that case, destlen and
+ * sourcelen are not updated to facilitate retrying from the beginning with the
+ * provision of more input data or more output space. In the case of invalid
+ * inflate data (a negative error), the dest and source pointers are updated to
+ * facilitate the debugging of deflators.
+ *
+ * puff() also has a mode to determine the size of the uncompressed output with
+ * no output written. For this dest must be (unsigned char *)0. In this case,
+ * the input value of *destlen is ignored, and on return *destlen is set to the
+ * size of the uncompressed output.
+ *
+ * The return codes are:
+ *
+ * 2: available inflate data did not terminate
+ * 1: output space exhausted before completing inflate
+ * 0: successful inflate
+ * -1: invalid block type (type == 3)
+ * -2: stored block length did not match one's complement
+ * -3: dynamic block code description: too many length or distance codes
+ * -4: dynamic block code description: code lengths codes incomplete
+ * -5: dynamic block code description: repeat lengths with no first length
+ * -6: dynamic block code description: repeat more than specified lengths
+ * -7: dynamic block code description: invalid literal/length code lengths
+ * -8: dynamic block code description: invalid distance code lengths
+ * -9: dynamic block code description: missing end-of-block code
+ * -10: invalid literal/length or distance code in fixed or dynamic block
+ * -11: distance is too far back in fixed or dynamic block
+ *
+ * Format notes:
+ *
+ * - Three bits are read for each block to determine the kind of block and
+ * whether or not it is the last block. Then the block is decoded and the
+ * process repeated if it was not the last block.
+ *
+ * - The leftover bits in the last byte of the deflate data after the last
+ * block (if it was a fixed or dynamic block) are undefined and have no
+ * expected values to check.
+ */
+int puff(unsigned char *dest, /* pointer to destination pointer */
+ unsigned long *destlen, /* amount of output space */
+ const unsigned char *source, /* pointer to source data pointer */
+ unsigned long *sourcelen) /* amount of input available */
+{
+ struct state s; /* input/output state */
+ int last, type; /* block information */
+ int err; /* return value */
+
+ /* initialize output state */
+ s.out = dest;
+ s.outlen = *destlen; /* ignored if dest is NIL */
+ s.outcnt = 0;
+
+ /* initialize input state */
+ s.in = source;
+ s.inlen = *sourcelen;
+ s.incnt = 0;
+ s.bitbuf = 0;
+ s.bitcnt = 0;
+
+ /* return if bits() or decode() tries to read past available input */
+ if (setjmp(s.env) != 0) /* if came back here via longjmp() */
+ err = 2; /* then skip do-loop, return error */
+ else {
+ /* process blocks until last block or error */
+ do {
+ last = bits(&s, 1); /* one if last block */
+ type = bits(&s, 2); /* block type 0..3 */
+ err = type == 0 ? stored(&s) :
+ (type == 1 ? fixed(&s) :
+ (type == 2 ? dynamic(&s) :
+ -1)); /* type == 3, invalid */
+ if (err != 0) break; /* return with error */
+ } while (!last);
+ }
+
+ /* update the lengths and return */
+ if (err <= 0) {
+ *destlen = s.outcnt;
+ *sourcelen = s.incnt;
+ }
+ return err;
+}
+
+#ifdef TEST
+/* Examples of how to use puff().
+
+ Usage: puff [-w] [-nnn] file
+ ... | puff [-w] [-nnn]
+
+ where file is the input file with deflate data, nnn is the number of bytes
+ of input to skip before inflating (e.g. to skip a zlib or gzip header), and
+ -w is used to write the decompressed data to stdout */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Return size times approximately the cube root of 2, keeping the result as 1,
+ 3, or 5 times a power of 2 -- the result is always > size, until the result
+ is the maximum value of an unsigned long, where it remains. This is useful
+ to keep reallocations less than ~33% over the actual data. */
+local size_t bythirds(size_t size)
+{
+ int n;
+ size_t m;
+
+ m = size;
+ for (n = 0; m; n++)
+ m >>= 1;
+ if (n < 3)
+ return size + 1;
+ n -= 3;
+ m = size >> n;
+ m += m == 6 ? 2 : 1;
+ m <<= n;
+ return m > size ? m : (size_t)(-1);
+}
+
+/* Read the input file *name, or stdin if name is NULL, into allocated memory.
+ Reallocate to larger buffers until the entire file is read in. Return a
+ pointer to the allocated data, or NULL if there was a memory allocation
+ failure. *len is the number of bytes of data read from the input file (even
+ if load() returns NULL). If the input file was empty or could not be opened
+ or read, *len is zero. */
+local void *load(char *name, size_t *len)
+{
+ size_t size;
+ void *buf, *swap;
+ FILE *in;
+
+ *len = 0;
+ buf = malloc(size = 4096);
+ if (buf == NULL)
+ return NULL;
+ in = name == NULL ? stdin : fopen(name, "rb");
+ if (in != NULL) {
+ for (;;) {
+ *len += fread((char *)buf + *len, 1, size - *len, in);
+ if (*len < size) break;
+ size = bythirds(size);
+ if (size == *len || (swap = realloc(buf, size)) == NULL) {
+ free(buf);
+ buf = NULL;
+ break;
+ }
+ buf = swap;
+ }
+ fclose(in);
+ }
+ return buf;
+}
+
+int main(int argc, char **argv)
+{
+ int ret, put = 0;
+ unsigned skip = 0;
+ char *arg, *name = NULL;
+ unsigned char *source = NULL, *dest;
+ size_t len = 0;
+ unsigned long sourcelen, destlen;
+
+ /* process arguments */
+ while (arg = *++argv, --argc)
+ if (arg[0] == '-') {
+ if (arg[1] == 'w' && arg[2] == 0)
+ put = 1;
+ else if (arg[1] >= '0' && arg[1] <= '9')
+ skip = (unsigned)atoi(arg + 1);
+ else {
+ fprintf(stderr, "invalid option %s\n", arg);
+ return 3;
+ }
+ }
+ else if (name != NULL) {
+ fprintf(stderr, "only one file name allowed\n");
+ return 3;
+ }
+ else
+ name = arg;
+ source = load(name, &len);
+ if (source == NULL) {
+ fprintf(stderr, "memory allocation failure\n");
+ return 4;
+ }
+ if (len == 0) {
+ fprintf(stderr, "could not read %s, or it was empty\n",
+ name == NULL ? "<stdin>" : name);
+ free(source);
+ return 3;
+ }
+ if (skip >= len) {
+ fprintf(stderr, "skip request of %d leaves no input\n", skip);
+ free(source);
+ return 3;
+ }
+
+ /* test inflate data with offset skip */
+ len -= skip;
+ sourcelen = (unsigned long)len;
+ ret = puff(NIL, &destlen, source + skip, &sourcelen);
+ if (ret)
+ fprintf(stderr, "puff() failed with return code %d\n", ret);
+ else {
+ fprintf(stderr, "puff() succeeded uncompressing %lu bytes\n", destlen);
+ if (sourcelen < len) fprintf(stderr, "%lu compressed bytes unused\n",
+ len - sourcelen);
+ }
+
+ /* if requested, inflate again and write decompressd data to stdout */
+ if (put) {
+ dest = malloc(destlen);
+ if (dest == NULL) {
+ fprintf(stderr, "memory allocation failure\n");
+ free(source);
+ return 4;
+ }
+ puff(dest, &destlen, source + skip, &sourcelen);
+ fwrite(dest, 1, destlen, stdout);
+ free(dest);
+ }
+
+ /* clean up */
+ free(source);
+ return ret;
+}
+#endif
diff --git a/redist/puff.h b/redist/puff.h
new file mode 100644
index 0000000..eef7139
--- /dev/null
+++ b/redist/puff.h
@@ -0,0 +1,31 @@
+/* puff.h
+ Copyright (C) 2002-2010 Mark Adler, all rights reserved
+ version 2.1, 4 Apr 2010
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the author 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.
+
+ Mark Adler madler@alumni.caltech.edu
+ */
+
+
+/*
+ * See puff.c for purpose and usage.
+ */
+int puff(unsigned char *dest, /* pointer to destination pointer */
+ unsigned long *destlen, /* amount of output space */
+ const unsigned char *source, /* pointer to source data pointer */
+ unsigned long *sourcelen); /* amount of input available */ \ No newline at end of file
diff --git a/redist/symbol_enumerator.c b/redist/symbol_enumerator.c
new file mode 100644
index 0000000..eddddb9
--- /dev/null
+++ b/redist/symbol_enumerator.c
@@ -0,0 +1,241 @@
+#include <stdio.h>
+#include "symbol_enumerator.h"
+
+#if defined( WIN32 ) || defined( WINDOWS ) || defined( USE_WINDOWS )
+
+#include <windows.h>
+
+typedef struct _SYMBOL_INFO {
+ ULONG SizeOfStruct;
+ ULONG TypeIndex;
+ ULONG64 Reserved[2];
+ ULONG Index;
+ ULONG Size;
+ ULONG64 ModBase;
+ ULONG Flags;
+ ULONG64 Value;
+ ULONG64 Address;
+ ULONG Register;
+ ULONG Scope;
+ ULONG Tag;
+ ULONG NameLen;
+ ULONG MaxNameLen;
+ TCHAR Name[1];
+} SYMBOL_INFO, *PSYMBOL_INFO;
+typedef struct _IMAGEHLP_STACK_FRAME {
+ ULONG64 InstructionOffset;
+ ULONG64 ReturnOffset;
+ ULONG64 FrameOffset;
+ ULONG64 StackOffset;
+ ULONG64 BackingStoreOffset;
+ ULONG64 FuncTableEntry;
+ ULONG64 Params[4];
+ ULONG64 Reserved[5];
+ BOOL Virtual;
+ ULONG Reserved2;
+} IMAGEHLP_STACK_FRAME, *PIMAGEHLP_STACK_FRAME;
+
+
+typedef BOOL (*PSYM_ENUMERATESYMBOLS_CALLBACK)(
+ PSYMBOL_INFO pSymInfo,
+ ULONG SymbolSize,
+ PVOID UserContext
+ );
+
+BOOL WINAPI SymEnumSymbols(
+ HANDLE hProcess,
+ ULONG64 BaseOfDll,
+ PCTSTR Mask,
+ PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
+ const PVOID UserContext
+);
+
+BOOL WINAPI SymInitialize(
+ HANDLE hProcess,
+ PCTSTR UserSearchPath,
+ BOOL fInvadeProcess
+);
+
+BOOL CALLBACK __cdecl mycb(
+ PSYMBOL_INFO pSymInfo,
+ ULONG SymbolSize,
+ PVOID UserContext
+ ){
+ SymEnumeratorCallback cb = (SymEnumeratorCallback)UserContext;
+ return !cb( "", &pSymInfo->Name[0], (void*)pSymInfo->Address, (long) pSymInfo->Size );
+ }
+
+int EnumerateSymbols( SymEnumeratorCallback cb )
+{
+ HANDLE proc = GetCurrentProcess();
+ if( !SymInitialize( proc, 0, 1 ) ) return -1;
+ if( !SymEnumSymbols( proc, 0, "*!*", &mycb, (void*)cb ) )
+ {
+ SymCleanup(proc);
+ return -2;
+ }
+ SymCleanup(proc);
+ return 0;
+}
+
+#else
+
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <stdint.h>
+#include <limits.h>
+#include <string.h>
+
+#ifndef __GNUC__
+#define __int128_t long long long
+#endif
+
+#include <link.h>
+#include <elf.h>
+
+#define UINTS_PER_WORD (__WORDSIZE / (CHAR_BIT * sizeof (unsigned int)))
+
+
+ struct dl_phdr_info {
+ ElfW(Addr) dlpi_addr; /* Base address of object */
+ const char *dlpi_name; /* (Null-terminated) name of
+ object */
+ const ElfW(Phdr) *dlpi_phdr; /* Pointer to array of
+ ELF program headers
+ for this object */
+ ElfW(Half) dlpi_phnum; /* # of items in dlpi_phdr */
+ };
+
+
+
+void dl_iterate_phdr( void*, void*);
+
+
+static ElfW(Word) gnu_hashtab_symbol_count(const unsigned int *const table)
+{
+ const unsigned int *const bucket = table + 4 + table[2] * (unsigned int)(UINTS_PER_WORD);
+ unsigned int b = table[0];
+ unsigned int max = 0U;
+
+ while (b-->0U)
+ if (bucket[b] > max)
+ max = bucket[b];
+
+ return (ElfW(Word))max;
+}
+
+static static void *dynamic_pointer(const ElfW(Addr) addr,
+ const ElfW(Addr) base, const ElfW(Phdr) *const header, const ElfW(Half) headers)
+{
+ if (addr) {
+ ElfW(Half) h;
+
+ for (h = 0; h < headers; h++)
+ if (header[h].p_type == PT_LOAD)
+ if (addr >= base + header[h].p_vaddr &&
+ addr < base + header[h].p_vaddr + header[h].p_memsz)
+ return (void *)addr;
+ }
+
+ return NULL;
+}
+
+//Mostly based off of http://stackoverflow.com/questions/29903049/get-names-and-addresses-of-exported-functions-from-in-linux
+static int callback(struct dl_phdr_info *info,
+ size_t size, void *data)
+{
+ SymEnumeratorCallback cb = (SymEnumeratorCallback)data;
+ const ElfW(Addr) base = info->dlpi_addr;
+ const ElfW(Phdr) *const header = info->dlpi_phdr;
+ const ElfW(Half) headers = info->dlpi_phnum;
+ const char *libpath, *libname;
+ ElfW(Half) h;
+
+ if (info->dlpi_name && info->dlpi_name[0])
+ libpath = info->dlpi_name;
+ else
+ libpath = "";
+
+ libname = strrchr(libpath, '/');
+
+ if (libname && libname[0] == '/' && libname[1])
+ libname++;
+ else
+ libname = libpath;
+
+ for (h = 0; h < headers; h++)
+ {
+ if (header[h].p_type == PT_DYNAMIC)
+ {
+ const ElfW(Dyn) *entry = (const ElfW(Dyn) *)(base + header[h].p_vaddr);
+ const ElfW(Word) *hashtab;
+ const ElfW(Sym) *symtab = NULL;
+ const char *strtab = NULL;
+ ElfW(Word) symbol_count = 0;
+
+ for (; entry->d_tag != DT_NULL; entry++)
+ {
+ switch (entry->d_tag)
+ {
+ case DT_HASH:
+ hashtab = dynamic_pointer(entry->d_un.d_ptr, base, header, headers);
+ if (hashtab)
+ symbol_count = hashtab[1];
+ break;
+ case DT_GNU_HASH:
+ hashtab = dynamic_pointer(entry->d_un.d_ptr, base, header, headers);
+ if (hashtab)
+ {
+ ElfW(Word) count = gnu_hashtab_symbol_count(hashtab);
+ if (count > symbol_count)
+ symbol_count = count;
+ }
+ break;
+ case DT_STRTAB:
+ strtab = dynamic_pointer(entry->d_un.d_ptr, base, header, headers);
+ break;
+ case DT_SYMTAB:
+ symtab = dynamic_pointer(entry->d_un.d_ptr, base, header, headers);
+ break;
+ }
+ }
+
+ if (symtab && strtab && symbol_count > 0) {
+ ElfW(Word) s;
+
+ for (s = 0; s < symbol_count; s++) {
+ const char *name;
+ void *const ptr = dynamic_pointer(base + symtab[s].st_value, base, header, headers);
+ int result;
+
+ if (!ptr)
+ continue;
+
+ if (symtab[s].st_name)
+ name = strtab + symtab[s].st_name;
+ else
+ name = "";
+
+ result = cb( libpath, name, ptr, symtab[s].st_size );
+ if( result ) return result; //Bail early.
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+
+
+
+
+int EnumerateSymbols( SymEnumeratorCallback cb )
+{
+ dl_iterate_phdr( callback, cb );
+}
+
+
+
+
+#endif
diff --git a/redist/symbol_enumerator.h b/redist/symbol_enumerator.h
new file mode 100644
index 0000000..87e033b
--- /dev/null
+++ b/redist/symbol_enumerator.h
@@ -0,0 +1,12 @@
+#ifndef _SYMBOL_ENUMERATOR_H
+#define _SYMBOL_ENUMERATOR_H
+
+//Enumerates all symbols in the currently loaded excutable.
+//Don't forget to compile with -rdynamic!
+
+//Return 0 to continue search. 1 to stop.
+typedef int (*SymEnumeratorCallback)( const char * path, const char * name, void * location, long size );
+
+int EnumerateSymbols( SymEnumeratorCallback cb );
+
+#endif