texlive[48593] Build/source/texk/web2c/luatexdir/luapplib: pplib for

commits+lscarso at tug.org commits+lscarso at tug.org
Wed Sep 5 23:35:27 CEST 2018


Revision: 48593
          http://tug.org/svn/texlive?view=revision&revision=48593
Author:   lscarso
Date:     2018-09-05 23:35:27 +0200 (Wed, 05 Sep 2018)
Log Message:
-----------
pplib for luatex: removed udeless files

Removed Paths:
-------------
    trunk/Build/source/texk/web2c/luatexdir/luapplib/ppapi.h-OK
    trunk/Build/source/texk/web2c/luatexdir/luapplib/ppload.c-OK
    trunk/Build/source/texk/web2c/luatexdir/luapplib/util/utilfpred.c-OK
    trunk/Build/source/texk/web2c/luatexdir/luapplib/util/utiliof.c-OK
    trunk/Build/source/texk/web2c/luatexdir/luapplib/util/utilsha.c-OK

Deleted: trunk/Build/source/texk/web2c/luatexdir/luapplib/ppapi.h-OK
===================================================================
--- trunk/Build/source/texk/web2c/luatexdir/luapplib/ppapi.h-OK	2018-09-05 21:32:42 UTC (rev 48592)
+++ trunk/Build/source/texk/web2c/luatexdir/luapplib/ppapi.h-OK	2018-09-05 21:35:27 UTC (rev 48593)
@@ -1,360 +0,0 @@
-
-#ifndef PP_API_H
-#define PP_API_H
-
-#include <stdint.h>
-#include <stddef.h>
-#include <string.h>
-
-#include "ppconf.h"
-
-#define pplib_version "v0.97"
-#define pplib_author "p.jackowski at gust.org.pl"
-
-/* types */
-
-typedef int64_t ppint;
-typedef size_t ppuint; // machine word
-
-typedef double ppnum;
-typedef char * ppname;
-typedef char * ppstring;
-
-typedef struct {
-  size_t size;
-  int flags;
-} _ppname;
-
-typedef struct {
-  size_t size;
-  int flags;
-} _ppstring;
-
-typedef struct ppobj ppobj;
-typedef struct ppref ppref;
-
-typedef struct {
-  ppobj *data;
-  size_t size;
-} pparray;
-
-typedef struct {
-  ppobj *data;
-	ppname *keys;
-  size_t size;
-} ppdict;
-
-typedef struct {
-  ppdict *dict;
-  void *input, *I;
-  size_t offset;
-  size_t length;
-  ppstring cryptkey;
-  int flags;
-} ppstream;
-
-#define PPSTREAM_COMPRESSED (1<<0)
-#define PPSTREAM_ENCRYPTED_AES (1<<1)
-#define PPSTREAM_ENCRYPTED_RC4 (1<<2)
-#define PPSTREAM_ENCRYPTED (PPSTREAM_ENCRYPTED_AES|PPSTREAM_ENCRYPTED_RC4)
-#define PPSTREAM_ENCRYPTED_OWN (1<<3)
-
-#define ppstream_compressed(stream) ((stream)->flags & PPSTREAM_COMPRESSED)
-#define ppstream_encrypted(stream) ((stream)->flags & PPSTREAM_ENCRYPTED)
-
-typedef enum {
-  PPNONE = 0,
-  PPNULL,
-  PPBOOL,
-  PPINT,
-  PPNUM,
-  PPNAME,
-  PPSTRING,
-  PPARRAY,
-  PPDICT,
-  PPSTREAM,
-  PPREF
-} ppobjtp;
-
-PPDEF extern const char * ppobj_kind[];
-
-struct ppobj {
-  ppobjtp type;
-  union {
-    ppint integer;
-    ppnum number;
-    ppname name;
-    ppstring string;
-    pparray *array;
-    ppdict *dict;
-    ppstream *stream;
-    ppref *ref;
-    void *any;
-  };
-};
-
-typedef struct ppxref ppxref;
-
-struct ppref {
-  ppobj object;
-  ppuint number, version;
-  size_t offset;
-  size_t length;
-  ppxref *xref;
-};
-
-typedef struct ppdoc ppdoc;
-
-/* object */
-
-#define ppobj_get_null(o) ((o)->type == PPNULL ? 1 : 0)
-#define ppobj_get_bool(o, v) ((o)->type == PPBOOL ? ((v = ((o)->integer != 0)), 1) : 0)
-#define ppobj_get_int(o, v) ((o)->type == PPINT ? ((v = (o)->integer), 1) : 0)
-#define ppobj_get_uint(o, v) ((o)->type == PPINT && (o)->integer >= 0 ? ((v = (ppuint)((o)->integer)), 1) : 0)
-#define ppobj_get_num(o, v) ((o)->type == PPNUM ? ((v = (o)->number), 1) : (((o)->type == PPINT ? ((v = (ppnum)((o)->integer)), 1) : 0)))
-#define ppobj_get_name(o) ((o)->type == PPNAME ? (o)->name : NULL)
-#define ppobj_get_string(o) ((o)->type == PPSTRING ? (o)->string : NULL)
-#define ppobj_get_array(o) ((o)->type == PPARRAY ? (o)->array : NULL)
-#define ppobj_get_dict(o) ((o)->type == PPDICT ? (o)->dict : NULL)
-#define ppobj_get_stream(o) ((o)->type == PPSTREAM ? (o)->stream : NULL)
-#define ppobj_get_ref(o) ((o)->type == PPREF ? (o)->ref : NULL)
-
-#define ppobj_rget_obj(o) ((o)->type == PPREF ? ppref_obj((o)->ref) : o)
-#define ppobj_rget_null(o) ((o)->type == PPNULL ? 1 : ((o)->type == PPREF ? ppobj_get_null(ppref_obj((o)->ref)) : 0))
-#define ppobj_rget_bool(o, v) ((o)->type == PPBOOL ? ((v = ((o)->integer != 0)), 1) : ((o)->type == PPREF ? ppobj_get_bool(ppref_obj((o)->ref), v) : 0))
-#define ppobj_rget_int(o, v) ((o)->type == PPINT ? ((v = (o)->integer), 1) : ((o)->type == PPREF ? ppobj_get_int(ppref_obj((o)->ref), v) : 0))
-#define ppobj_rget_uint(o, v) ((o)->type == PPINT && (o)->integer >= 0 ? ((v = (ppuint)((o)->integer)), 1) : ((o)->type == PPREF ? ppobj_get_uint(ppref_obj((o)->ref), v) : 0))
-#define ppobj_rget_num(o, v) ((o)->type == PPNUM ? ((v = (o)->number), 1) : (((o)->type == PPINT ? ((v = (ppnum)((o)->integer)), 1) : ((o)->type == PPREF ? ppobj_get_num(ppref_obj((o)->ref), v) : 0))))
-#define ppobj_rget_name(o) ((o)->type == PPNAME ? (o)->name : ((o)->type == PPREF ? ppobj_get_name(ppref_obj((o)->ref)) : NULL))
-#define ppobj_rget_string(o) ((o)->type == PPSTRING ? (o)->string : ((o)->type == PPREF ? ppobj_get_string(ppref_obj((o)->ref)) : NULL))
-#define ppobj_rget_array(o) ((o)->type == PPARRAY ? (o)->array : ((o)->type == PPREF ? ppobj_get_array(ppref_obj((o)->ref)) : NULL))
-#define ppobj_rget_dict(o) ((o)->type == PPDICT ? (o)->dict : ((o)->type == PPREF ? ppobj_get_dict(ppref_obj((o)->ref)) : NULL))
-#define ppobj_rget_stream(o) ((o)->type == PPSTREAM ? (o)->stream : ((o)->type == PPREF ? ppobj_get_stream(ppref_obj((o)->ref)) : NULL))
-#define ppobj_rget_ref(o) ((o)->type == PPREF ? (o)->ref : ((o)->type == PPREF ? ppobj_get_ref(ppref_obj((o)->ref)) : NULL))
-
-#define ppobj_get_bool_value(o) ((o)->type == PPBOOL ? ((o)->integer != 0) : 0)
-#define ppobj_get_int_value(o) ((o)->type == PPINT ? (o)->integer : 0)
-#define ppobj_get_num_value(o) ((o)->type == PPNUM  ? (o)->number : ((o)->type == PPINT  ? (ppnum)((o)->integer) : 0.0))
-
-/* name */
-
-#define ppname_is(name, s) (memcmp(name, s, sizeof("" s) - 1) == 0)
-#define ppname_eq(name, n) (memcmp(name, s, ppname_size(name)) == 0)
-
-#define _ppname_ghost(name) (((const _ppname *)(name)) - 1)
-#define ppname_size(name) (_ppname_ghost(name)->size)
-#define ppname_exec(name) (_ppname_ghost(name)->flags & PPNAME_EXEC)
-
-#define PPNAME_ENCODED (1 << 0)
-#define PPNAME_DECODED (1 << 1)
-#define PPNAME_EXEC (1 << 1)
-
-PPAPI ppname ppname_decoded (ppname name);
-PPAPI ppname ppname_encoded (ppname name);
-
-/* string */
-
-#define _ppstring_ghost(string) (((const _ppstring *)(string)) - 1)
-#define ppstring_size(string) (_ppstring_ghost(string)->size)
-
-#define PPSTRING_ENCODED (1 << 0)
-#define PPSTRING_DECODED (1 << 1)
-//#define PPSTRING_EXEC (1 << 2) // postscript only
-#define PPSTRING_PLAIN 0
-#define PPSTRING_BASE16 (1 << 3)
-#define PPSTRING_BASE85 (1 << 4)
-#define PPSTRING_UTF16BE (1 << 5)
-#define PPSTRING_UTF16LE (1 << 6)
-
-#define ppstring_type(string) (_ppstring_ghost(string)->flags & (PPSTRING_BASE16|PPSTRING_BASE85))
-#define ppstring_hex(string) (_ppstring_ghost(string)->flags & PPSTRING_BASE16)
-#define ppstring_utf(string) (_ppstring_ghost(string)->flags & (PPSTRING_UTF16BE|PPSTRING_UTF16LE))
-
-PPAPI ppstring ppstring_decoded (ppstring string);
-PPAPI ppstring ppstring_encoded (ppstring string);
-
-/* array */
-
-#define pparray_size(array) ((array)->size)
-#define pparray_at(array, index) ((array)->data + index)
-
-#define pparray_first(array, index, obj) ((index) = 0, (obj) = pparray_at(array,  0))
-#define pparray_next(index, obj) (++(index), ++(obj))
-
-#define pparray_get(array, index) (index < (array)->size ? pparray_at(array, index) : NULL)
-
-PPAPI ppobj * pparray_get_obj (pparray *array, size_t index);
-PPAPI int pparray_get_bool (pparray *array, size_t index, int *v);
-PPAPI int pparray_get_int (pparray *array, size_t index, ppint *v);
-PPAPI int pparray_get_uint (pparray *array, size_t index, ppuint *v);
-PPAPI int pparray_get_num (pparray *array, size_t index, ppnum *v);
-PPAPI ppname pparray_get_name (pparray *array, size_t index);
-PPAPI ppstring pparray_get_string (pparray *array, size_t index);
-PPAPI pparray * pparray_get_array (pparray *array, size_t index);
-PPAPI ppdict * pparray_get_dict (pparray *array, size_t index);
-//PPAPI ppstream * pparray_get_stream (pparray *array, size_t index);
-PPAPI ppref * pparray_get_ref (pparray *array, size_t index);
-
-PPAPI ppobj * pparray_rget_obj (pparray *array, size_t index);
-PPAPI int pparray_rget_bool (pparray *array, size_t index, int *v);
-PPAPI int pparray_rget_int (pparray *array, size_t index, ppint *v);
-PPAPI int pparray_rget_uint (pparray *array, size_t index, ppuint *v);
-PPAPI int pparray_rget_num (pparray *array, size_t index, ppnum *v);
-PPAPI ppname pparray_rget_name (pparray *array, size_t index);
-PPAPI ppstring pparray_rget_string (pparray *array, size_t index);
-PPAPI pparray * pparray_rget_array (pparray *array, size_t index);
-PPAPI ppdict * pparray_rget_dict (pparray *array, size_t index);
-PPAPI ppstream * pparray_rget_stream (pparray *array, size_t index);
-PPAPI ppref * pparray_rget_ref (pparray *array, size_t index);
-
-/* dict */
-
-#define ppdict_size(dict) ((dict)->size)
-#define ppdict_at(dict, index) ((dict)->data + index)
-#define ppdict_key(dict, index) ((dict)->keys[index])
-
-PPAPI ppobj * ppdict_get_obj (ppdict *dict, const char *name);
-PPAPI int ppdict_get_bool (ppdict *dict, const char *name, int *v);
-PPAPI int ppdict_get_int (ppdict *dict, const char *name, ppint *v);
-PPAPI int ppdict_get_uint (ppdict *dict, const char *name, ppuint *v);
-PPAPI int ppdict_get_num (ppdict *dict, const char *name, ppnum *v);
-PPAPI ppname ppdict_get_name (ppdict *dict, const char *name);
-PPAPI ppstring ppdict_get_string (ppdict *dict, const char *name);
-PPAPI pparray * ppdict_get_array (ppdict *dict, const char *name);
-PPAPI ppdict * ppdict_get_dict (ppdict *dict, const char *name);
-//PPAPI ppstream * ppdict_get_stream (ppdict *dict, const char *name);
-PPAPI ppref * ppdict_get_ref (ppdict *dict, const char *name);
-
-PPAPI ppobj * ppdict_rget_obj (ppdict *dict, const char *name);
-PPAPI int ppdict_rget_bool (ppdict *dict, const char *name, int *v);
-PPAPI int ppdict_rget_int (ppdict *dict, const char *name, ppint *v);
-PPAPI int ppdict_rget_uint (ppdict *dict, const char *name, ppuint *v);
-PPAPI int ppdict_rget_num (ppdict *dict, const char *name, ppnum *v);
-PPAPI ppname ppdict_rget_name (ppdict *dict, const char *name);
-PPAPI ppstring ppdict_rget_string (ppdict *dict, const char *name);
-PPAPI pparray * ppdict_rget_array (ppdict *dict, const char *name);
-PPAPI ppdict * ppdict_rget_dict (ppdict *dict, const char *name);
-PPAPI ppstream * ppdict_rget_stream (ppdict *dict, const char *name);
-PPAPI ppref * ppdict_rget_ref (ppdict *dict, const char *name);
-
-#define ppdict_first(dict, pkey, obj) (pkey = (dict)->keys, obj = (dict)->data)
-#define ppdict_next(pkey, obj) (++(pkey), ++(obj))
-
-/* stream */
-
-#define ppstream_dict(stream) ((stream)->dict)
-
-PPAPI uint8_t * ppstream_first (ppstream *stream, size_t *size, int decode);
-PPAPI uint8_t * ppstream_next (ppstream *stream, size_t *size);
-PPAPI uint8_t * ppstream_all (ppstream *stream, size_t *size, int decode);
-PPAPI void ppstream_done (ppstream *stream);
-
-PPAPI void ppstream_init_buffers (void);
-PPAPI void ppstream_free_buffers (void);
-
-/* ref */
-
-#define ppref_obj(ref) (&(ref)->object)
-
-/* xref */
-
-PPAPI ppxref * ppdoc_xref (ppdoc *pdf);
-PPAPI ppxref * ppxref_prev (ppxref *xref);
-PPAPI ppdict * ppxref_trailer (ppxref *xref);
-PPAPI ppdict * ppxref_catalog (ppxref *xref);
-PPAPI ppdict * ppxref_info (ppxref *xref);
-PPAPI ppref * ppxref_pages (ppxref *xref);
-PPAPI ppref * ppxref_find (ppxref *xref, ppuint refnumber);
-
-/* doc */
-
-PPAPI ppdoc * ppdoc_load (const char *filename);
-PPAPI ppdoc * ppdoc_mem (const void *data, size_t size);
-PPAPI void ppdoc_free (ppdoc *pdf);
-
-#define ppdoc_trailer(pdf) ppxref_trailer(ppdoc_xref(pdf))
-#define ppdoc_catalog(pdf) ppxref_catalog(ppdoc_xref(pdf))
-#define ppdoc_info(pdf) ppxref_info(ppdoc_xref(pdf))
-#define ppdoc_pages(pdf) ppxref_pages(ppdoc_xref(pdf))
-
-PPAPI ppuint ppdoc_page_count (ppdoc *pdf);
-PPAPI ppref * ppdoc_page (ppdoc *pdf, ppuint index);
-PPAPI ppref *  ppdoc_first_page (ppdoc *pdf);
-PPAPI ppref * ppdoc_next_page (ppdoc *pdf);
-
-PPAPI ppstream * ppcontents_first (ppdict *dict);
-PPAPI ppstream * ppcontents_next (ppdict *dict, ppstream *stream);
-
-/* crypt */
-
-typedef enum {
-  PPCRYPT_NONE = 0,
-  PPCRYPT_DONE = 1,
-  PPCRYPT_FAIL = -1,
-  PPCRYPT_PASS = -2
-} ppcrypt_status;
-
-PPAPI ppcrypt_status ppdoc_crypt_status (ppdoc *pdf);
-PPAPI ppcrypt_status ppdoc_crypt_pass (ppdoc *pdf, const void *userpass, size_t userpasslength, const void *ownerpass, size_t ownerpasslength);
-
-/* permission flags, effect in Acrobat File -> Properties -> Security tab */
-
-PPAPI ppint ppdoc_permissions (ppdoc *pdf);
-
-#define PPDOC_ALLOW_PRINT (1<<2)        // printing
-#define PPDOC_ALLOW_MODIFY (1<<3)       // filling form fields, signing, creating template pages
-#define PPDOC_ALLOW_COPY (1<<4)         // copying, copying for accessibility
-#define PPDOC_ALLOW_ANNOTS (1<<5)       // filling form fields, copying, signing
-#define PPDOC_ALLOW_EXTRACT (1<<9)      // contents copying for accessibility
-#define PPDOC_ALLOW_ASSEMBLY (1<<10)    // (no effect)
-#define PPDOC_ALLOW_PRINT_HIRES (1<<11) // (no effect)
-
-/* context */
-
-typedef struct ppcontext ppcontext;
-
-PPAPI ppcontext * ppcontext_new (void);
-PPAPI void ppcontext_done (ppcontext *context);
-PPAPI void ppcontext_free (ppcontext *context);
-
-/* contents parser */
-
-PPAPI ppobj * ppcontents_first_op (ppcontext *context, ppstream *stream, size_t *psize, ppname *pname);
-PPAPI ppobj * ppcontents_next_op (ppcontext *context, ppstream *stream, size_t *psize, ppname *pname);
-PPAPI ppobj * ppcontents_parse (ppcontext *context, ppstream *stream, size_t *psize);
-
-/* boxes and transforms */
-
-typedef struct {
-  ppnum lx, ly, rx, ry;
-} pprect;
-
-PPAPI pprect * pparray_to_rect (pparray *array, pprect *rect);
-PPAPI pprect * ppdict_get_rect (ppdict *dict, const char *name, pprect *rect);
-PPAPI pprect * ppdict_get_box (ppdict *dict, const char *name, pprect *rect);
-
-typedef struct {
-  ppnum xx, xy, yx, yy, x, y;
-} ppmatrix;
-
-PPAPI ppmatrix * pparray_to_matrix (pparray *array, ppmatrix *matrix);
-PPAPI ppmatrix * ppdict_get_matrix (ppdict *dict, const char *name, ppmatrix *matrix);
-
-/* logger */
-
-typedef void (*pplogger_callback) (const char *message, void *alien);
-PPAPI void pplog_callback (pplogger_callback logger, void *alien);
-PPAPI int pplog_prefix (const char *prefix);
-
-/* version */
-
-PPAPI const char * ppdoc_version_string (ppdoc *pdf);
-PPAPI int ppdoc_version_number (ppdoc *pdf, int *minor);
-
-/* doc info */
-
-PPAPI size_t ppdoc_file_size (ppdoc *pdf);
-PPAPI ppuint ppdoc_objects (ppdoc *pdf);
-PPAPI size_t ppdoc_memory (ppdoc *pdf, size_t *waste);
-
-#endif

Deleted: trunk/Build/source/texk/web2c/luatexdir/luapplib/ppload.c-OK
===================================================================
--- trunk/Build/source/texk/web2c/luatexdir/luapplib/ppload.c-OK	2018-09-05 21:32:42 UTC (rev 48592)
+++ trunk/Build/source/texk/web2c/luatexdir/luapplib/ppload.c-OK	2018-09-05 21:35:27 UTC (rev 48593)
@@ -1,2555 +0,0 @@
-
-#include <utilbasexx.h>
-
-#include "pplib.h"
-
-const char * ppobj_kind[] = { "none", "null", "bool", "integer", "number", "name", "string", "array", "dict", "stream", "ref" };
-
-#define ignored_char(c) (c == 0x20 || c == 0x0A || c == 0x0D || c == 0x09 || c == 0x00)
-#define newline_char(c) (c == 0x0A || c == 0x0D)
-#define IGNORED_CHAR_CASE 0x20: case 0x0A: case 0x0D: case 0x09: case 0x00
-#define NEWLINE_CHAR_CASE 0x0A: case 0x0D
-#define DIGIT_CHAR_CASE '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9'
-#define OCTAL_CHAR_CASE '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7'
-
-#define MAX_INT_DIGITS 32
-
-#define PP_LENGTH_UNKNOWN ((size_t)-1)
-
-static const char * ppref_str (ppuint refnumber, ppuint refversion)
-{
-	static char buffer[MAX_INT_DIGITS + 1 + MAX_INT_DIGITS + 1 + 1 + 1];
-#if defined(MSVC64)|| defined(MINGW64)
-	sprintf(buffer, PPUINTF " " PPUINTF " R", refnumber, refversion);
-#else
-	sprintf(buffer, PPUINTF " " PPUINTF " R", (unsigned long)(refnumber), (unsigned long)(refversion));
-#endif
-	return buffer;
-}
-
-/* name */
-
-// pdf name delimiters: 0..32, ()<>[]{}/%
-// # treated specially
-// .+- are valid part of name; keep in mind names such as -| | |- .notdef ABCDEF+Font etc.
-const char ppname_byte_lookup[] = {
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 1, 1, '#', 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
-};
-
-#define PPNAME_INIT (8+1)
-
-#define ppname_flush(O, ghost, siz, flgs) \
-  (iof_put(O, '\0'), \
-   ghost = (_ppname *)ppheap_flush(O, &siz), \
-   ghost->flags = flgs, \
-   ghost->size = siz - sizeof(_ppname) - 1, \
-  (ppname)(ghost + 1))
-
-#define ppname_flush_with_ego(O, ghost, siz, flgs) \
-  (iof_put(O, '\0'), \
-   iof_ensure(O, sizeof(ppname *)), \
-   O->pos += sizeof(ppname *), \
-   ghost = (_ppname *)ppheap_flush(O, &siz), \
-   ghost->flags = flgs, \
-   ghost->size = siz - sizeof(_ppname) - 1 - sizeof(ppname *), \
-  (ppname)(ghost + 1))
-
-#define ppname_set_alter_ego(name, ghost, ego) (*((ppname *)(name + (ghost)->size + 1)) = ego)
-#define ppname_get_alter_ego(name) (*((ppname *)(name + ppname_size(name) + 1)))
-
-static ppname ppscan_name (iof *I, ppheap **pheap)
-{
-  int c, decode;
-  iof *O;
-  _ppname *ghost1, *ghost2;
-  ppname encoded, decoded;
-  size_t size;
-  const char *p, *e;
-  uint8_t v1, v2;
-  O = ppheap_buffer(pheap, sizeof(_ppname), PPNAME_INIT);
-  for (decode = 0, c = iof_char(I); c >= 0 && ppname_byte_lookup[c]; c = iof_next(I))
-  {
-    if (c == '#')
-      decode = 1;
-    iof_put(O, c);
-  }
-  if (!decode)
-    return ppname_flush(O, ghost1, size, 0);
-  encoded = ppname_flush_with_ego(O, ghost1, size, 0|PPNAME_ENCODED);
-  O = ppheap_buffer(pheap, sizeof(_ppname), PPNAME_INIT);
-  for (p = encoded, e = encoded + ghost1->size; p < e; ++p)
-  {
-    if (*p == '#' && p + 2 < e ){
-      v1 = base16_value(p[1]);
-      v2 = base16_value(p[2]);
-      iof_put(O, ((v1<<4)+v2));
-    }else
-      iof_put(O, *p);
-  }
-  decoded = ppname_flush_with_ego(O, ghost2, size, 0|PPNAME_DECODED);
-  ppname_set_alter_ego(encoded, ghost1, decoded);
-  ppname_set_alter_ego(decoded, ghost2, encoded);
-  return encoded;
-}
-
-static ppname ppscan_exec (iof *I, ppheap **pheap, int first)
-{
-  int c, decode;
-  iof *O;
-  _ppname *ghost1, *ghost2;
-  ppname encoded, decoded;
-  size_t size;
-  const char *p, *e;
-  uint8_t v1, v2;
-
-  O = ppheap_buffer(pheap, sizeof(_ppname), PPNAME_INIT);
-  iof_put(O, first);
-  for (decode = 0, c = iof_char(I); c >= 0 && ppname_byte_lookup[c]; c = iof_next(I))
-  {
-    if (c == '#')
-      decode = 1;
-    iof_put(O, c);
-  }
-  if (!decode)
-    return ppname_flush(O, ghost1, size, PPNAME_EXEC);
-  encoded = ppname_flush_with_ego(O, ghost1, size, PPNAME_EXEC|PPNAME_ENCODED);
-  O = ppheap_buffer(pheap, sizeof(_ppname), PPNAME_INIT);
-  for (p = encoded, e = encoded + ghost1->size; p < e; ++p)
-  {
-    if (*p == '#' && p + 2 < e ){
-      v1 = base16_value(p[1]);
-      v2 = base16_value(p[2]);
-      iof_put(O, ((v1<<4)+v2));
-    }else
-      iof_put(O, *p);
-  }
-  decoded = ppname_flush_with_ego(O, ghost2, size, PPNAME_EXEC|PPNAME_DECODED);
-  ppname_set_alter_ego(encoded, ghost1, decoded);
-  ppname_set_alter_ego(decoded, ghost2, encoded);
-  return encoded;
-}
-
-static ppname ppexec_internal (const void *data, size_t size, ppheap **pheap)
-{ // used only for artificial 'EI' operator name
-  iof *O;
-  _ppname *ghost1;
-
-  O = ppheap_buffer(pheap, sizeof(_ppname), size);
-  iof_write(O, data, size);
-  return ppname_flush(O, ghost1, size, PPNAME_EXEC);
-}
-
-ppname ppname_decoded (ppname name)
-{
-  const _ppname *ghost;
-  ghost = _ppname_ghost(name);
-  return (ghost->flags & PPNAME_ENCODED) ? ppname_get_alter_ego(name) : name;
-}
-
-ppname ppname_encoded (ppname name)
-{
-  const _ppname *ghost;
-  ghost = _ppname_ghost(name);
-  return (ghost->flags & PPNAME_DECODED) ? ppname_get_alter_ego(name) : name;
-}
-
-/* string */
-
-#define PPSTRING_INIT (16+1)
-
-#define ppstring_flush(O, ghost, siz, flgs) \
-  (iof_put(O, '\0'), \
-   ghost = (_ppstring *)ppheap_flush(O, &siz), \
-   ghost->flags = flgs, \
-   ghost->size = siz - sizeof(_ppstring) - 1, \
-  (ppstring)(ghost + 1))
-
-#define ppstring_flush_with_ego(O, ghost, siz, flgs) \
-  (iof_put(O, '\0'), \
-   iof_ensure(O, sizeof(ppstring *)), \
-   O->pos += sizeof(ppstring *), \
-   ghost = (_ppstring *)ppheap_flush(O, &siz), \
-   ghost->flags = flgs, \
-   ghost->size = siz - sizeof(_ppstring) - 1 - sizeof(ppstring *), \
-  (ppstring)(ghost + 1))
-
-#define ppstring_utf16be_bom(decoded) (decoded[0] == ((char)0xFE) && decoded[1] == ((char)0xFF) )
-#define ppstring_utf16le_bom(decoded) (decoded[0] == ((char)0xFF) && decoded[1] == ((char)0xFE))
-
-#define ppstring_check_bom(decoded, ghost) ((void)\
-  (ghost->size >= 2 ? (ppstring_utf16be_bom(decoded) ? (ghost->flags |= PPSTRING_UTF16BE) : \
-                      (ppstring_utf16le_bom(decoded) ? (ghost->flags |= PPSTRING_UTF16LE) : 0)) : 0))
-
-#define ppstring_check_bom2(decoded, ghost1, ghost2) ((void)\
-  (ghost2->size >= 2 ? (ppstring_utf16be_bom(decoded) ? ((ghost1->flags |= PPSTRING_UTF16BE), (ghost2->flags |= PPSTRING_UTF16BE)) : \
-                       (ppstring_utf16le_bom(decoded) ? ((ghost1->flags |= PPSTRING_UTF16LE), (ghost2->flags |= PPSTRING_UTF16LE)) : 0)) : 0))
-
-#define ppstring_set_alter_ego(string, ghost, ego) (*((ppstring *)(string + (ghost)->size + 1)) = ego)
-#define ppstring_get_alter_ego(string) (*((ppstring *)(string + ppstring_size(string) + 1)))
-
-static ppstring ppscan_string (iof *I, ppheap **pheap)
-{
-  int c, decode, balance;
-  iof *O;
-  _ppstring *ghost1, *ghost2;
-  uint8_t *p, *e;
-  ppstring encoded, decoded;
-  size_t size;
-  O = ppheap_buffer(pheap, sizeof(_ppstring), PPSTRING_INIT);
-  for (decode = 0, balance = 0, c = iof_char(I); c >= 0; )
-  {
-    switch (c)
-    {
-      case '\\':
-        decode = 1; // unescaping later
-        iof_put(O, '\\');
-        if ((c = iof_next(I)) >= 0)
-        {
-          iof_put(O, c);
-          c = iof_next(I);
-        }
-        break;
-      case '(': // may be unescaped if balanced
-        ++balance;
-        iof_put(O, '(');
-        c = iof_next(I);
-        break;
-      case ')':
-        if (balance == 0)
-        {
-          c = IOFEOF;
-          ++I->pos;
-          break;
-        }
-        --balance;
-        iof_put(O, ')');
-        c = iof_next(I);
-        break;
-      default:
-        iof_put(O, c);
-        c = iof_next(I);
-    }
-  }
-  if (!decode)
-  {
-    encoded = ppstring_flush(O, ghost1, size, 0);
-    ppstring_check_bom(encoded, ghost1); // any bytes can be there
-    return encoded;
-  }
-  encoded = ppstring_flush_with_ego(O, ghost1, size, 0|PPSTRING_ENCODED);
-  O = ppheap_buffer(pheap, sizeof(_ppstring), PPSTRING_INIT);
-  for (p = (uint8_t *)encoded, e = (uint8_t *)encoded + ghost1->size; p < e; ++p)
-  {
-    if (*p == '\\')
-    {
-      if (++p >= e)
-        break;
-      switch (*p)
-      {
-        case OCTAL_CHAR_CASE:
-          c = *p - '0';
-          if (++p < e && *p >= '0' && *p <= '7')
-          {
-            c = (c << 3) + *p - '0';
-            if (++p < e && *p >= '0' && *p <= '7')
-              c = (c << 3) + *p - '0';
-          }
-          iof_put(O, c);
-          break;
-        case 'n':
-          iof_put(O, '\n');
-          break;
-        case 'r':
-          iof_put(O, '\r');
-          break;
-        case 't':
-          iof_put(O, '\t');
-          break;
-        case 'b':
-          iof_put(O, '\b');
-          break;
-        case 'f':
-          iof_put(O, '\f');
-          break;
-        case NEWLINE_CHAR_CASE: // not a part of the string, ignore (pdf spec page 55)
-          break;
-        case '(': case ')': case '\\':
-        default: // for enything else backslash is ignored (pdf spec page 54)
-          iof_put(O, *p);
-          break;
-      }
-    }
-    else
-      iof_put(O, *p);
-  }
-  decoded = ppstring_flush_with_ego(O, ghost2, size, 0|PPSTRING_DECODED);
-  ppstring_check_bom2(decoded, ghost1, ghost2);
-  ppstring_set_alter_ego(encoded, ghost1, decoded);
-  ppstring_set_alter_ego(decoded, ghost2, encoded);
-  return encoded;
-}
-
-/* Hex string may contain white characters. If odd number of digits, the last assumed to be '0' */
-
-static ppstring ppscan_base16 (iof *I, ppheap **pheap)
-{
-  int c, v1, v2;
-  iof *O;
-  _ppstring *ghost1, *ghost2;
-  size_t size;
-  ppstring encoded, decoded;
-  uint8_t *p, *e;
-
-  O = ppheap_buffer(pheap, sizeof(_ppstring), PPSTRING_INIT);
-  for (c = iof_char(I); c >= 0 && (base16_digit(c) || ignored_char(c)); c = iof_next(I))
-    iof_put(O, c);
-  if (c == '>')
-    ++I->pos;
-  encoded = ppstring_flush_with_ego(O, ghost1, size, PPSTRING_BASE16|PPSTRING_ENCODED);
-  O = ppheap_buffer(pheap, sizeof(_ppstring), (ghost1->size >> 1) + 1);
-  for (p = (uint8_t *)encoded, e = (uint8_t *)encoded + ghost1->size; p < e; ++p)
-  {
-    if ((v1 = base16_value(*p)) < 0) // ignored
-      continue;
-    for (v2 = 0, ++p; p < e && (v2 = base16_value(*p)) < 0; ++p);
-    iof_put(O, (v1<<4)|v2);
-  }
-  decoded = ppstring_flush_with_ego(O, ghost2, size, 0|PPSTRING_DECODED);
-  ppstring_check_bom2(decoded, ghost1, ghost2);
-  ppstring_set_alter_ego(encoded, ghost1, decoded);
-  ppstring_set_alter_ego(decoded, ghost2, encoded);
-  return encoded;
-}
-
-/* internal use only; binary string */
-
-static ppstring ppstring_buffer (iof *O, ppheap **pheap)
-{
-   _ppstring *ghost1, *ghost2;
-   ppstring encoded, decoded;
-   uint8_t *p, *e;
-   size_t size;
-
-   decoded = ppstring_flush_with_ego(O, ghost2, size, 0|PPSTRING_DECODED);
-   O = ppheap_buffer(pheap, sizeof(_ppstring), (ghost2->size << 1) + 1);
-   for (p = (uint8_t *)decoded, e = (uint8_t *)decoded + ghost2->size; p < e; ++p)
-     iof_set2(O, base16_uc_alphabet[(*p)>>4], base16_uc_alphabet[(*p)&15]);
-   encoded = ppstring_flush_with_ego(O, ghost1, size, PPSTRING_BASE16|PPSTRING_ENCODED);
-   ppstring_set_alter_ego(encoded, ghost1, decoded);
-   ppstring_set_alter_ego(decoded, ghost2, encoded);
-   return encoded;
-}
-
-ppstring ppstring_internal (const void *data, size_t size, ppheap **pheap)
-{ // so far used only for crypt key
-  iof *O;
-
-  O = ppheap_buffer(pheap, sizeof(_ppstring), size);
-  iof_write(O, data, size);
-  return ppstring_buffer(O, pheap);
-}
-
-/* PDF spec says nothing about base85 strings, but streams might be (afair no leading '<~' but present trailing '~>') */
-
-static ppstring ppscan_base85 (iof *I, ppheap **pheap)
-{ // bawse85 alphabet is 33.117, adobe also hires 'z' and 'y' for compression
-  int c;
-  iof *O, B;
-  _ppstring *ghost1, *ghost2;
-  size_t size;
-  ppstring encoded, decoded;
-  O = ppheap_buffer(pheap, sizeof(_ppstring), PPSTRING_INIT);
-  for (c = iof_char(I); (c >= '!' && c <= 'u') || c == 'z' || c == 'y'; c = iof_next(I))
-    iof_put(O, c);
-  if (c == '~')
-    if ((c = iof_next(I)) == '>')
-      ++I->pos;
-  encoded = ppstring_flush_with_ego(O, ghost1, size, PPSTRING_BASE85|PPSTRING_ENCODED);
-  iof_string_reader(&B, encoded, ghost1->size);
-  O = ppheap_buffer(pheap, sizeof(_ppstring), (ghost1->size * 5 / 4) + 1);
-  base85_decode(&B, O);
-  decoded = ppstring_flush_with_ego(O, ghost2, size, 0|PPSTRING_DECODED);
-  ppstring_check_bom2(decoded, ghost1, ghost2);
-  ppstring_set_alter_ego(encoded, ghost1, decoded);
-  ppstring_set_alter_ego(decoded, ghost2, encoded);
-  return encoded;
-}
-
-/*
-Encrypted strings. In case of encrypted strings, we first need to decode the string (saving original form hardly makes sense),
-then decrypt the string, and encode it again.
-*/
-
-const char ppstring_byte_escape[] = { /* -1 escaped with octal, >0 escaped with \\, 0 left intact*/
- -1,-1,-1,-1,-1,-1,-1,-1,'b','t','n',-1,'f','r',-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
-  0, 0, 0, 0, 0, 0, 0, 0,'(',')', 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
- -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
-};
-
-
-static ppstring ppscan_crypt_string (iof *I, ppcrypt *crypt, ppheap **pheap)
-{
-  int c, b, balance, encode;
-  iof *O;
-  _ppstring *ghost1, *ghost2;
-  ppstring encoded, decoded;
-  uint8_t *p, *e;
-  size_t size;
-
-  O = ppheap_buffer(pheap, sizeof(_ppstring), PPSTRING_INIT);
-  for (balance = 0, encode = 0, c = iof_char(I); c >= 0; )
-  {
-    switch (c)
-    {
-      case '\\':
-        if ((c = iof_next(I)) < 0)
-          break;
-        encode = 1;
-        switch (c)
-        {
-          case OCTAL_CHAR_CASE:
-            b = c - '0';
-            if ((c = iof_next(I)) >= 0 && c >= '0' && c <= '7')
-            {
-              b = (b << 3) + c - '0';
-              if ((c = iof_next(I)) >= 0 && c >= '0' && c <= '7')
-              {
-                b = (b << 3) + c - '0';
-                c = iof_next(I);
-              }
-            }
-            iof_put(O, b);
-            // c is set to the next char
-            break;
-          case 'n':
-            iof_put(O, '\n');
-            c = iof_next(I);
-            break;
-          case 'r':
-            iof_put(O, '\r');
-            c = iof_next(I);
-            break;
-          case 't':
-            iof_put(O, '\t');
-            c = iof_next(I);
-            break;
-          case 'b':
-            iof_put(O, '\b');
-            c = iof_next(I);
-            break;
-          case 'f':
-            iof_put(O, '\f');
-            c = iof_next(I);
-            break;
-          case NEWLINE_CHAR_CASE: // not a part of the string, ignore (pdf spec page 55)
-            c = iof_next(I);
-            break;
-          case '(': case ')': case '\\':
-          default: // for enything else backslash is ignored (pdf spec page 54)
-            iof_put(O, c);
-            c = iof_next(I);
-            break;
-        }
-        break;
-      case '(':
-        ++balance;
-        encode = 1;
-        iof_put(O, '(');
-        c = iof_next(I);
-        break;
-      case ')':
-        if (balance == 0)
-        {
-          c = IOFEOF;
-          ++I->pos;
-        }
-        else
-        {
-          --balance;
-          //encode = 1;
-          iof_put(O, ')');
-          c = iof_next(I);
-        }
-        break;
-      default:
-        if (ppstring_byte_escape[c] != 0)
-          encode = 1;
-        iof_put(O, c);
-        c = iof_next(I);
-    }
-  }
-  /* decrypt the buffer in place, update size */
-  if (ppstring_decrypt(crypt, O->buf, iof_size(O), O->buf, &size))
-    O->pos = O->buf + size;
-  /* make encoded counterpart */
-  if (!encode)
-  {
-    decoded = ppstring_flush(O, ghost2, size, 0);
-    ppstring_check_bom(decoded, ghost2);
-    return decoded;
-  }
-  decoded = ppstring_flush_with_ego(O, ghost2, size, PPSTRING_DECODED);
-  O = ppheap_buffer(pheap, sizeof(_ppstring), ghost2->size);
-  for (p = (uint8_t *)decoded, e = (uint8_t *)decoded + ghost2->size; p < e; ++p)
-  {
-    switch ((b = ppstring_byte_escape[*p]))
-    {
-      case 0:
-        iof_put(O, *p);
-        break;
-      case -1:
-        iof_put4(O, '\\', (c >> 6) + '0', ((c >> 3) & 7) + '0', (c & 7) + '0');
-        break;
-      default:
-        iof_put2(O, '\\', b);
-        break;
-    }
-  }
-  encoded = ppstring_flush_with_ego(O, ghost1, size, PPSTRING_ENCODED);
-  ppstring_check_bom2(decoded, ghost1, ghost2);
-  ppstring_set_alter_ego(encoded, ghost1, decoded);
-  ppstring_set_alter_ego(decoded, ghost2, encoded);
-  return encoded;
-}
-
-
-static ppstring ppscan_crypt_base16 (iof *I, ppcrypt *crypt, ppheap **pheap)
-{
-  int c, v1, v2;
-  iof *O;
-  _ppstring *ghost1, *ghost2;
-  ppstring encoded, decoded;
-  uint8_t *p, *e;
-  size_t size;
-
-  O = ppheap_buffer(pheap, sizeof(_ppstring), PPSTRING_INIT);
-  // base16_decode(I, O); // no info about the last char..
-  for (c = iof_char(I); c != '>' && c >= 0; )
-  {
-    if ((v1 = base16_value(c)) < 0)
-    {
-      if (ignored_char(c))
-      {
-        c = iof_next(I);
-        continue;
-      }
-      break;
-    }
-    do {
-      c = iof_next(I);
-      if ((v2 = base16_value(c)) >= 0)
-      {
-        c = iof_next(I);
-        break;
-      }
-      if (!ignored_char(c)) // c == '>' || c < 0 or some crap
-      {
-        v2 = 0;
-        break;
-      }
-    } while (1);
-    iof_put(O, (v1 << 4)|v2);
-  }
-  if (c == '>')
-    ++I->pos;
-  /* decrypt the buffer in place, update size */
-  if (ppstring_decrypt(crypt, O->buf, iof_size(O), O->buf, &size))
-    O->pos = O->buf + size;
-  decoded = ppstring_flush_with_ego(O, ghost2, size, PPSTRING_DECODED);
-  /* recreate an encoded form */
-  O = ppheap_buffer(pheap, sizeof(_ppstring), (ghost2->size << 1) + 1);
-  for (p = (uint8_t *)decoded, e = (uint8_t *)decoded + ghost2->size; p < e; ++p)
-    iof_set2(O, base16_uc_alphabet[(*p)>>4], base16_uc_alphabet[(*p)&15]);
-  encoded = ppstring_flush_with_ego(O, ghost1, size, PPSTRING_BASE16|PPSTRING_ENCODED);
-  ppstring_check_bom2(decoded, ghost1, ghost2);
-  ppstring_set_alter_ego(encoded, ghost1, decoded);
-  ppstring_set_alter_ego(decoded, ghost2, encoded);
-  return encoded;
-}
-
-/* ppstring alter ego switcher */
-
-ppstring ppstring_decoded (ppstring string)
-{
-  const _ppstring *ghost;
-  ghost = _ppstring_ghost(string);
-  return (ghost->flags & PPSTRING_ENCODED) ? ppstring_get_alter_ego(string) : string;
-}
-
-ppstring ppstring_encoded (ppstring string)
-{
-  const _ppstring *ghost;
-  ghost = _ppstring_ghost(string);
-  return (ghost->flags & PPSTRING_DECODED) ? ppstring_get_alter_ego(string) : string;
-}
-
-/* scanner stack */
-
-#define PPSTACK_BUFFER 512
-
-static void ppstack_init (ppstack *stack, ppheap **pheap)
-{
-  stack->buf = stack->pos = (ppobj *)pp_malloc(PPSTACK_BUFFER * sizeof(ppobj));
-  stack->size = 0;
-  stack->space = PPSTACK_BUFFER;
-  stack->pheap = pheap;
-}
-
-#define ppstack_free_buffer(stack) (pp_free((stack)->buf))
-
-static void ppstack_resize (ppstack *stack)
-{
-  ppobj *newbuffer;
-  stack->space <<= 1;
-  newbuffer = (ppobj *)pp_malloc(stack->space * sizeof(ppobj));
-  memcpy(newbuffer, stack->buf, stack->size * sizeof(ppobj));
-  ppstack_free_buffer(stack);
-  stack->buf = newbuffer;
-  stack->pos = newbuffer + stack->size;
-}
-
-#define ppstack_push(stack) ((void)((stack)->size < (stack)->space || (ppstack_resize(stack), 0)), ++(stack)->size, (stack)->pos++)
-#define ppstack_pop(stack, n) ((stack)->size -= (n), (stack)->pos -= (n))
-#define ppstack_at(stack, i) ((stack)->buf + i)
-#define ppstack_clear(stack) ((stack)->pos = (stack)->buf, (stack)->size = 0)
-
-/* scanner commons */
-
-#define ppscan_uint(I, u) iof_get_uintlw(I, u)
-#define ppread_uint(s, u) string_to_uintlw((const char *)(s), u)
-
-static ppobj * ppscan_numobj (iof *I, ppobj *obj, int negative)
-{
-  ppint integer;
-  ppnum number;
-  int exponent;
-  int c;
-  c = iof_char(I);
-  iof_scan_integer(I, c, integer);
-  switch(c)
-  {
-    case '.':
-    {
-      number = (ppnum)integer;
-      c = iof_next(I);
-      iof_scan_fraction(I, c, number, exponent);
-      double_negative_exp10(number, exponent);
-      obj->type = PPNUM, obj->number = negative ? -number : number;
-      break;
-    }
-    default:
-      obj->type = PPINT, obj->integer = negative ? -integer : integer;
-      break;
-  }
-  return obj;
-}
-
-static ppobj * ppscan_numobj_frac (iof *I, ppobj *obj, int negative)
-{
-  ppnum number;
-  int c, exponent;
-
-  number = 0.0;
-  c = iof_next(I);
-  iof_scan_fraction(I, c, number, exponent);
-  double_negative_exp10(number, exponent);
-  obj->type = PPNUM, obj->number = negative ? -number : number;
-  return obj;
-}
-
-static int ppscan_find (iof *I)
-{ // skips whitechars and comments
-  int c;
-  for (c = iof_char(I); ; c = iof_next(I))
-  {
-    switch (c)
-    {
-      case IGNORED_CHAR_CASE:
-        break;
-      case '%': {
-        do {
-          if ((c = iof_next(I)) < 0)
-            return c;
-        } while (!newline_char(c));
-        break;
-      }
-      default:
-        return c;
-    }
-  }
-  return c; // never reached
-}
-
-static int ppscan_keyword (iof *I, const char *keyword, size_t size)
-{
-  size_t i;
-  int c;
-  if (iof_left(I) >= size)
-  {
-    if (memcmp(I->pos, keyword, size) != 0)
-      return 0;
-    I->pos += size;
-    return 1;
-  }
-  // sticky case, we can't go back
-  for (i = 0, c = iof_char(I); i < size; ++i, ++keyword, c = iof_next(I))
-    if (i != c)
-      return 0;
-  return 1;
-}
-
-#define ppscan_key(I, literal) ppscan_keyword(I, "" literal, sizeof(literal) - 1)
-
-/* objects parser */
-
-static ppref * ppref_unresolved (ppheap **pheap, ppuint refnumber, ppuint refversion)
-{
-  ppref *ref = (ppref *)ppheap_take(pheap, sizeof(ppref));
-  memset(ref, 0, sizeof(ppref));
-  ref->object.type = PPNONE;
-  ref->number = refnumber;
-  ref->version = refversion;
-  return ref;
-}
-
-#define PPMARK PPNONE
-
-static ppobj * ppscan_obj (iof *I, ppdoc *pdf, ppxref *xref)
-{
-  int c;
-  ppobj *obj;
-  size_t mark, size;
-  ppuint refnumber, refversion;
-  ppref *ref;
-  ppstack *stack;
-  ppcrypt *crypt;
-
-  stack = &pdf->stack;
-  c = iof_char(I);
-  switch (c)
-  {
-    case DIGIT_CHAR_CASE:
-      return ppscan_numobj(I, ppstack_push(stack), 0);
-    case '.':
-      return ppscan_numobj_frac(I, ppstack_push(stack), 0);
-    case '+':
-      ++I->pos;
-      return ppscan_numobj(I, ppstack_push(stack), 0);
-    case '-':
-      ++I->pos;
-      return ppscan_numobj(I, ppstack_push(stack), 1);
-    case '/':
-      ++I->pos;
-      obj = ppstack_push(stack);
-      obj->type = PPNAME;
-      obj->name = ppscan_name(I, &pdf->heap);
-      return obj;
-    case '(':
-      ++I->pos;
-      obj = ppstack_push(stack);
-      obj->type = PPSTRING;
-      if (ppcrypt_ref(pdf, crypt))
-        obj->string = ppscan_crypt_string(I, crypt, &pdf->heap);
-      else
-        obj->string = ppscan_string(I, &pdf->heap);
-      return obj;
-    case '[':
-      mark = stack->size;
-      obj = ppstack_push(stack);
-      obj->type = PPMARK; // ppscan_obj() checks types backward for 'R', so set the type immediatelly (reserved for PPARRAY)
-      obj->any = NULL;
-      ++I->pos;
-      for (c = ppscan_find(I); c != ']'; c = ppscan_find(I))
-      {
-        if (ppscan_obj(I, pdf, xref) == NULL)
-        { // callers assume that NULL returns means nothing pushed
-          size = stack->size - mark; // pop items AND the obj reserved for array
-          ppstack_pop(stack, size);
-          return NULL;
-        }
-      }
-      ++I->pos;
-      size = stack->size - mark - 1;
-      obj = ppstack_at(stack, mark); // stack might have been realocated
-      obj->type = PPARRAY;
-      obj->array = pparray_create(ppstack_at(stack, mark + 1), size, &pdf->heap);
-      ppstack_pop(stack, size); // pop array items, leave the array on top
-      return obj;
-    case '<':
-      if ((c = iof_next(I)) == '<')
-      {
-        mark = stack->size;
-        obj = ppstack_push(stack);
-        obj->type = PPMARK;
-        obj->any = NULL;
-        ++I->pos;
-        for (c = ppscan_find(I); c != '>'; c = ppscan_find(I))
-        {
-          if (ppscan_obj(I, pdf, xref) == NULL)
-          {
-            size = stack->size - mark;
-            ppstack_pop(stack, size);
-            return NULL;
-          }
-        }
-        if (iof_next(I) == '>')
-          ++I->pos;
-        size = stack->size - mark - 1;
-        obj = ppstack_at(stack, mark);
-        obj->type = PPDICT;
-        obj->dict = ppdict_create(ppstack_at(stack, mark + 1), size, &pdf->heap);
-        ppstack_pop(stack, size);
-        return obj;
-      }
-      obj = ppstack_push(stack);
-      obj->type = PPSTRING;
-      if (ppcrypt_ref(pdf, crypt))
-        obj->string = ppscan_crypt_base16(I, crypt, &pdf->heap);
-      else
-        obj->string = ppscan_base16(I, &pdf->heap);
-      return obj;
-    case 'R':
-      if (stack->size >= 2 && stack->pos[-1].type == PPINT && stack->pos[-2].type == PPINT)
-      {
-        ++I->pos;
-        obj = &stack->pos[-2];
-        refnumber = (ppuint)obj->integer;
-        ppstack_pop(stack, 1); // pop version number, retype obj to a reference
-        if (xref == NULL || (ref = ppxref_find(xref, refnumber)) == NULL)
-        { /* pdf spec page 64: unresolvable reference is not an error, should just be treated as a reference to null.
-             we also need this to read trailer, where refs can't be resolved yet */
-          refversion = (obj + 1)->integer;
-          //if (xref != NULL)
-          //  loggerf("unresolved reference %s", ppref_str(refnumber, refversion));
-          ref = ppref_unresolved(stack->pheap, refnumber, refversion);
-        }
-        obj->type = PPREF;
-        obj->ref = ref;
-        return obj;
-      }
-      break;
-    case 't':
-      if (iof_next(I) == 'r' && iof_next(I) == 'u' && iof_next(I) == 'e')
-      {
-        ++I->pos;
-        obj = ppstack_push(stack);
-        obj->type = PPBOOL;
-        obj->integer = 1;
-        return obj;
-      }
-      break;
-    case 'f':
-      if (iof_next(I) == 'a' && iof_next(I) == 'l' && iof_next(I) == 's' && iof_next(I) == 'e')
-      {
-        ++I->pos;
-        obj = ppstack_push(stack);
-        obj->type = PPBOOL;
-        obj->integer = 0;
-        return obj;
-      }
-      break;
-    case 'n':
-      if (iof_next(I) == 'u' && iof_next(I) == 'l' && iof_next(I) == 'l')
-      {
-        ++I->pos;
-        obj = ppstack_push(stack);
-        obj->type = PPNULL;
-        obj->any = NULL;
-        return obj;
-      }
-      break;
-  }
-  return NULL;
-}
-
-/*
-A variant for contents streams (aka postscript); wise of operators, blind to references.
-We are still PDF, so we don't care about postscript specific stuff such as radix numbers
-and scientific numbers notation. It takes ppstack * as context (no ppdoc *) to be able
-to run contents parser beyond the scope of ppdoc heap.
-*/
-
-static ppstring ppstring_inline (iof *I, ppdict *imagedict, ppheap **pheap);
-
-static ppobj * ppscan_psobj (iof *I, ppstack *stack)
-{
-  int c;
-  ppobj *obj, *op;
-  size_t size, mark;
-  ppname exec;
-
-  c = iof_char(I);
-  switch (c)
-  {
-    case DIGIT_CHAR_CASE:
-      return ppscan_numobj(I, ppstack_push(stack), 0);
-    case '.':
-      return ppscan_numobj_frac(I, ppstack_push(stack), 0);
-    case '+':
-      c = iof_next(I);
-      if (base10_digit(c)) // '+.abc' is probably an executable name, but we are not in postscript
-        return ppscan_numobj(I, ppstack_push(stack), 0);
-      else if (c == '.')
-        return ppscan_numobj_frac(I, ppstack_push(stack), 0);
-      obj = ppstack_push(stack);
-      obj->type = PPNAME;
-      obj->name = ppscan_exec(I, stack->pheap, '+');
-      return obj;
-    case '-':
-      c = iof_next(I);
-      if (base10_digit(c)) // ditto, we would handle type1 '-|' '|-' operators though
-        return ppscan_numobj(I, ppstack_push(stack), 1);
-      else if (c == '.')
-        return ppscan_numobj_frac(I, ppstack_push(stack), 1);
-      obj = ppstack_push(stack);
-      obj->type = PPNAME;
-      obj->name = ppscan_exec(I, stack->pheap, '-');
-      return obj;
-    case '/':
-      ++I->pos;
-      obj = ppstack_push(stack);
-      obj->type = PPNAME;
-      obj->name = ppscan_name(I, stack->pheap);
-      return obj;
-    case '(':
-      ++I->pos;
-      obj = ppstack_push(stack);
-      obj->type = PPSTRING;
-      obj->string = ppscan_string(I, stack->pheap);
-      return obj;
-    case '[':
-      mark = stack->size;
-      obj = ppstack_push(stack);
-      obj->type = PPMARK;
-      obj->any = NULL;
-      ++I->pos;
-      for (c = ppscan_find(I); c != ']'; c = ppscan_find(I))
-      {
-        if (ppscan_psobj(I, stack) == NULL)
-        {
-          size = stack->size - mark;
-          ppstack_pop(stack, size);
-          return NULL;
-        }
-      }
-      ++I->pos;
-      size = stack->size - mark - 1;
-      obj = ppstack_at(stack, mark);
-      obj->type = PPARRAY;
-      obj->array = pparray_create(ppstack_at(stack, mark + 1), size, stack->pheap);
-      ppstack_pop(stack, size);
-      return obj;
-    case '<':
-      if ((c = iof_next(I)) == '<')
-      {
-        mark = stack->size;
-        obj = ppstack_push(stack);
-        obj->type = PPMARK;
-        obj->any = NULL;
-        ++I->pos;
-        for (c = ppscan_find(I); c != '>'; c = ppscan_find(I))
-        {
-          if (ppscan_psobj(I, stack) == NULL)
-          {
-            size = stack->size - mark;
-            ppstack_pop(stack, size);
-            return NULL;
-          }
-        }
-        if (iof_next(I) == '>')
-          ++I->pos;
-        size = stack->size - mark - 1;
-        obj = ppstack_at(stack, mark);
-        obj->type = PPDICT;
-        obj->dict = ppdict_create(ppstack_at(stack, mark + 1), size, stack->pheap);
-        ppstack_pop(stack, size);
-        return obj;
-      }
-      obj = ppstack_push(stack);
-      obj->type = PPSTRING;
-      if (c == '~')
-        ++I->pos, obj->string = ppscan_base85(I, stack->pheap);
-      else
-        obj->string = ppscan_base16(I, stack->pheap);
-      return obj;
-    default:
-      if (c < 0 || !ppname_byte_lookup[c])
-        break; // forbid empty names; dead loop otherwise
-      ++I->pos;
-      /* true false null practically don't occur in streams so it makes sense to assume that we get an operator name here.
-         If it happen to be a keyword we could give back those several bytes to the heap but.. heap buffer is tricky enough. */
-      exec = ppscan_exec(I, stack->pheap, c);
-      obj = ppstack_push(stack);
-      switch (exec[0])
-      {
-        case 't':
-          if (exec[1] == 'r' && exec[2] == 'u' && exec[3] == 'e' && exec[4] == '\0')
-          {
-            obj->type = PPBOOL;
-            obj->integer = 1;
-            // todo: drop exec
-            return obj;
-          }
-          break;
-        case 'f':
-          if (exec[1] == 'a' && exec[2] == 'l' && exec[3] == 's' && exec[4] == 'e' && exec[5] == '\0')
-          {
-            obj->type = PPBOOL;
-            obj->integer = 0;
-            // todo: drop exec
-            return obj;
-          }
-          break;
-        case 'n':
-          if (exec[1] == 'u' && exec[2] == 'l' && exec[3] == 'l' && exec[4] == '\0')
-          {
-            obj->type = PPNULL;
-            obj->any = NULL;
-            // todo: drop exec
-            return obj;
-          }
-          break;
-        case 'B':
-           /*
-           Inline images break rules of operand/operator syntax, so 'BI/ID' operators need to be treated as special syntactic keywords.
-
-             BI <keyval pairs> ID<whitechar?><imagedata><whitechar?>EI
-
-           We treat the image as a single syntactic token; BI starts collecting a dict, ID is the beginning of the data. Effectively EI
-           operator obtains two operands - dict and string. It is ok to put three items onto the stack, callers dont't assume there is just one.
-           */
-          if (exec[1] == 'I' && exec[2] == '\0')
-          {
-            ppdict *imagedict;
-            /* key val pairs -> dict */
-            mark = stack->size - 1;
-            obj->type = PPMARK;
-            obj->any = NULL;
-            for (c = ppscan_find(I); ; c = ppscan_find(I))
-            {
-              if ((op = ppscan_psobj(I, stack)) == NULL)
-              {
-                size = stack->size - mark;
-                ppstack_pop(stack, size);
-                return NULL;
-              }
-              if (op->type == PPNAME && ppname_exec(op->name))
-              {
-                if (!ppname_is(op->name, "ID"))
-                { // weird
-                  size = stack->size - mark;
-                  ppstack_pop(stack, size);
-                  return NULL;
-                }
-                break;
-              }
-            }
-            size = stack->size - mark - 1;
-            obj = ppstack_at(stack, mark);
-            obj->type = PPDICT;
-            obj->dict = imagedict = ppdict_create(ppstack_at(stack, mark + 1), size, stack->pheap);
-            ppstack_pop(stack, size);
-            /* put image data string */
-            obj = ppstack_push(stack);
-            obj->type = PPSTRING;
-            obj->string = ppstring_inline(I, imagedict, stack->pheap);;
-            /* put EI operator name */
-            obj = ppstack_push(stack);
-            obj->type = PPNAME;
-            obj->name = ppexec_internal("EI", 2, stack->pheap);
-            return obj;
-          }
-      }
-      obj->type = PPNAME;
-      obj->name = exec;
-      return obj;
-  }
-  return NULL;
-}
-
-/*
-We try to get the exact inline image length from its dict params. If cannot predict the length, we have to scan the input until 'EI'.
-I've checked on may examples that it gives the same results but one can never be sure, as 'EI' might happen to be a part of the data.
-Stripping white char is also very heuristic; \0 is a white char in PDF and very likely to be a data byte.. weak method.
-*/
-
-static size_t inline_image_length (ppdict *dict)
-{
-  ppuint w, h, bpc, colors;
-  ppname cs;
-
-  if (ppdict_get_uint(dict, "W", &w) && ppdict_get_uint(dict, "H", &h) && ppdict_get_uint(dict, "BPC", &bpc) && (cs = ppdict_get_name(dict, "CS")) != NULL)
-  {
-    if (ppname_is(cs, "DeviceGray"))
-      colors = 1;
-    else if (ppname_is(cs, "DeviceRGB"))
-      colors = 3;
-    else if (ppname_is(cs, "DeviceCMYK"))
-      colors = 4;
-    else
-      return PP_LENGTH_UNKNOWN;
-    return (w * h * bpc * colors + 7) >> 3;
-  }
-  return PP_LENGTH_UNKNOWN;
-}
-
-static ppstring ppstring_inline (iof *I, ppdict *imagedict, ppheap **pheap)
-{
-  iof *O;
-  int c, d, e;
-  size_t length, leftin, leftout, bytes;
-
-  O = ppheap_buffer(pheap, sizeof(_ppstring), PPSTRING_INIT);
-  c = iof_char(I);
-  if (ignored_char(c))
-    c = iof_next(I);
-
-  length = inline_image_length(imagedict);
-  if (length != PP_LENGTH_UNKNOWN)
-  {
-    while (length > 0 && iof_readable(I) && iof_writable(O))
-    {
-      leftin = iof_left(I);
-      leftout = iof_left(O);
-      bytes = length;
-      if (bytes > leftin) bytes = leftin;
-      if (bytes > leftout) bytes = leftout;
-      memcpy(O->pos, I->pos, bytes);
-      I->pos += bytes;
-      O->pos += bytes;
-      length -= bytes;
-    }
-    // gobble EI
-    if (ppscan_find(I) == 'E')
-      if (iof_next(I) == 'I')
-        ++I->pos;
-  }
-  else
-  {
-    while (c >= 0)
-    {
-      if (c == 'E')
-      {
-        d = iof_next(I);
-        if (d == 'I')
-        {
-          e = iof_next(I);
-          if (!ppname_byte_lookup[e])
-          { /* strip one newline from the end and stop */
-            if (O->pos - 2 >= O->buf) // sanity
-            {
-              c = *(O->pos - 1);
-              if (ignored_char(c))
-              {
-                if (c == 0x0A && *(O->pos - 2) == 0x0D)
-                  O->pos -= 2;
-                else
-                  O->pos -= 1;
-              }
-            }
-            break;
-          }
-          iof_put2(O, c, d);
-          c = e;
-        }
-        else
-        {
-          iof_put(O, c);
-          c = d;
-        }
-      }
-      else
-      {
-        iof_put(O, c);
-        c = iof_next(I);
-      }
-    }
-  }
-  return ppstring_buffer(O, pheap);
-}
-
-/* input reader */
-
-/*
-PDF input is a pseudo file that either keeps FILE * or data. Reader iof * is a proxy to input
-that provides byte-by-byte interface. Our iof structure is capable to link iof_file *input,
-but t avoid redundant checks on IOF_DATA flag, here we link iof *I directly to FILE * or mem buffer.
-When reading from file we need an internal buffer, which should be kept rather small, as it is
-only used to parse xrefs and objects (no streams). We allocate the buffer from a private heap
-(not static) to avoid conflicts when processing >1 pdfs at once. Besides, the input buffer may be
-needed after loading the document, eg. to access references raw data.
-*/
-
-#define PPDOC_BUFFER 0xFFF // keep that small, it is only used to parse body objects
-
-static void ppdoc_reader_init (ppdoc *pdf, iof_file *input)
-{
-  iof *I;
-  pdf->input = *input;
-  input = &pdf->input;
-  input->refcount = 1;
-  I = &pdf->reader;
-  if (input->flags & IOF_DATA)
-  {
-    pdf->buffer = NULL;            // input iof_file is the buffer
-    iof_string_reader(I, NULL, 0); // gets IOF_DATA flag
-  }
-  else
-  {
-    pdf->buffer = (uint8_t *)ppheap_take(&pdf->heap, PPDOC_BUFFER);
-    iof_setup_file_handle_reader(I, NULL, 0, iof_file_get_fh(input)); // gets IOF_FILE_HANDLE flag and FILE *
-    I->space = PPDOC_BUFFER; // used on refill
-  }
-}
-
-/*
-Whenever we need to read the input file, we fseek the to the given offset and fread to to the private buffer.
-The length we need is not always predictable, in which case PPDOC_BUFFER bytes are read (keep it small).
-I->buf = I->pos is set to the beginning, I->end set to the end (end is the first byte one shouldn't read).
-*/
-
-static iof * ppdoc_reader (ppdoc *pdf, size_t offset, size_t length)
-{
-  iof_file *input;
-  iof *I;
-  input = &pdf->input;
-  I = &pdf->reader;
-  if (iof_file_seek(input, offset, SEEK_SET) != 0)
-    return NULL;
-  I->flags &= ~IOF_STOPPED;
-  if (input->flags & IOF_DATA)
-  {
-    I->buf = I->pos = input->pos;
-    I->end = (length == PP_LENGTH_UNKNOWN || I->pos + length >= input->end) ? input->end : (I->pos + length);
-  }
-  else
-  {
-    I->buf = I->pos = pdf->buffer; // ->buf is actually permanently equal pdf->buffer but we might need some tricks
-    if (length == PP_LENGTH_UNKNOWN || length > PPDOC_BUFFER)
-      length = PPDOC_BUFFER;
-    length = fread(I->buf, 1, length, I->file);
-    I->end = I->buf + length;
-  }
-  return I;
-}
-
-/* The position from the beginning of input
-- for data buffer: (pdf->input.pos - pdf->input.buf) + (I->pos - I->buf)
-  I->buf == pdf->input.pos, so this resolves to (I->pos - pdf->input.buf), independent from I->buf
-- for file buffer: ftell(pdf->input.file) - (I->end - I->pos)
-*/
-
-#define ppdoc_reader_tell(pdf, I) ((size_t)(((pdf)->input.flags & IOF_DATA) ? ((I)->pos - (pdf)->input.buf) : (ftell(iof_file_get_fh(&(pdf)->input)) - ((I)->end - (I)->pos))))
-
-/* pdf */
-
-#define PPDOC_HEADER 10 // "%PDF-?.??\n"
-
-static int ppdoc_header (ppdoc *pdf, uint8_t header[PPDOC_HEADER])
-{
-  size_t i;
-  if (memcmp(header, "%PDF-", 5) != 0)
-    return 0;
-  for (i = 5; i < PPDOC_HEADER - 1 && !ignored_char(header[i]); ++i)
-    pdf->version[i - 5] = header[i];
-  pdf->version[i - 5] = '\0';
-  return 1;
-}
-
-static int ppdoc_tail (ppdoc *pdf, iof_file *input, size_t *pxrefoffset)
-{
-  int c;
-  uint8_t tail[4*10], *p, back, tailbytes;
-
-  if (iof_file_seek(input, 0, SEEK_END) != 0)
-    return 0;
-  pdf->filesize = (size_t)iof_file_tell(input);
-  // simple heuristic to avoif fgetc() / fseek(-2) hiccup: keep seeking back by len(startxref) + 1 == 10
-  // until a letter found (assuming liberal white characters and tail length)
-  for (back = 1, tailbytes = 0; ; ++back)
-  {
-    if (iof_file_seek(input, -10, SEEK_CUR) != 0)
-      return 0;
-    tailbytes += 10;
-    c = iof_file_getc(input);
-    tailbytes -= 1;
-    switch (c)
-    {
-      case IGNORED_CHAR_CASE:
-      case DIGIT_CHAR_CASE:
-      case '%': case 'E': case 'O': case 'F':
-        if (back > 4) // 2 should be enough
-          return 0;
-        continue;
-      case 's': case 't': case 'a': case 'r': case 'x': case 'e': case 'f':
-        if (iof_file_read(tail, 1, tailbytes, input) != tailbytes)
-          return 0;
-        tail[tailbytes] = '\0';
-        for (p = &tail[0]; ; ++p)
-        {
-          if (*p == '\0')
-            return 0;
-          if ((c = base10_value(*p)) >= 0)
-            break;
-        }
-        ppread_uint(p, pxrefoffset);
-        return 1;
-      default:
-        return 0;
-    }
-  }
-  return 0;
-}
-
-/* xref/body */
-
-static int ppscan_start_entry (iof *I, ppref *ref)
-{
-  ppuint u;
-  ppscan_find(I); if (!ppscan_uint(I, &u) || u != ref->number) return 0;
-  ppscan_find(I); if (!ppscan_uint(I, &u) || u != ref->version) return 0;
-  ppscan_find(I); if (!ppscan_key(I, "obj")) return 0;
-  ppscan_find(I);
-  return 1;
-}
-
-static int ppscan_skip_entry (iof *I)
-{
-  size_t u;
-  ppscan_find(I); if (!ppscan_uint(I, &u)) return 0;
-  ppscan_find(I); if (!ppscan_uint(I, &u)) return 0;
-  ppscan_find(I); if (!ppscan_key(I, "obj")) return 0;
-  ppscan_find(I);
-  return 1;
-}
-
-static int ppscan_start_stream (iof *I, ppdoc *pdf, size_t *streamoffset)
-{
-  int c;
-  ppscan_find(I);
-  if (ppscan_key(I, "stream"))
-  { // skip 1 or 2 whites (here we shouldn't just gobble all blanks)
-    c = iof_char(I);
-    if (ignored_char(c))
-    {
-      c = iof_next(I);
-      if (ignored_char(c))
-        ++I->pos;
-    }
-    *streamoffset = ppdoc_reader_tell(pdf, I);
-    return 1;
-  }
-  return 0;
-}
-
-static ppxref * ppxref_load (ppdoc *pdf, size_t xrefoffset);
-static ppxref * ppxref_load_chain (ppdoc *pdf, ppxref *xref);
-
-/* Parsing xref table
-
-  1 10               // first ref number and refs count
-  0000000000 00000 n // 10-digits offset, 5 digits version, type identifier
-  0000000000 00000 n // n states for normal I guess
-  0000000000 00000 f // f states for free (not used)
-  ...
-
-Free entries seem to be a relic of ancient times, completelly useless for us. To avoid parsing xref table twice,
-we waste some space on free entries by allocating one plane of refs for each section. Later on we slice sections,
-so that effectively free entries are not involved in map.
-
-Subsequent refs gets number, version and offset. Other fields initialized when parsing PDF body.
-
-Having xref table loaded, we sort sections for future binary search (xref with objects count == 0 is considered invalid).
-
-Then we have to deal with the trailer dict. In general, to load objects and resolve references we need a complete chain
-of xrefs (not only the top). To load the previous xref, we need its offset, which is given in trailer. So we have to
-parse the trailer ignoring references, which might be unresolvable at this point (objects parser makes a dummy check
-for xref != NULL on refs resolving ppscan_obj(), which irritates me but I don't want a separate parser for trailer..).
-The same applies to xref streams, in which we have parse the trailer not having xref map at all. So the procedure is:
-
-  - load xref map, initialize references, make it ready to search
-  - parse trailer ignoring references
-  - get /Prev xref offset and load older xref (linked list via ->prev)
-  - sort all refs in all xrefs by offset
-  - parse refs in order resolving references in contained objects
-  - fix trailer references
-
-First created xref becomes a pdf->xref (top xref). We link that early to control offsets already read (insane loops?).
-*/
-
-// Every xref table item "0000000000 00000 n" is said to be terminated with 2-byte EOL but we don't like relying on whites.
-#define xref_item_length (10+1+5+1+1)
-
-static ppxref * ppxref_load_table (iof *I, ppdoc *pdf, size_t xrefoffset)
-{
-  ppxref *xref;
-  ppxsec *xrefsection;
-  ppref *ref;
-  ppuint first, count, refindex;
-  uint8_t buffer[xref_item_length + 1];
-  const char *p;
-  const ppobj *obj;
-
-  buffer[xref_item_length] = '\0';
-  xref = ppxref_create(pdf, 0, xrefoffset);
-  if (pdf->xref == NULL) pdf->xref = xref;
-  for (ppscan_find(I); ppscan_uint(I, &first); ppscan_find(I))
-  {
-    ppscan_find(I);
-    if (!ppscan_uint(I, &count))
-      return NULL;
-    if (count == 0) // weird
-      continue;
-    xref->count += count;
-    xrefsection = NULL;
-    ref = (ppref *)ppheap_take(&pdf->heap, count * sizeof(ppref));
-    for (refindex = 0; refindex < count; ++refindex, ++ref)
-    {
-      ref->xref = xref;
-      ref->number = first + refindex;
-      ppscan_find(I);
-      iof_read(I, buffer, xref_item_length);
-      switch (buffer[xref_item_length - 1])
-      {
-        case 'n':
-          if (xrefsection == NULL)
-          {
-            xrefsection = ppxref_push_section(xref, &pdf->heap);
-            xrefsection->first = ref->number;
-            xrefsection->refs = ref;
-          }
-          xrefsection->last = ref->number;
-          for (p = (const char *)buffer; *p == '0'; ++p);
-          p = ppread_uint(p, &ref->offset);
-          for ( ; *p == ' ' || *p == '0'; ++p);
-          p = ppread_uint(p, &ref->version);
-          ref->object.type = PPNONE; // init for sanity
-          ref->object.any = NULL;
-          ref->length = 0;
-          break;
-        case 'f':
-        default:
-          --ref;
-          xrefsection = NULL;
-          --xref->count;
-      }
-    }
-  }
-  /* sort section */
-  if (!ppxref_sort(xref))
-    ; // case of xref->size == 0 handled by ppxref_load_chain()
-  /* get trailer ignoring refs */
-  if (!ppscan_key(I, "trailer"))
-    return NULL;
-  ppscan_find(I);
-  if ((obj = ppscan_obj(I, pdf, NULL)) == NULL)
-    return NULL;
-  ppstack_pop(&pdf->stack, 1);
-  if (obj->type != PPDICT)
-    return NULL;
-  xref->trailer = *obj;
-  return ppxref_load_chain(pdf, xref);
-}
-
-/* Parsing xref stream
-First we load the trailer, ignoring references. Dict defines sections and fields lengths:
-
-  /Size                                  % max ref number plus 1
-  /Index [ first count first count ... ] % a pair of numbers for every section, defaults to [0 Size]
-  /W [w1 w2 w3]                          % fields lengths, 0 states for omitted field
-
-xref stream data is a continuous stream of binary number triplets. First number is a type:
-
-  0 - free entry (as 'f' in xref table)
-  1 - normal entry, followed by offset an version (as 'n' in xref table)
-  2 - compressed entry, followed by parent object stream number and entry index
-
-0 and 1 are handled as 'n' and 'f' entries in xref table. For type 2 we normally initialize
-ref->number and ref->version (the later is implicitly 0). ref->offset is set to 0 (invalid offset),
-which is recognized by objects loader.
-*/
-
-#define XREF_STREAM_MAX_FIELD 4
-
-static ppxref * ppxref_load_stream (iof *I, ppdoc *pdf, size_t xrefoffset)
-{
-  ppxref *xref;
-  ppxsec *xrefsection;
-  ppref *ref;
-  ppobj *obj;
-  ppstream *xrefstream;
-  size_t streamoffset;
-  ppuint w1, w2, w3, w, bufferbytes;
-  uint8_t buffer[3 * XREF_STREAM_MAX_FIELD], *b;
-  ppuint first, count, f1, f2, f3;
-  pparray *fieldwidths, *sectionindices;
-  ppobj sectionmock[2], *sectionfirst, *sectioncount;
-  size_t sections, sectionindex, refindex;
-
-  if (!ppscan_skip_entry(I))
-    return NULL;
-  if ((obj = ppscan_obj(I, pdf, NULL)) == NULL)
-    return NULL;
-  ppstack_pop(&pdf->stack, 1);
-  if (obj->type != PPDICT || !ppscan_start_stream(I, pdf, &streamoffset))
-    return NULL;
-  xrefstream = ppstream_create(pdf, obj->dict, streamoffset);
-  /* All normal streams go through ppstream_info(), but it makes no sense for trailer stream (no crypt allowed, no refs yet).
-     So we just record the length and informative flag. Here we have to expect that /Length and /Filter are not indirects. */
-  if (!ppdict_get_uint(obj->dict, "Length", &xrefstream->length))
-    return NULL;
-  if (ppdict_get_obj(obj->dict, "Filter") != NULL)
-    xrefstream->flags |= PPSTREAM_COMPRESSED;
-  if ((fieldwidths = ppdict_get_array(xrefstream->dict, "W")) != NULL)
-  {
-    if (!pparray_get_uint(fieldwidths, 0, &w1)) w1 = 0;
-    if (!pparray_get_uint(fieldwidths, 1, &w2)) w2 = 0;
-    if (!pparray_get_uint(fieldwidths, 2, &w3)) w3 = 0;
-  }
-  else
-    w1 = w2 = w3 = 0;
-  if (w1 > XREF_STREAM_MAX_FIELD || w2 > XREF_STREAM_MAX_FIELD || w3 > XREF_STREAM_MAX_FIELD)
-    return NULL;
-  bufferbytes = w1 + w2 + w3;
-  if ((sectionindices = ppdict_get_array(xrefstream->dict, "Index")) != NULL)
-  {
-    sections = sectionindices->size >> 1;
-    sectionfirst = sectionindices->data;
-  }
-  else
-  {
-    sections = 1;
-    sectionmock[0].type = PPINT;
-    sectionmock[0].integer = 0;
-    sectionmock[1].type = PPINT;
-    if (!ppdict_get_int(xrefstream->dict, "Size", &sectionmock[1].integer))
-      sectionmock[1].integer = 0;
-    sectionfirst = &sectionmock[0];
-  }
-  if ((I = ppstream_read(xrefstream, 1, 0)) == NULL)
-    return NULL; // we fseek() so original I is useless anyway
-  xref = ppxref_create(pdf, sections, xrefoffset);
-  if (pdf->xref == NULL) pdf->xref = xref;
-  xref->trailer.type = PPSTREAM;
-  xref->trailer.stream = xrefstream;
-  for (sectionindex = 0; sectionindex < sections; ++sectionindex, sectionfirst += 2)
-  {
-    sectioncount = sectionfirst + 1;
-    if (!ppobj_get_uint(sectionfirst, first) || !ppobj_get_uint(sectioncount, count))
-      goto xref_stream_error;
-    if (count == 0)
-      continue;
-    xref->count += count;
-    xrefsection = NULL;
-    ref = (ppref *)ppheap_take(&pdf->heap, count * sizeof(ppref));
-    for (refindex = 0; refindex < count; ++refindex, ++ref)
-    {
-      ref->xref = xref;
-      ref->number = first + refindex;
-      if (iof_read(I, buffer, bufferbytes) != bufferbytes)
-        goto xref_stream_error;
-      b = buffer;
-      if (w1 == 0)
-        f1 = 1; // default type is 1
-      else
-        for (f1 = 0, w = 0; w < w1; f1 = (f1 << 8)|(*b), ++w, ++b);
-      for (f2 = 0, w = 0; w < w2; f2 = (f2 << 8)|(*b), ++w, ++b);
-      for (f3 = 0, w = 0; w < w3; f3 = (f3 << 8)|(*b), ++w, ++b);
-      switch (f1)
-      {
-        case 0:
-          //--ref;
-          xrefsection = NULL;
-          --xref->count;
-          break;
-        case 1:
-          if (xrefsection == NULL)
-          {
-            xrefsection = ppxref_push_section(xref, &pdf->heap);
-            xrefsection->first = ref->number;
-            xrefsection->refs = ref;
-          }
-          xrefsection->last = ref->number;
-          ref->offset = f2;
-          ref->version = f3;
-          ref->object.type = PPNONE;
-          ref->object.any = NULL;
-          ref->length = 0;
-          break;
-        case 2:
-          if (xrefsection == NULL)
-          {
-            xrefsection = ppxref_push_section(xref, &pdf->heap);
-            xrefsection->first = ref->number;
-            xrefsection->refs = ref;
-          }
-          xrefsection->last = ref->number;
-          ref->offset = 0; // f2 is parent objstm, f3 is index in parent, both useless
-          ref->version = 0; // compressed objects has implicit version == 0
-          ref->object.type = PPNONE;
-          ref->object.any = NULL;
-          ref->length = 0;
-          break;
-        default:
-          goto xref_stream_error;
-      }
-    }
-  }
-  /* sort sections */
-  if (!ppxref_sort(xref))
-    ; // case of xref->size == 0 handled by ppxref_load_chain()
-  /* close the stream _before_ loading prev xref */
-  ppstream_done(xrefstream);
-  /* load prev and return */
-  return ppxref_load_chain(pdf, xref);
-xref_stream_error:
-  ppstream_done(xrefstream);
-  return NULL;
-}
-
-/*
-The following procedure loads xref /Prev, links xref->prev and typically returns xref.
-Some docs contain empty xref (one section with zero objects) that is actually a proxy
-to xref stream referred as /XRefStm (genuine concept of xrefs old/new style xrefs in
-the same doc). In case of 0-length xref we ignore the proxy and return the target xref
-(otherwise we would need annoying sanity check for xref->size > 0 on every ref search).
-*/
-
-static ppxref * ppxref_load_chain (ppdoc *pdf, ppxref *xref)
-{
-  ppdict *trailer;
-  ppuint xrefoffset;
-  ppxref *prevxref, *nextxref;
-
-  trailer = ppxref_trailer(xref);
-  if (!ppdict_get_uint(trailer, "Prev", &xrefoffset)) // XRefStm is useless
-    return xref; // missing /Prev is obviously ok
-  for (nextxref = pdf->xref; nextxref != NULL; nextxref = nextxref->prev)
-    if (nextxref->offset == xrefoffset) // insane
-      return NULL;
-  if ((prevxref = ppxref_load(pdf, (size_t)xrefoffset)) == NULL)
-    return NULL;
-  if (xref->size > 0)
-  {
-    xref->prev = prevxref;
-    return xref;
-  }
-  if (pdf->xref == xref)
-    pdf->xref = prevxref;
-  return prevxref;
-}
-
-static ppxref * ppxref_load (ppdoc *pdf, size_t xrefoffset)
-{
-  iof *I;
-  if ((I = ppdoc_reader(pdf, xrefoffset, PP_LENGTH_UNKNOWN)) == NULL)
-    return NULL;
-  ppscan_find(I);
-  if (ppscan_key(I, "xref"))
-    return ppxref_load_table(I, pdf, xrefoffset);
-  return ppxref_load_stream(I, pdf, xrefoffset);
-  // iof_close(I) does nothing here
-}
-
-static void ppoffmap_sort (ppref **left, ppref **right)
-{
-  ppref **l, **r, *t;
-  ppuint pivot;
-  l = left, r = right;
-  pivot = (*(l + ((r - l) / 2)))->offset;
-  do
-  { // don't read from pointer!
-    while ((*l)->offset < pivot) ++l;
-    while ((*r)->offset > pivot) --r;
-    if (l <= r)
-    {
-      t = *l;
-      *l = *r;
-      *r = t;
-      ++l, --r;
-    }
-  } while (l <= r);
-  if (left < r)
-    ppoffmap_sort(left, r);
-  if (l < right)
-    ppoffmap_sort(l, right);
-}
-
-
-static void fix_trailer_references (ppdoc *pdf)
-{
-  ppxref *xref;
-  ppdict *trailer;
-  ppname *pkey;
-  ppobj *obj;
-  ppref *ref;
-  for (xref = pdf->xref; xref != NULL; xref = xref->prev)
-  {
-    if ((trailer = ppxref_trailer(xref)) == NULL)
-      continue;
-    for (ppdict_first(trailer, pkey, obj); *pkey != NULL; ppdict_next(pkey, obj))
-    { // no need to go deeper in structs, all items in trailer except info and root must be direct refs
-      if (obj->type != PPREF)
-        continue;
-      ref = obj->ref;
-      if (ref->offset == 0) // unresolved?
-        if ((ref = ppxref_find(xref, ref->number)) != NULL)
-          obj->ref = ref; // at this moment the reference still points nothing, but should be the one with the proper offset
-    }
-  }
-}
-
-/*
-Here comes a procedure that loads all entries from all document bodies. We resolve references while
-parsing objects and to make resolving correct, we need a complete chain of xref maps, and a knowledge
-about possible linearized dict (first offset). So loading refs sorted by offsets makes sense (not sure
-if it matters nowadays but we also avoid fseek() by large offsets).
-
-Here is the proc:
-
-  - create a list of all refs in all bodies
-  - sort the list by offsets
-  - for every ref from the sorted list:
-    - estimate object length to avoid fread-ing more than necessary (not perfect but enough)
-    - fseek() to the proper offset, fread() entry data or its part
-    - parse the object with ppscan_obj(I, pdf, xref), where xref is not necessarily top pdf->xref
-    - save the actual ref->length (not sure if we need that?)
-    - make a stream if a dict is followed by "stream" keyword, also save the stream offset
-  - free the list
-*/
-
-static int ppdoc_load_objstm (ppstream *stream, ppdoc *pdf, ppxref *xref);
-
-static void ppdoc_load_entries (ppdoc *pdf)
-{
-  size_t objects, sectionindex, refnumber, offindex;
-  ppnum linearized;
-  ppref **offmap, **pref, *ref;
-  ppxref *xref;
-  ppxsec *xsec;
-  ppobj *obj;
-  ppname type;
-  int redundant_indirection = 0;
-  ppcrypt *crypt;
-  ppstream *stream;
-
-  if ((objects = (size_t)ppdoc_objects(pdf)) == 0) // can't happen
-    return;
-  pref = offmap = (ppref **)pp_malloc(objects * sizeof(ppref *));
-  objects = 0; // recount refs with offset > 0
-  for (xref = pdf->xref; xref != NULL; xref = xref->prev)
-    for (sectionindex = 0, xsec = xref->sects; sectionindex < xref->size; ++sectionindex, ++xsec)
-      for (refnumber = xsec->first, ref = xsec->refs; refnumber <= xsec->last; ++refnumber, ++ref)
-        if (ref->offset > 0) // 0 means compressed or insane
-          *pref++ = ref, ++objects;
-  ppoffmap_sort(offmap, offmap + objects - 1);
-
-  crypt = pdf->crypt;
-  for (offindex = 0, pref = offmap; offindex < objects; )
-  {
-    ref = *pref;
-    ++pref;
-    ++offindex;
-    if (ref->object.type != PPNONE) // might be preloaded already (/Encrypt dict, stream filter dicts, stream /Length..)
-    	continue;
-    if (offindex < objects)
-      ref->length = (*pref)->offset - ref->offset;
-    else
-      ref->length = pdf->filesize > ref->offset ? pdf->filesize - ref->offset : 0;
-    if (crypt != NULL)
-    {
-      ppcrypt_start_ref(crypt, ref);
-      obj = ppdoc_load_entry(pdf, ref);
-      ppcrypt_end_ref(crypt);
-    }
-    else
-    {
-      obj = ppdoc_load_entry(pdf, ref);
-    }
-    switch (obj->type)
-    {
-      case PPDICT: /* Check if the object at first offset is linearized dict. We need that to resolve all references properly. */
-        if (offindex == 1 && ppdict_get_num(obj->dict, "Linearized", &linearized)) // /Linearized value is a version number, default 1.0
-          pdf->flags |= PPDOC_LINEARIZED;
-        break;
-      case PPREF:
-        redundant_indirection = 1;
-        break;
-      default:
-        break;
-    }
-    // if pdf->crypt crypt->ref = NULL
-  }
-
-  /* refs pointngs refs? cut. */
-  if (redundant_indirection)
-  {
-    for (offindex = 0, pref = offmap; offindex < objects; ++offindex)
-    {
-      ref = *pref++;
-      if (ref->object.type == PPREF)
-        ref->object = ref->object.ref->object; // doing for all effectively cuts all insane chains
-    }
-  }
-
-  /* now handle streams; update stream info (eg. /Length), load pdf 1.5 object streams
-     we could do earlier but then we would need to struggle with indirects */
-  for (offindex = 0, pref = offmap; offindex < objects; ++offindex)
-  {
-    ref = *pref++;
-    obj = &ref->object;
-    if (obj->type != PPSTREAM)
-      continue;
-    stream = obj->stream;
-    if (crypt != NULL)
-    {
-      ppcrypt_start_ref(crypt, ref);
-      ppstream_info(stream, pdf);
-      ppcrypt_end_ref(crypt);
-    }
-    else
-    {
-      ppstream_info(stream, pdf);
-    }
-    if (ref->xref->trailer.type == PPSTREAM && (type = ppdict_get_name(stream->dict, "Type")) != NULL && ppname_is(type, "ObjStm")) // somewhat dummy..
-      if (!ppdoc_load_objstm(stream, pdf, ref->xref))
-        loggerf("invalid objects stream %s at offset " PPSIZEF, ppref_str(ref->number, ref->version), ref->offset);
-  }
-  pp_free(offmap);
-}
-
-ppobj * ppdoc_load_entry (ppdoc *pdf, ppref *ref)
-{
-  iof *I;
-  size_t length;
-  ppxref *xref;
-  ppobj *obj;
-  ppstack *stack;
-  size_t streamoffset;
-  ppref *refref;
-  ppuint refnumber, refversion;
-
-  length = ref->length > 0 ? ref->length : PP_LENGTH_UNKNOWN; // estimated or unknown
-  if ((I = ppdoc_reader(pdf, ref->offset, length)) == NULL || !ppscan_start_entry(I, ref))
-  {
-    loggerf("invalid %s offset " PPSIZEF, ppref_str(ref->number, ref->version), ref->offset);
-    return &ref->object; // PPNONE
-  }
-  stack = &pdf->stack;
-  xref = ref->xref; // to resolve indirects properly
-  if ((obj = ppscan_obj(I, pdf, xref)) == NULL)
-  {
-    loggerf("invalid %s object at offset " PPSIZEF, ppref_str(ref->number, ref->version), ref->offset);
-    return &ref->object; // PPNONE
-  }
-  ref->object = *obj;
-  ppstack_pop(stack, 1);
-  obj = &ref->object;
-  ref->length = ppdoc_reader_tell(pdf, I) - ref->offset;
-  if (obj->type == PPDICT)
-  {
-    if (ppscan_start_stream(I, pdf, &streamoffset))
-    {
-      obj->type = PPSTREAM;
-      obj->stream = ppstream_create(pdf, obj->dict, streamoffset);
-    }
-  }
-  else if (obj->type == PPINT)
-  {
-    ppscan_find(I);
-    if (ppscan_uint(I, &refversion) && ppscan_find(I) == 'R')
-    {
-      refnumber = (ppuint)obj->integer;
-      if ((refref = ppxref_find(xref, refnumber)) != NULL)
-      {
-        obj->type = PPREF;
-        obj->ref = refref;
-      }
-      else
-      {
-        obj->type = PPNONE; // as ppref_unresolved()
-        obj->any = NULL;
-      }
-    }
-  }
-  return obj;
-}
-
-/* Loading entries from object stream
-
-  /N is the number of contained entries
-  /First is the offset of the first item
-
-The stream consists of N pairs of numbers <objnum> <offset> <objnum> <offset> ...
-Offsets are ascending (relative to the first), but ref numbers order is arbitrary.
-PDF spec says there might be some additional data between objects, so we should obey offsets.
-Which means we should basically load the stream at once (may be needed anyway to grab the stream [...]).
-*/
-
-static int ppdoc_load_objstm (ppstream *stream, ppdoc *pdf, ppxref *xref)
-{
-  ppdict *dict; // stream dict, actually still on stack
-  ppref *ref;
-  ppobj *obj;
-  ppuint items, firstoffset, offset, objnum, i, invalid = 0;
-  iof *I;
-  uint8_t *firstdata, *indexdata;
-  ppstack *stack;
-
-  dict = stream->dict;
-  if (!ppdict_rget_uint(dict, "N", &items) || !ppdict_rget_uint(dict, "First", &firstoffset))
-    return 0;
-  if ((I = ppstream_read(stream, 1, 1)) == NULL)
-    return 0;
-  firstdata = I->pos + firstoffset;
-  if (firstdata >= I->end)
-    goto invalid_objstm;
-  stack = &pdf->stack;
-  //if (pdf->crypt != NULL)
-  //  ppcrypt_end_ref(pdf->crypt); // objects are not encrypted, pdf->crypt->ref ensured NULL
-  for (i = 0; i < items; ++i)
-  {
-    ppscan_find(I);
-    if (!ppscan_uint(I, &objnum))
-      goto invalid_objstm;
-    ppscan_find(I);
-    if (!ppscan_uint(I, &offset))
-      goto invalid_objstm;
-    if ((ref = ppxref_find_local(xref, objnum)) == NULL || ref->object.type != PPNONE)
-    {
-      loggerf("invalid compressed object number " PPUINTF " at position " PPUINTF, objnum, i);
-      ++invalid;
-      continue;
-    }
-    if (firstdata + offset >= I->end)
-    {
-      loggerf("invalid compressed object offset " PPUINTF " at position " PPUINTF, offset, i);
-      ++invalid;
-      continue;
-    }
-    indexdata = I->pos; // save position
-    I->pos = firstdata + offset; // go to the object
-    ppscan_find(I);
-    if ((obj = ppscan_obj(I, pdf, xref)) != NULL)
-    {
-      ref->object = *obj;
-      ppstack_pop(stack, 1);
-      // nothing more needed, as obj can never be indirect ref or stream
-    }
-    else
-    {
-      ++invalid;
-      loggerf("invalid compressed object %s at stream offset " PPUINTF, ppref_str(objnum, 0), offset);
-    }
-    I->pos = indexdata; // restore position and read next from index
-  }
-  ppstream_done(stream);
-  return invalid == 0;
-invalid_objstm:
-  ppstream_done(stream);
-  return 0;
-}
-
-/* main PDF loader proc */
-
-ppcrypt_status ppdoc_crypt_pass (ppdoc *pdf, const void *userpass, size_t userpasslength, const void *ownerpass, size_t ownerpasslength)
-{
-  switch (pdf->cryptstatus)
-  {
-    case PPCRYPT_NONE:
-    case PPCRYPT_DONE:
-    case PPCRYPT_FAIL:
-      break;
-    case PPCRYPT_PASS: // initial status or really needs password
-      pdf->cryptstatus = ppdoc_crypt_init(pdf, userpass, userpasslength, ownerpass, ownerpasslength);
-      switch (pdf->cryptstatus)
-      {
-        case PPCRYPT_NONE:
-        case PPCRYPT_DONE:
-          ppdoc_load_entries(pdf);
-          break;
-        case PPCRYPT_PASS: // user needs to check ppdoc_crypt_status() and recall ppdoc_crypt_pass() with the proper password
-        case PPCRYPT_FAIL: // hopeless..
-          break;
-      }
-      break;
-  }
-  return pdf->cryptstatus;
-}
-
-static ppdoc * ppdoc_read (ppdoc *pdf, iof_file *input)
-{
-  uint8_t header[PPDOC_HEADER];
-  size_t xrefoffset;
-
-  input = &pdf->input;
-  if (iof_file_read(header, 1, PPDOC_HEADER, input) != PPDOC_HEADER || !ppdoc_header(pdf, header))
-    return NULL;
-  if (!ppdoc_tail(pdf, input, &xrefoffset))
-    return NULL;
-  if (ppxref_load(pdf, xrefoffset) == NULL)
-    return NULL;
-  fix_trailer_references(pdf); // after loading xrefs but before accessing trailer refs (/Encrypt might be a reference)
-  // check encryption, if any, try empty password
-  switch (ppdoc_crypt_pass(pdf, "", 0, NULL, 0))
-  {
-    case PPCRYPT_NONE: // no encryption
-    case PPCRYPT_DONE: // encryption with an empty password
-    case PPCRYPT_PASS: // the user needs to check ppdoc_crypt_status() and call ppdoc_crypt_pass()
-      break;
-    case PPCRYPT_FAIL: // hopeless
-      //loggerf("decryption failed");
-      //return NULL;
-      break;
-  }
-  return pdf;
-}
-
-static void ppdoc_pages_init (ppdoc *pdf);
-
-static ppdoc * ppdoc_create (iof_file *input)
-{
-  ppdoc *pdf;
-  ppheap *heap;
-
-  heap = ppheap_new();
-  pdf = (ppdoc *)ppheap_take(&heap, sizeof(ppdoc));
-  pdf->flags = 0;
-  pdf->heap = heap;
-  pdf->xref = NULL;
-  pdf->version[0] = '\0';
-  pdf->crypt = NULL;
-  pdf->cryptstatus = PPCRYPT_PASS; // force encryption check on ppdoc_read() -> ppdoc_crypt_pass()
-  ppstack_init(&pdf->stack, &pdf->heap);
-  ppdoc_reader_init(pdf, input);
-  ppdoc_pages_init(pdf);
-  if (ppdoc_read(pdf, &pdf->input) != NULL)
-    return pdf;
-  ppdoc_free(pdf);
-  return NULL;
-}
-
-ppdoc * ppdoc_load (const char *filename)
-{
-  FILE *file;
-  iof_file input;
-  if ((file = fopen(filename, "rb")) == NULL)
-    return NULL;
-  iof_file_init(&input, file);
-  input.flags |= IOF_CLOSE_FILE;
-  return ppdoc_create(&input);
-}
-
-ppdoc * ppdoc_mem (const void *data, size_t size)
-{
-	iof_file input;
-	iof_file_rdata_init(&input, data, size);
-	input.flags |= IOF_BUFFER_ALLOC; // todo: 3 modes: borrow, take over, copy?
-	return ppdoc_create(&input);
-}
-
-void ppdoc_free (ppdoc *pdf)
-{
-  //iof_file_free(&pdf->input);
-  iof_file_decref(&pdf->input);
-  ppstack_free_buffer(&pdf->stack);
-  ppheap_free(pdf->heap); // last!
-}
-
-ppcrypt_status ppdoc_crypt_status (ppdoc *pdf)
-{
-  return pdf->cryptstatus;
-}
-
-ppint ppdoc_permissions (ppdoc *pdf)
-{
-  return pdf->crypt != NULL ? pdf->crypt->permissions : (ppint)0xFFFFFFFFFFFFFFFF;
-}
-
-/* pages access */
-
-static pparray * pppage_node (ppdict *dict, ppuint *count, ppname *type)
-{
-  ppname *pkey, key;
-  ppobj *obj;
-  pparray *kids = NULL;
-  *count = 0;
-  *type = NULL;
-  for (ppdict_first(dict, pkey, obj); (key = *pkey) != NULL; ppdict_next(pkey, obj))
-  {
-    switch (key[0])
-    {
-      case 'T':
-        if (ppname_is(key, "Type"))
-          *type = ppobj_get_name(obj);
-        break;
-      case 'C':
-        if (ppname_is(key, "Count"))
-          ppobj_get_uint(obj, *count);
-        break;
-      case 'K':
-        if (ppname_is(key, "Kids"))
-          kids = ppobj_rget_array(obj);
-        break;
-    }
-  }
-  return kids;
-}
-
-#define ppname_is_page(type) (type != NULL && ppname_is(type, "Page"))
-
-ppuint ppdoc_page_count (ppdoc *pdf)
-{
-  ppref *ref;
-  ppname type;
-  ppuint count;
-  if ((ref = ppxref_pages(pdf->xref)) == NULL)
-    return 0;
-  if (pppage_node(ref->object.dict, &count, &type) == NULL)
-    return ppname_is_page(type) ? 1 : 0; // acrobat and ghostscript accept documents with root /Pages entry being a reference to a sole /Page object
-  return count;
-}
-
-ppref * ppdoc_page (ppdoc *pdf, ppuint index)
-{
-  ppdict *dict;
-  ppuint count;
-  pparray *kids;
-  size_t size, i;
-  ppobj *r, *o;
-  ppref *ref;
-  ppname type;
-
-
-  if ((ref = ppxref_pages(pdf->xref)) == NULL)
-    return NULL;
-  dict = ref->object.dict;
-  if ((kids = pppage_node(dict, &count, &type)) != NULL)
-  {
-    if (index < 1 || index > count)
-      return NULL;
-  }
-  else
-  {
-    return index == 1 && ppname_is_page(type) ? ref : NULL;
-  }
-scan_array:
-  if (index <= count / 2)
-  { // probably shorter way from the beginning
-    for (i = 0, size = kids->size, r = pparray_at(kids, 0); i < size; ++i, ++r)
-    {
-      if (r->type != PPREF)
-        return NULL;
-      o = &r->ref->object;
-      if (o->type != PPDICT)
-        return NULL;
-      dict = o->dict;
-      if ((kids = pppage_node(dict, &count, &type)) != NULL)
-      {
-        if (index <= count)
-          goto scan_array;
-        index -= count;
-        continue;
-      }
-      if (index == 1 && ppname_is_page(type))
-        return r->ref;
-      --index;
-    }
-  }
-  else if ((size = kids->size) > 0) // for safe (size-1)
-  { // probably shorter way from the end
-    index = count - index + 1;
-    for (i = 0, r = pparray_at(kids, size - 1); i < size; ++i, --r)
-    {
-      if (r->type != PPREF)
-        return NULL;
-      o = &r->ref->object;
-      if (o->type != PPDICT)
-        return NULL;
-      dict = o->dict;
-      if ((kids = pppage_node(dict, &count, &type)) != NULL)
-      {
-        if (index <= count)
-          goto scan_array;
-        index -= count;
-        continue;
-      }
-      if (index == 1 && ppname_is_page(type))
-        return r->ref;
-      --index;
-    }
-  }
-  return NULL;
-}
-
-/*
-Through pages iterator. Iterating over pages tree just on the base of /Kids and /Parent keys
-is ineffective, as to get next pageref we need to take parent, find the pageref in /Kids,
-take next (or go upper).. Annoying. We use a dedicated stack for pages iterator. This could
-actually be done with pdf->stack, but some operations may clear it, so safer to keep it independent
-Besides, its depth is constant (set on first use), so no need for allocs.
-*/
-
-static void ppdoc_pages_init (ppdoc *pdf)
-{
-  pppages *pages;
-  pages = &pdf->pages;
-  pages->root = pages->parent = pages->buffer;
-  pages->depth = 0;
-  pages->space = PPPAGES_STACK_DEPTH;
-}
-
-static ppkids * pppages_push (ppdoc *pdf, pparray *kids)
-{
-  ppkids *newroot, *bounds;
-  pppages *pages;
-  pages = &pdf->pages;
-  if (pages->depth == pages->space)
-  {
-    pages->space <<= 1;
-    newroot = (ppkids *)ppheap_take(&pdf->heap, pages->space * sizeof(ppkids));
-    memcpy(newroot, pages->root, pages->depth * sizeof(ppkids));
-    pages->root = newroot;
-  }
-  bounds = pages->parent = &pages->root[pages->depth++];
-  bounds->current = pparray_at(kids, 0);
-  bounds->sentinel = pparray_at(kids, kids->size);
-  return bounds;
-}
-
-#define pppages_pop(pages) (--((pages)->parent), --((pages)->depth))
-
-static ppref * ppdoc_pages_group_first (ppdoc *pdf, ppref *ref)
-{
-  ppdict *dict;
-  pparray *kids;
-  ppuint count;
-  ppname type;
-
-  dict = ref->object.dict; // typecheck made by callers
-  while ((kids = pppage_node(dict, &count, &type)) != NULL)
-  {
-    if ((ref = pparray_get_ref(kids, 0)) == NULL || ref->object.type != PPDICT)
-      return NULL;
-    pppages_push(pdf, kids);
-    dict = ref->object.dict;
-  }
-  return ppname_is_page(type) ? ref : NULL;
-}
-
-ppref * ppdoc_first_page (ppdoc *pdf)
-{
-  ppref *ref;
-  pppages *pages;
-  if ((ref = ppdoc_pages(pdf)) == NULL)
-    return NULL;
-  pages = &pdf->pages;
-  pages->parent = pages->root;
-  pages->depth = 0;
-  return ppdoc_pages_group_first(pdf, ref);
-}
-
-ppref * ppdoc_next_page (ppdoc *pdf)
-{
-  pppages *pages;
-  ppkids *bounds;
-  ppref *ref;
-  ppobj *obj;
-  pages = &pdf->pages;
-  while (pages->depth > 0)
-  {
-    bounds = pages->parent;
-    obj = ++bounds->current;
-    if (obj < bounds->sentinel)
-    {
-      if (obj->type != PPREF)
-        return NULL;
-      ref = obj->ref;
-      if (ref->object.type != PPDICT)
-        return NULL;
-      return ppdoc_pages_group_first(pdf, ref);
-    }
-    else
-    { // no next node, go upper
-      pppages_pop(pages);
-    }
-  }
-  return NULL;
-}
-
-/* context */
-
-ppcontext * ppcontext_new (void)
-{
-  ppheap *heap;
-  ppcontext *context;
-  heap = ppheap_new();
-  context = (ppcontext *)pp_malloc(sizeof(ppcontext)); // not from priv heap, as we delete it on renew
-  context->heap = heap;
-  ppstack_init(&context->stack, &context->heap);
-  return context;
-}
-
-void ppcontext_done (ppcontext *context)
-{
-  ppheap_renew(context->heap);
-  ppstack_clear(&context->stack);
-}
-
-void ppcontext_free (ppcontext *context)
-{
-  ppstack_free_buffer(&context->stack);
-  ppheap_free(context->heap);
-  pp_free(context);
-}
-
-/* page contents streams */
-
-//#define ppcontents_first_stream(array) pparray_rget_stream(array, 0)
-
-static ppstream * ppcontents_first_stream (pparray *array)
-{
-  size_t i;
-  ppobj *obj;
-  ppref *ref;
-  for (pparray_first(array, i, obj); i < array->size; pparray_next(i, obj))
-    if ((ref = ppobj_get_ref(obj)) != NULL && ref->object.type == PPSTREAM)
-      return ref->object.stream;
-  return NULL;
-}
-
-static ppstream * ppcontents_next_stream (pparray *array, ppstream *stream)
-{
-  size_t i;
-  ppobj *obj;
-  ppref *ref;
-  for (pparray_first(array, i, obj); i < array->size; pparray_next(i, obj))
-    if ((ref = ppobj_get_ref(obj)) != NULL && ref->object.type == PPSTREAM && ref->object.stream == stream)
-      if (++i < array->size && (ref = ppobj_get_ref(obj + 1)) != NULL && ref->object.type == PPSTREAM)
-        return ref->object.stream;
-  return NULL;
-}
-
-ppstream * ppcontents_first (ppdict *dict)
-{
-  ppobj *contentsobj;
-  if ((contentsobj = ppdict_rget_obj(dict, "Contents")) == NULL)
-    return NULL;
-  switch (contentsobj->type)
-  {
-    case PPARRAY:
-      return ppcontents_first_stream(contentsobj->array);
-    case PPSTREAM:
-      return contentsobj->stream;
-    default:
-      break;
-  }
-  return NULL;
-}
-
-ppstream * ppcontents_next (ppdict *dict, ppstream *stream)
-{
-  ppobj *contentsobj;
-  if ((contentsobj = ppdict_rget_obj(dict, "Contents")) == NULL)
-    return NULL;
-  switch (contentsobj->type)
-  {
-    case PPARRAY:
-      return ppcontents_next_stream(contentsobj->array, stream);
-    case PPSTREAM:
-      break;
-    default:
-      break;
-  }
-  return NULL;
-}
-
-static ppobj * ppcontents_op (iof *I, ppstack *stack, size_t *psize, ppname *pname)
-{
-  ppobj *obj;
-  ppstack_clear(stack);
-  do {
-    if (ppscan_find(I) < 0)
-      return NULL;
-    if ((obj = ppscan_psobj(I, stack)) == NULL)
-      return NULL;
-  } while (obj->type != PPNAME || !ppname_exec(obj->name));
-  *pname = obj->name;
-  *psize = stack->size - 1;
-  return stack->buf;
-}
-
-ppobj * ppcontents_first_op (ppcontext *context, ppstream *stream, size_t *psize, ppname *pname)
-{
-  iof *I;
-  if ((I = ppstream_read(stream, 1, 0)) == NULL)
-    return NULL;
-  return ppcontents_op(I, &context->stack, psize, pname);
-}
-
-ppobj * ppcontents_next_op (ppcontext *context, ppstream *stream, size_t *psize, ppname *pname)
-{
-  return ppcontents_op(ppstream_iof(stream), &context->stack, psize, pname);
-}
-
-ppobj * ppcontents_parse (ppcontext *context, ppstream *stream, size_t *psize)
-{
-  iof *I;
-  ppstack *stack;
-  ppobj *obj;
-  stack = &context->stack;
-  ppstack_clear(stack);
-  if ((I = ppstream_read(stream, 1, 0)) == NULL)
-    return NULL;
-  while (ppscan_find(I) >= 0)
-    if ((obj = ppscan_psobj(I, stack)) == NULL)
-      goto error;
-  *psize = stack->size;
-  ppstream_done(stream);
-  return stack->buf;
-error:
-  ppstream_done(stream);
-  return NULL;
-}
-
-/* boxes */
-
-pprect * pparray_to_rect (pparray *array, pprect *rect)
-{
-  ppobj *obj;
-  if (array->size != 4)
-    return NULL;
-  obj = pparray_at(array, 0);
-  if (!ppobj_get_num(obj, rect->lx)) return NULL;
-  obj = pparray_at(array, 1);
-  if (!ppobj_get_num(obj, rect->ly)) return NULL;
-  obj = pparray_at(array, 2);
-  if (!ppobj_get_num(obj, rect->rx)) return NULL;
-  obj = pparray_at(array, 3);
-  if (!ppobj_get_num(obj, rect->ry)) return NULL;
-  return rect;
-}
-
-pprect * ppdict_get_rect (ppdict *dict, const char *name, pprect *rect)
-{
-  pparray *array;
-  return (array = ppdict_rget_array(dict, name)) != NULL ? pparray_to_rect(array, rect) : NULL;
-}
-
-pprect * ppdict_get_box (ppdict *dict, const char *name, pprect *rect)
-{
-  do {
-    if (ppdict_get_rect(dict, name, rect) != NULL)
-      return rect;
-    dict = ppdict_rget_dict(dict, "Parent");
-  } while (dict != NULL);
-  return NULL;
-}
-
-ppmatrix * pparray_to_matrix (pparray *array, ppmatrix *matrix)
-{
-  ppobj *obj;
-  if (array->size != 6)
-    return NULL;
-  obj = pparray_at(array, 0);
-  if (!ppobj_get_num(obj, matrix->xx)) return NULL;
-  obj = pparray_at(array, 1);
-  if (!ppobj_get_num(obj, matrix->xy)) return NULL;
-  obj = pparray_at(array, 2);
-  if (!ppobj_get_num(obj, matrix->yx)) return NULL;
-  obj = pparray_at(array, 3);
-  if (!ppobj_get_num(obj, matrix->yy)) return NULL;
-  obj = pparray_at(array, 4);
-  if (!ppobj_get_num(obj, matrix->x)) return NULL;
-  obj = pparray_at(array, 5);
-  if (!ppobj_get_num(obj, matrix->y)) return NULL;
-  return matrix;
-}
-
-ppmatrix * ppdict_get_matrix (ppdict *dict, const char *name, ppmatrix *matrix)
-{
-  pparray *array;
-  return (array = ppdict_rget_array(dict, name)) != NULL ? pparray_to_matrix(array, matrix) : NULL;
-}
-
-/* logger */
-
-void pplog_callback (pplogger_callback logger, void *alien)
-{
-	logger_callback((logger_function)logger, alien);
-}
-
-int pplog_prefix (const char *prefix)
-{
-	return logger_prefix(prefix);
-}
-
-/* version */
-
-const char * ppdoc_version_string (ppdoc *pdf)
-{
-  return pdf->version;
-}
-
-int ppdoc_version_number (ppdoc *pdf, int *minor)
-{
-  *minor = pdf->version[2] - '0';
-  return pdf->version[0] - '0';
-}
-
-/* doc info */
-
-size_t ppdoc_file_size (ppdoc *pdf)
-{
-  return pdf->filesize;
-}
-
-ppuint ppdoc_objects (ppdoc *pdf)
-{
-  ppuint count;
-  ppxref *xref;
-  for (count = 0, xref = pdf->xref; xref != NULL; xref = xref->prev)
-    count += xref->count;
-  return count;
-}
-
-size_t ppdoc_memory (ppdoc *pdf, size_t *waste)
-{
-  size_t used;
-  ppheap *heap;
-  used = 0, *waste = 0;
-  for (heap = pdf->heap; heap != NULL; heap = heap->prev)
-  {
-    used += heap->space;
-    *waste += heap->size;
-  }
-  return used;
-}

Deleted: trunk/Build/source/texk/web2c/luatexdir/luapplib/util/utilfpred.c-OK
===================================================================
--- trunk/Build/source/texk/web2c/luatexdir/luapplib/util/utilfpred.c-OK	2018-09-05 21:32:42 UTC (rev 48592)
+++ trunk/Build/source/texk/web2c/luatexdir/luapplib/util/utilfpred.c-OK	2018-09-05 21:35:27 UTC (rev 48593)
@@ -1,767 +0,0 @@
-/* predictor filters; common for flate and lzw */
-
-#include "utilmem.h"
-#include "utillog.h"
-#include "utilfpred.h"
-
-/*
-Here we implement predictor filters used with flate and lzw compressions in PDF streams. The main idea of data prediction
-is to compute and output the differences between data records instead of this records. Adjacent pixels in images are usually
-similar, so differences between pixel values tends to be zero. And both Flate and LZW performs better when the input
-is rather smooth. Although a preliminary use of predictors is related to bitmap data, The actual need for predictor filter
-came from the fact that xref streams may also be predicted (usually with PNG up-predictor).
-
-PDF specification allows to use several predictor algorithms, specified by /Predictor key in /DecodeParms dictionary:
-
-   1 - no predictor (default)
-   2 - TIFF horizontal predictor
-  10 - PNG none predictor
-  11 - PNG sub predictor
-  12 - PNG up predictor
-  13 - PNG average predictor
-  14 - PNG paeth predictor
-
-All PNG predictors works on bytes, regardless the image color-depth. While encoding, every input data byte is decreased
-by the appropriate byte of the previous pixel. Even if the pixel does not fit a full byte, PNG predictors use an artificial
-pixel size rounded up to a full byte. PNG predictors utilizes previous (left) pixel, pixel above and previous to above
-pixel. In case of PNG, the type of the predictor is written on a dedicated byte on the beginning of every scanline. It
-means all predictor functions must maintain and information about left, above and left-above pixels.
-
-Despite the same differencing idea, TIFF predictors are different. The prediction process bases on pixel components,
-which are not necessarily bytes (component of a pixel is added/substracted from a relevant component of a previous
-pixel). In TIFF predictor 2, only the previous (the left) pixel is taken into account, there is no need to keep
-an information about other surrounding pixels. Also there is no expicit algorithm marker in data; the same prediction
-method is applied to all input rows.
-
-Not surprisingly, predictor encoders and decoders are pretty similar. Encoders take some input value and the previous
-input value (or 0 at the beginning of the scanline) and output a difference between them. Decoders takes an input value,
-previously decoded value (or zero) and outputs their sum. When encoding, the result is cast to the proper unsigned integer,
-when decoding, modulo 256 (or appropriate) is used, which makes encoding and decoding looseless.
-
-Some extra bits trickery is involved in TIFF predictor function, when components doesn't fit bytes boundary. In that case,
-an input is treated as an bits stream. Every input byte is "buffered" in a larger integer, as its lower bits (from right).
-Every output value is taken from its higher (left) bits. In a special case of bits-per-component equal 1, we buffer all
-pixel bits and use XOR to compute bits difference between pixels. I've excerpted that trick from poppler, but I'm not
-really sure if it works any better, especially when the number of components per pixel is 1. In that case we do a hard
-bit-by-bit work anyway.
-
-Predictor codecs state keeps a notion of surrounding pixels. PNG predictors uses left, up and upleft
-pixel data, while TIFF predictor (2) only needs the previous (left) pixel. Important to note that PNG
-predictors always work on bytes, no matter of color-depth (bits per component), while TIFF predictor
-works on pixel components, which not necessarily fits into a complete byte. However, for PNG predictor
-the size of a pixel still matters, because 'left' and 'upleft' refers to a corresponding pixel byte,
-not necessarily previous byte.
-
-In PNG prediction, we record every pixel byte (in decoded form) in state->rowsave. At the end of a scanline
-we copy state->rowsave to state->rowup, so that in the next scanline we can access up-pixel byte.
-Left pixel byte is accessed as state->rowsave (the byte recently stored or virtual left edge byte \0).
-Up-left pixel byte is accessed via state->rowup, but with state->pixelsize offset (same as left byte, possibly \0
-at the left edge of the row). Both state->rowup and state->rowsave has a safe span of pixelsize bytes on the left,
-that are permanently \0.
-*/
-
-#define predictor_component_t unsigned short
-#define predictor_pixel1b_t unsigned int
-
-typedef struct predictor_state {
-  int default_predictor;                      /* default predictor indicator */
-  int current_predictor;                      /* current predictor, possibly taken from algorithm marker in PNG data */
-  int rowsamples;                             /* number of pixels in a scanline (/DecodeParms << /Columns ... >>) */
-  int compbits;                               /* number of bits per component (/DecodeParms << /BitsPerComponent ... >>) */
-  int components;                             /* number of components (/DecodeParms << /Colors ... >>) */
-  uint8_t *buffer;                            /* temporary private buffer area */
-  uint8_t *rowin;                             /* an input row buffer position */
-  int rowsize;                                /* size of a current scanline in bytes (rounded up) */
-  int rowend;                                 /* an input buffer end position */
-  int rowindex;                               /* an output buffer position */
-  union {
-    struct {                                  /* used by PNG predictor codecs */
-      uint8_t *rowup, *rowsave;               /* previous scanline buffers */
-      int predictorbyte;                      /* flag indicating that algorithm byte is read/written */
-      int pixelsize;                          /* number of bytes per pixel (rounded up) */
-    };
-    struct {                                  /* used by TIFF predictor codecs */
-      union {
-        predictor_component_t *prevcomp;      /* an array of left pixel components */
-        predictor_pixel1b_t *prevpixel;       /* left pixel value stored on a single integer (for 1bit color-depth) */
-      };
-      int compin, compout;                    /* bit stream buffers */
-      int bitsin, bitsout;                    /* bit stream counters */
-      int sampleindex;                        /* pixel counter */
-      int compindex;                          /* component counter */
-      int pixbufsize;                         /* size of pixel buffer in bytes */
-    };
-  };
-  int flush;
-  int status;
-} predictor_state;
-
-enum {
-  STATUS_LAST = 0,
-  STATUS_CONTINUE = 1 // any value different then IOFEOF, IOFERR, ...
-};
-
-predictor_state * predictor_decoder_init (predictor_state *state, int predictor, int rowsamples, int components, int compbits)
-{
-  int rowsize, pixelsize;
-#define storage_pos(b, p, size) ((b = p), (p += size))
-  uint8_t *buffer, *p;
-  size_t buffersize;
-
-  pixelsize = (components * compbits + 7) >> 3; // to bytes, rounded up
-  rowsize = (rowsamples * components * compbits + 7) >> 3;
-
-  state->default_predictor = state->current_predictor = predictor;
-  state->rowsamples = rowsamples;
-  state->components = components;
-  state->compbits = compbits;
-
-  if (predictor == 2)
-  { /* tiff predictor */
-    size_t compbuf, pixbuf;
-    compbuf = state->components * sizeof(predictor_component_t);
-    pixbuf = 1 * sizeof(predictor_pixel1b_t);
-    state->pixbufsize = (int)(compbuf > pixbuf ? compbuf : pixbuf);
-    buffersize = rowsize + state->pixbufsize;
-    buffer = (uint8_t *)util_calloc(buffersize, 1);
-    state->prevcomp = (predictor_component_t *)(state->rowin + rowsize);
-    state->sampleindex = state->compindex = 0;
-    state->bitsin = state->bitsout = 0;
-    state->compin = state->compout = 0;
-  }
-  else
-  { /* png predictors */
-    buffersize = (3 * rowsize + 2 * pixelsize + 1) * sizeof(uint8_t);
-    p = buffer = (uint8_t *)util_calloc(buffersize, 1);
-    storage_pos(state->rowin, p, 1 + rowsize); // one extra byte for prediction algorithm tag
-    p += pixelsize;                            // pixelsize extra bytes for virtual left pixel at the edge, eg. rowup[-1] (permanently \0)
-    storage_pos(state->rowup, p, rowsize);     // actual row byte
-    p += pixelsize;                            // ditto
-    storage_pos(state->rowsave, p, rowsize);
-    state->pixelsize = pixelsize;
-    state->predictorbyte = 0;
-  }
-  state->buffer = buffer;
-  state->rowsize = rowsize;
-  state->rowindex = 0;
-  state->rowend = 0;
-  state->status = STATUS_CONTINUE;
-  return state;
-}
-
-predictor_state * predictor_encoder_init (predictor_state *state, int predictor, int rowsamples, int components, int compbits)
-{
-  return predictor_decoder_init(state, predictor, rowsamples, components, compbits);
-}
-
-void predictor_decoder_close (predictor_state *state)
-{
-  util_free(state->buffer);
-}
-
-void predictor_encoder_close (predictor_state *state)
-{
-  util_free(state->buffer);
-}
-
-/*
-Predictor type identifiers (pdf spec 76). lpdf doesn't hire the codec if predictor is 1. Predictor 15 indicates
-that the type of PNG prediction algorithm may change in subsequent lines. We always check algorithm marker anyway.
-*/
-
-enum predictor_code {
-  NONE_PREDICTOR = 1,
-  TIFF_PREDICTOR = 2,
-  PNG_NONE_PREDICTOR = 10,
-  PNG_SUB_PREDICTOR = 11,
-  PNG_UP_PREDICTOR = 12,
-  PNG_AVERAGE_PREDICTOR = 13,
-  PNG_PAETH_PREDICTOR = 14,
-  PNG_OPTIMUM_PREDICTOR = 15
-};
-
-/*
-All predoctor codecs first read the entire data row into a buffer. This is not crucial for the process,
-but allows to separate read/write states. In particular, there is one place in which codec functions
-may return on EOD.
-*/
-
-#define start_row(state) (state->rowindex = 0, state->rowin = state->buffer)
-
-static int read_scanline (predictor_state *state, iof *I, int size)
-{
-  int rowtail, left;
-  while ((rowtail = size - state->rowend) > 0)
-  {
-    left = (int)iof_left(I);
-    if (left >= rowtail)
-    {
-      memcpy(state->buffer + state->rowend, I->pos, (size_t)rowtail);
-      state->rowend += rowtail;
-      I->pos += rowtail;
-      start_row(state);
-      break;
-    }
-    else
-    {
-      if ((rowtail = left) > 0)
-      {
-        memcpy(state->buffer + state->rowend, I->pos, (size_t)rowtail);
-        state->rowend += rowtail;
-        I->pos += rowtail;
-      }
-      if (iof_input(I) == 0)
-      {
-        if (state->rowend == 0) // no scanline to process, no more input
-          return state->flush ? IOFEOF : IOFEMPTY;
-        /* If we are here, there is an incomplete scanline in buffer:
-           - if there is a chance for more (state->flush == 0), than wait for more
-           - otherwise encode/decode the last incomplete line?
-           pdf spec p. 76 says that "A row occupies a whole number of bytes",
-           so this situation should be considered abnormal (not found so far).
-         */
-        if (!state->flush)
-          return IOFEMPTY;
-        loggerf("incomplete scanline in predictor filter");
-        //return IOFERR;
-        state->status = STATUS_LAST;
-        state->rowsize -= size - state->rowend;
-        start_row(state);
-        break;
-      }
-    }
-  }
-  return STATUS_CONTINUE;
-}
-
-#define read_row(state, I, size, status) if ((status = read_scanline(state, I, size)) != STATUS_CONTINUE) return status
-
-#define ensure_output_bytes(O, n) if (!iof_ensure(O, n)) return IOFFULL
-
-#define tobyte(c) ((unsigned char)(c))
-#define tocomp(c) ((unsigned short)(c))
-
-#define row_byte(state) (state->rowin[state->rowindex])
-
-#define up_pixel_byte(state)     (state->rowup[state->rowindex])
-#define upleft_pixel_byte(state) (state->rowup[state->rowindex - state->pixelsize])
-#define left_pixel_byte(state)   (state->rowsave[state->rowindex - state->pixelsize])
-
-#define save_pixel_byte(state, c) (state->rowsave[state->rowindex] = c)
-
-#define left_pixel_component(state) (state->prevcomp[state->compindex]) // tiff predictor with 2, 4, 8, 16 components
-#define left_pixel_value(state) (state->prevpixel[0])                   // tiff predictor with 1bit components
-
-#define save_pixel_component(state, c) ((void)\
-  ((state->prevcomp[state->compindex] = c), \
-   (++state->compindex < state->components || (state->compindex = 0))))
-
-#define save_pixel_value(state, c) (state->prevpixel[0] = c)
-
-/* Once the codec function is done with the scanline, we set imaginary left pixel data to zero, and reset row counters to
-zero in order to allow buffering another input scanline. */
-
-#define reset_row(state) state->rowend = 0
-
-#define reset_png_row(state) (memcpy(state->rowup, state->rowsave, state->rowsize), state->predictorbyte = 0, reset_row(state))
-
-#define reset_tiff_row(state) \
-  memset(state->prevcomp, 0, state->pixbufsize), \
-  state->bitsin = state->bitsout = 0, \
-  state->compin = state->compout = 0, \
-  reset_row(state), \
-  state->sampleindex = state->compindex = 0
-
-/* PNG paeth predictor function; http://www.libpng.org/pub/png/book/chapter09.html
-Compute the base value p := left + up - upleft, then choose that byte the closest
-(of the smallest absolute difference) to the base value. Left byte has a precedence. */
-
-
-static int paeth (predictor_state *state)
-{
-  int p, p1, p2, p3;
-  p = left_pixel_byte(state) + up_pixel_byte(state) - upleft_pixel_byte(state);
-  p1 = p >= left_pixel_byte(state)   ? (p - left_pixel_byte(state))   : (left_pixel_byte(state) - p);
-  p2 = p >= up_pixel_byte(state)     ? (p - up_pixel_byte(state))     : (up_pixel_byte(state) - p);
-  p3 = p >= upleft_pixel_byte(state) ? (p - upleft_pixel_byte(state)) : (upleft_pixel_byte(state) - p);
-  return (p1 <= p2 && p1 <= p3) ? left_pixel_byte(state) : (p2 <= p3 ? up_pixel_byte(state) : upleft_pixel_byte(state));
-}
-
-/* predictor decoder */
-
-iof_status predictor_decode_state (iof *I, iof *O, predictor_state *state)
-{
-  int status, c, d, outbytes;
-  while (state->status == STATUS_CONTINUE)
-  {
-    if (state->default_predictor >= 10) // PNG predictor?
-    {
-      read_row(state, I, state->rowsize + 1, status);
-      if (state->predictorbyte == 0)
-      { // we could actually check state->rowin <> state->buffer, but we need this flag for encoder anyway
-        state->current_predictor = row_byte(state) + 10;
-        state->predictorbyte = 1;
-        ++state->rowin;
-      }
-    }
-    else
-    {
-      read_row(state, I, state->rowsize, status);
-    }
-    switch (state->current_predictor)
-    {
-      case NONE_PREDICTOR:
-        for ( ; state->rowindex < state->rowsize; ++state->rowindex)
-        {
-          ensure_output_bytes(O, 1);
-          c = row_byte(state);
-          iof_set(O, c);
-        }
-        reset_row(state);
-        break;
-      case TIFF_PREDICTOR:
-        switch (state->compbits)
-        {
-          case 1:
-            outbytes = (state->components + 7) >> 3;
-            for ( ; state->sampleindex < state->rowsamples; ++state->sampleindex)
-            {
-              ensure_output_bytes(O, outbytes);
-              while (state->bitsin < state->components)
-              {
-                state->compin = (state->compin << 8) | row_byte(state);
-                state->bitsin += 8;
-                ++state->rowindex;
-              }
-              state->bitsin -= state->components;
-              d = state->compin >> state->bitsin;
-              state->compin &= (1 << state->bitsin) - 1;
-              c = d ^ left_pixel_value(state);
-              save_pixel_value(state, c);
-              state->compout = (state->compout << state->components) | c;
-              state->bitsout += state->components;
-              while (state->bitsout >= 8)
-              {
-                state->bitsout -= 8;
-                iof_set(O, state->compout >> state->bitsout);
-                state->compout &= (1 << state->bitsout) - 1;
-              }
-            }
-            if (state->bitsout > 0)
-            {
-              ensure_output_bytes(O, 1);
-              iof_set(O, state->compin << (8 - state->bitsout));
-            }
-            break;
-          case 2: case 4:
-            for ( ; state->sampleindex < state->rowsamples; ++state->sampleindex)
-            {
-              for ( ; state->compindex < state->components; ) // state->compindex is ++ed  by save_pixel_component()
-              {
-                ensure_output_bytes(O, 1);
-                if (state->bitsin < state->compbits)
-                {
-                  state->compin = (state->compin << 8) | row_byte(state);
-                  state->bitsin += 8;
-                  ++state->rowindex;
-                }
-                state->bitsin -= state->compbits;
-                d = state->compin >> state->bitsin;
-                state->compin &= (1 << state->bitsin) - 1;
-                c = (d + left_pixel_component(state)) & 0xff;
-                save_pixel_component(state, c);
-                state->compout = (state->compout << state->compbits) | c;
-                state->bitsout += state->compbits;
-                if (state->bitsout >= 8)
-                {
-                  state->bitsout -= 8;
-                  iof_set(O, state->compout >> state->bitsout);
-                  state->compout &= (1 << state->bitsout) - 1;
-                }
-              }
-            }
-            if (state->bitsout > 0)
-            {
-              ensure_output_bytes(O, 1);
-              iof_set(O, state->compin << (8 - state->bitsout));
-            }
-            break;
-          case 8:
-            for ( ; state->rowindex < state->rowsize; ++state->rowindex)
-            {
-              ensure_output_bytes(O, 1);
-              c = (row_byte(state) + left_pixel_component(state)) & 0xff;
-              save_pixel_component(state, c);
-              iof_set(O, c);
-            }
-            break;
-          case 16:
-            for ( ; state->rowindex < state->rowsize - 1; ++state->rowindex)
-            {
-              ensure_output_bytes(O, 2);
-              d = row_byte(state) << 8;
-              ++state->rowindex;
-              d |= row_byte(state);
-              c = (d + left_pixel_component(state)) & 0xff;
-              save_pixel_component(state, c);
-              iof_set2(O, c >> 8, c & 0xff);
-            }
-            break;
-          default:
-            return IOFERR;
-        }
-        reset_tiff_row(state);
-        break;
-      case PNG_NONE_PREDICTOR:
-        for ( ; state->rowindex < state->rowsize; ++state->rowindex)
-        {
-          ensure_output_bytes(O, 1);
-          c = row_byte(state);
-          save_pixel_byte(state, c); // next row may need it
-          iof_set(O, c);
-        }
-        reset_png_row(state);
-        break;
-      case PNG_SUB_PREDICTOR:
-        for ( ; state->rowindex < state->rowsize; ++state->rowindex)
-        {
-          ensure_output_bytes(O, 1);
-          c = (row_byte(state) + left_pixel_byte(state)) & 0xff;
-          save_pixel_byte(state, c);
-          iof_set(O, c);
-        }
-        reset_png_row(state);
-        break;
-      case PNG_UP_PREDICTOR:
-        for ( ; state->rowindex < state->rowsize; ++state->rowindex)
-        {
-          ensure_output_bytes(O, 1);
-          c = (row_byte(state) + up_pixel_byte(state)) & 0xff;
-          save_pixel_byte(state, c);
-          iof_set(O, c);
-        }
-        reset_png_row(state);
-        break;
-      case PNG_AVERAGE_PREDICTOR:
-        for ( ; state->rowindex < state->rowsize; ++state->rowindex)
-        {
-          ensure_output_bytes(O, 1);
-          c = (row_byte(state) + ((up_pixel_byte(state) + left_pixel_byte(state)) / 2)) & 0xff;
-          save_pixel_byte(state, c);
-          iof_set(O, c);
-        }
-        reset_png_row(state);
-        break;
-      case PNG_PAETH_PREDICTOR:
-        for ( ; state->rowindex < state->rowsize; ++state->rowindex)
-        {
-          ensure_output_bytes(O, 1);
-          c = (row_byte(state) + paeth(state)) & 0xff;
-          save_pixel_byte(state, c);
-          iof_set(O, c);
-        }
-        reset_png_row(state);
-        break;
-      //case PNG_OPTIMUM_PREDICTOR: // valid as default_redictor, but not as algorithm identifier byte
-      default:
-        return IOFERR;
-    }
-  }
-  return state->status == STATUS_LAST ? IOFERR : IOFEOF;
-}
-
-/* predictor encoder */
-
-iof_status predictor_encode_state (iof *I, iof *O, predictor_state *state)
-{
-  int status, c, d, outbytes;
-  while (state->status == STATUS_CONTINUE)
-  {
-    read_row(state, I, state->rowsize, status);
-    if (state->current_predictor >= 10 && state->predictorbyte == 0)
-    {
-      ensure_output_bytes(O, 1);
-      iof_set(O, state->current_predictor - 10);
-      state->predictorbyte = 1;
-    }
-    switch (state->current_predictor)
-    {
-      case NONE_PREDICTOR:
-        for ( ; state->rowindex < state->rowsize; ++state->rowindex)
-        {
-          ensure_output_bytes(O, 1);
-          c = row_byte(state);
-          iof_set(O, c);
-        }
-        reset_row(state);
-        break;
-      case TIFF_PREDICTOR:
-        switch (state->compbits)
-        {
-          case 1:
-            outbytes = (state->components + 7) >> 3;
-            for ( ; state->sampleindex < state->rowsamples; ++state->sampleindex)
-            {
-              ensure_output_bytes(O, outbytes);
-              while (state->bitsin < state->components)
-              {
-                state->compin = (state->compin << 8) | row_byte(state);
-                state->bitsin += 8;
-                ++state->rowindex;
-              }
-              state->bitsin -= state->components;
-              c = state->compin >> state->bitsin;
-              state->compin &= (1 << state->bitsin) - 1;
-              d = c ^ left_pixel_value(state);
-              save_pixel_value(state, c);
-              state->compout = (state->compout << state->components) | d;
-              state->bitsout += state->components;
-              while (state->bitsout >= 8)
-              {
-                state->bitsout -= 8;
-                iof_set(O, state->compout >> state->bitsout);
-                state->compout &= (1 << state->bitsout) - 1;
-              }
-            }
-            if (state->bitsout > 0)
-            {
-              ensure_output_bytes(O, 1);
-              iof_set(O, state->compin << (8 - state->bitsout));
-            }
-            break;
-          case 2: case 4:
-            for ( ; state->sampleindex < state->rowsamples; ++state->sampleindex)
-            {
-              for ( ; state->compindex < state->components; )
-              {
-                ensure_output_bytes(O, 1);
-                if (state->bitsin < state->compbits)
-                {
-                  state->compin = (state->compin << 8) | row_byte(state);
-                  state->bitsin += 8;
-                  ++state->rowindex;
-                }
-                state->bitsin -= state->compbits;
-                c = state->compin >> state->bitsin;
-                state->compin &= (1 << state->bitsin) - 1;
-                d = tocomp(c - left_pixel_component(state));
-                save_pixel_component(state, c);
-                state->compout = (state->compout << state->compbits) | d;
-                state->bitsout += state->compbits;
-                if (state->bitsout >= 8)
-                {
-                  state->bitsout -= 8;
-                  iof_set(O, state->compout >> state->bitsout);
-                  state->compout &= (1 << state->bitsout) - 1;
-                }
-              }
-            }
-            if (state->bitsout > 0)
-            {
-              ensure_output_bytes(O, 1);
-              iof_set(O, state->compin << (8 - state->bitsout));
-            }
-            break;
-          case 8:
-            for ( ; state->rowindex < state->rowsize; ++state->rowindex)
-            {
-              ensure_output_bytes(O, 1);
-              c = row_byte(state);
-              d = tobyte(c - left_pixel_component(state));
-              save_pixel_component(state, c);
-              iof_set(O, d);
-            }
-            break;
-          case 16:
-            for ( ; state->rowindex < state->rowsize - 1; ++state->rowindex)
-            {
-              ensure_output_bytes(O, 2);
-              c = row_byte(state) << 8;
-              ++state->rowindex;
-              c |= row_byte(state);
-              d = tocomp(c - left_pixel_component(state));
-              save_pixel_component(state, c);
-              iof_set2(O, d >> 8, d & 0xff);
-            }
-            break;
-          default:
-            return IOFERR;
-        }
-        reset_tiff_row(state);
-        break;
-      case PNG_NONE_PREDICTOR:
-        for ( ; state->rowindex < state->rowsize; ++state->rowindex)
-        {
-          ensure_output_bytes(O, 1);
-          c = row_byte(state);
-          save_pixel_byte(state, c); // next row may need it
-          iof_set(O, c);
-        }
-        reset_png_row(state);
-        break;
-      case PNG_SUB_PREDICTOR:
-        for ( ; state->rowindex < state->rowsize; ++state->rowindex)
-        {
-          ensure_output_bytes(O, 1);
-          c = row_byte(state);
-          d = tobyte(c - left_pixel_byte(state));
-          save_pixel_byte(state, c);
-          iof_set(O, d);
-        }
-        reset_png_row(state);
-        break;
-      case PNG_OPTIMUM_PREDICTOR: // not worthy to perform optimization
-      case PNG_UP_PREDICTOR:
-        for ( ; state->rowindex < state->rowsize; ++state->rowindex)
-        {
-          ensure_output_bytes(O, 1);
-          c = row_byte(state);
-          d = tobyte(c - up_pixel_byte(state));
-          save_pixel_byte(state, c);
-          iof_set(O, d);
-        }
-        reset_png_row(state);
-        break;
-      case PNG_AVERAGE_PREDICTOR:
-        for ( ; state->rowindex < state->rowsize; ++state->rowindex)
-        {
-          ensure_output_bytes(O, 1);
-          c = row_byte(state);
-          d = tobyte(c - ((up_pixel_byte(state) + left_pixel_byte(state)) >> 1));
-          save_pixel_byte(state, c);
-          iof_set(O, d);
-        }
-        reset_png_row(state);
-        break;
-      case PNG_PAETH_PREDICTOR:
-        for ( ; state->rowindex < state->rowsize; ++state->rowindex)
-        {
-          ensure_output_bytes(O, 1);
-          c = row_byte(state);
-          d = tobyte(c - paeth(state));
-          save_pixel_byte(state, c);
-          iof_set(O, d);
-        }
-        reset_png_row(state);
-        break;
-      default:
-        return IOFERR;
-    }
-  }
-  return state->status == STATUS_LAST ? IOFERR : IOFEOF;
-}
-
-iof_status predictor_decode (iof *I, iof *O, int predictor, int rowsamples, int components, int compbits)
-{
-  predictor_state state;
-  int ret;
-  predictor_decoder_init(&state, predictor, rowsamples, components, compbits);
-  state.flush = 1;
-  ret = predictor_decode_state(I, O, &state);
-  predictor_decoder_close(&state);
-  return ret;
-}
-
-iof_status predictor_encode (iof *I, iof *O, int predictor, int rowsamples, int components, int compbits)
-{
-  predictor_state state;
-  int ret;
-  predictor_encoder_init(&state, predictor, rowsamples, components, compbits);
-  state.flush = 1;
-  ret = predictor_encode_state(I, O, &state);
-  predictor_encoder_close(&state);
-  return ret;
-}
-
-/* filters */
-
-// predictor decoder function
-
-static size_t predictor_decoder (iof *F, iof_mode mode)
-{
-  predictor_state *state;
-  iof_status status;
-  size_t tail;
-
-  state = iof_filter_state(predictor_state *, F);
-  switch(mode)
-  {
-    case IOFLOAD:
-    case IOFREAD:
-      if (F->flags & IOF_STOPPED)
-        return 0;
-      tail = iof_tail(F);
-      F->pos = F->buf + tail;
-      F->end = F->buf + F->space;
-      do {
-        status = predictor_decode_state(F->next, F, state);
-      } while (mode == IOFLOAD && status == IOFFULL && iof_resize_buffer(F));
-      return iof_decoder_retval(F, "predictor", status);
-    case IOFCLOSE:
-      predictor_decoder_close(state);
-      iof_free(F);
-      return 0;
-    default:
-      break;
-  }
-  return 0;
-}
-
-// predictor encoder function
-
-static size_t predictor_encoder (iof *F, iof_mode mode)
-{
-  predictor_state *state;
-  iof_status status;
-
-  state = iof_filter_state(predictor_state *, F);
-  switch (mode)
-  {
-    case IOFFLUSH:
-      state->flush = 1;
-      // fall through
-    case IOFWRITE:
-      F->end = F->pos;
-      F->pos = F->buf;
-      status = predictor_encode_state(F, F->next, state);
-      return iof_encoder_retval(F, "predictor", status);
-    case IOFCLOSE:
-      if (!state->flush)
-        predictor_encoder(F, IOFFLUSH);
-      predictor_encoder_close(state);
-      iof_free(F);
-      return 0;
-    default:
-      break;
-  }
-  return 0;
-}
-
-iof * iof_filter_predictor_decoder (iof *N, int predictor, int rowsamples, int components, int compbits)
-{
-  iof *I;
-  predictor_state *state;
-  I = iof_filter_reader(predictor_decoder, sizeof(predictor_state), &state);
-  iof_setup_next(I, N);
-  if (predictor_decoder_init(state, predictor, rowsamples, components, compbits) == NULL)
-  {
-    iof_discard(I);
-    return NULL;
-  }
-  state->flush = 1;
-  return I;
-}
-
-iof * iof_filter_predictor_encoder (iof *N, int predictor, int rowsamples, int components, int compbits)
-{
-  iof *O;
-  predictor_state *state;
-  O = iof_filter_writer(predictor_encoder, sizeof(predictor_state), &state);
-  iof_setup_next(O, N);
-  if (predictor_encoder_init(state, predictor, rowsamples, components, compbits) == NULL)
-  {
-    iof_discard(O);
-    return NULL;
-  }
-  return O;
-}

Deleted: trunk/Build/source/texk/web2c/luatexdir/luapplib/util/utiliof.c-OK
===================================================================
--- trunk/Build/source/texk/web2c/luatexdir/luapplib/util/utiliof.c-OK	2018-09-05 21:32:42 UTC (rev 48592)
+++ trunk/Build/source/texk/web2c/luatexdir/luapplib/util/utiliof.c-OK	2018-09-05 21:35:27 UTC (rev 48593)
@@ -1,2938 +0,0 @@
-/* input/iutput stream */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-
-#include "utilmem.h"
-#include "utillog.h"
-#include "utiliof.h"
-
-/* commons */
-
-void * iof_copy_data (const void *data, size_t size)
-{
-  return memcpy(util_malloc(size), data, size);
-}
-
-uint8_t * iof_copy_file_data (const char *filename, size_t *psize)
-{
-  FILE *file;
-  size_t size;
-  uint8_t *data;
-  if ((file = fopen(filename, "rb")) == NULL)
-    return NULL;
-  fseek(file, 0, SEEK_END);
-  size = (size_t)ftell(file);
-  data = (uint8_t *)util_malloc(size);
-  fseek(file, 0, SEEK_SET);
-  if ((*psize = fread(data, 1, size, file)) != size)
-  {
-    util_free(data);
-    data = NULL;
-  }
-  fclose(file);
-  return data;
-}
-
-uint8_t * iof_copy_file_handle_data (FILE *file, size_t *psize)
-{
-  size_t size;
-  uint8_t *data;
-  //long offset = ftell(file); // keep offset intact?
-  fseek(file, 0, SEEK_END);
-  size = (size_t)ftell(file);
-  data = (uint8_t *)util_malloc(size);
-  fseek(file, 0, SEEK_SET);
-  if ((*psize = fread(data, 1, size, file)) != size)
-  {
-    util_free(data);
-    data = NULL;
-  }
-  //fseek(file, offset, SEEK_SET)
-  return data;
-}
-
-FILE * iof_get_file (iof *F)
-{
-  if (F->flags & IOF_FILE)
-    return iof_file_get_file(F->iofile);
-  if (F->flags & IOF_FILE_HANDLE)
-    return F->file;
-  return NULL;
-}
-
-const char * iof_status_kind (iof_status status)
-{
-  switch (status)
-  {
-    case IOFEOF:
-      return "IOFEOF";
-    case IOFERR:
-      return "IOFERR";
-    case IOFEMPTY:
-      return "IOFEMPTY";
-    case IOFFULL:
-      return "IOFFULL";
-    default:
-      break;
-  }
-  return "(unknown)";
-}
-
-/* shared pseudofile */
-
-#define IOF_FILE_DEFAULTS 0
-
-iof_file * iof_file_new (FILE *file)
-{
-  iof_file *iofile = (iof_file *)util_malloc(sizeof(iof_file));
-  iof_file_set_fh(iofile, file);
-  iofile->offset = NULL;
-  iofile->size = 0;
-  iofile->name = NULL;
-  iofile->refcount = 0;
-  iofile->flags = IOF_FILE_DEFAULTS|IOF_ALLOC;
-  return iofile;
-}
-
-iof_file * iof_file_init (iof_file *iofile, FILE *file)
-{
-  iof_file_set_fh(iofile, file);
-  iofile->offset = NULL;
-  iofile->size = 0;
-  iofile->name = NULL;
-  iofile->refcount = 0;
-  iofile->flags = IOF_FILE_DEFAULTS;
-  return iofile;
-}
-
-iof_file * iof_file_rdata (const void *data, size_t size)
-{
-  iof_file *iofile = (iof_file *)util_malloc(sizeof(iof_file));
-  iofile->rbuf = iofile->rpos = (const uint8_t *)data;
-  iofile->rend = iofile->rbuf + size;
-  iofile->offset = NULL;
-  iofile->size = 0;
-  iofile->name = NULL;
-  iofile->refcount = 0;
-  iofile->flags = IOF_FILE_DEFAULTS|IOF_ALLOC|IOF_DATA;
-  return iofile;
-}
-
-iof_file * iof_file_rdata_init (iof_file *iofile, const void *data, size_t size)
-{
-  iofile->rbuf = iofile->rpos = (const uint8_t *)data;
-  iofile->rend = iofile->rbuf + size;
-  iofile->offset = NULL;
-  iofile->size = 0; // letse keep it consequently set to zero (only for user disposal)
-  iofile->name = NULL;
-  iofile->refcount = 0;
-  iofile->flags = IOF_FILE_DEFAULTS|IOF_DATA;
-  return iofile;
-}
-
-iof_file * iof_file_wdata (void *data, size_t size)
-{
-  return iof_file_rdata((const void *)data, size);
-}
-
-iof_file * iof_file_wdata_init (iof_file *iofile, void *data, size_t size)
-{
-  return iof_file_rdata_init(iofile, (const void *)data, size);
-}
-
-/* typical uses so far */
-
-iof_file * iof_file_reader_from_file_handle (iof_file *iofile, const char *filename, FILE *file, int preload, int closefile)
-{
-  uint8_t *data;
-  size_t size;
-
-  if (preload)
-  {
-    if ((data = iof_copy_file_handle_data(file, &size)) == NULL)
-    {
-      if (closefile)
-        fclose(file);
-      return NULL;
-    }
-    if (iofile == NULL)
-      iofile = iof_file_rdata(data, size);
-    else
-      iof_file_rdata_init(iofile, data, size);
-    iofile->flags |= IOF_BUFFER_ALLOC;
-    if (closefile)
-      fclose(file);
-  }
-  else
-  {
-    if (iofile == NULL)
-      iofile = iof_file_new(file);
-    else
-      iof_file_init(iofile, file);
-    if (closefile)
-      iofile->flags |= IOF_CLOSE_FILE;
-  }
-  if (filename != NULL)
-    iof_file_set_name(iofile, filename);
-  return iofile;
-}
-
-iof_file * iof_file_reader_from_file (iof_file *iofile, const char *filename, int preload)
-{
-  FILE *file;
-  if ((file = fopen(filename, "rb")) == NULL)
-    return NULL;
-  return iof_file_reader_from_file_handle(iofile, filename, file, preload, 1);
-}
-
-iof_file * iof_file_reader_from_data (iof_file *iofile, const void *data, size_t size, int preload, int freedata)
-{
-  void *newdata;
-  if (data == NULL)
-    return NULL;
-  if (preload)
-  {
-    newdata = iof_copy_data(data, size);
-    if (iofile == NULL)
-      iofile = iof_file_rdata(newdata, size);
-    else
-      iof_file_rdata_init(iofile, newdata, size);
-    iofile->flags |= IOF_BUFFER_ALLOC;
-    //if (freedata) // hardly makes sense...  we can't free const void *
-    //  util_free((void *)data);
-  }
-  else
-  {
-    if (iofile == NULL)
-      iofile = iof_file_rdata(data, size);
-    else
-      iof_file_rdata_init(iofile, data, size);
-    if (freedata)
-      iofile->flags |= IOF_BUFFER_ALLOC;
-  }
-  return iofile;
-}
-
-/*
-iof_file * iof_file_writer_from_file (iof_file *iofile, const char *filename)
-{
-  FILE *file;
-  if ((file = fopen(filename, "wb")) == NULL)
-    return NULL;
-  if (iofile == NULL)
-    iofile = iof_file_new(file);
-  else
-    iof_file_init(iofile, file);
-  iofile->flags |= IOF_CLOSE_FILE;
-  iof_file_set_name(iofile, filename);
-  return iofile;
-}
-*/
-
-/*
-Because of limited number of FILE* handles available, we may need to close contained handle
-between accessing it. In applications so far (fonts, images) we typically need the source
-to parse the file on creation and to rewrite or reload the data on dump. All iof_file api
-functions assume that iofile has FILE* opened. Reopening it on every access (ftell, fseek,
-read/write) makes no sense, as we would effectively loose control. If the caller invalidates
-iofile by closing and nulling its file handle, it is also responsible to reopen when necessary.
-*/
-
-int iof_file_close_input (iof_file *iofile)
-{
-  FILE *file;
-  if (iofile->flags & IOF_DATA)
-    return 0;
-  if ((file = iof_file_get_fh(iofile)) == NULL)
-    return 0;
-  fclose(file);
-  iof_file_set_fh(iofile, NULL);
-  iofile->flags &= ~IOF_RECLOSE_FILE;
-  iofile->flags |= IOF_REOPEN_FILE;
-  return 1;
-}
-
-int iof_file_reopen_input (iof_file *iofile)
-{ // returns true if iofile readable
-  FILE *file;
-  const char *filename;
-  if (iofile->flags & IOF_DATA)
-    return 1;
-  if ((file = iof_file_get_fh(iofile)) != NULL)
-    return 1; // if present, assumed readable
-  if ((filename = iofile->name) == NULL || (file = fopen(filename, "rb")) == NULL)
-    return 0;
-  iof_file_set_fh(iofile, file);
-  iofile->flags &= ~IOF_REOPEN_FILE;
-  iofile->flags |= IOF_RECLOSE_FILE;
-  return 1;
-}
-
-/* freeing iof_file */
-
-void iof_file_free (iof_file *iofile)
-{
-  FILE *file;
-  if (iofile->flags & IOF_DATA)
-  {
-    if (iofile->flags & IOF_BUFFER_ALLOC)
-    {
-      iofile->flags &= ~IOF_BUFFER_ALLOC;
-      if (iofile->buf != NULL)
-      {
-        util_free(iofile->buf);
-        iofile->buf = iofile->pos = iofile->end = NULL;
-      }
-    }
-  }
-  else if ((file = iof_file_get_fh(iofile)) != NULL)
-  {
-    if (iofile->flags & IOF_CLOSE_FILE)
-     	fclose(file);
-    iof_file_set_fh(iofile, NULL);
-  }
-  iof_file_set_name(iofile, NULL);
-  if (iofile->flags & IOF_ALLOC)
-    util_free(iofile);
-}
-
-/* set filename for reopen */
-
-void iof_file_set_name (iof_file *iofile, const char *name)
-{
-  if (iofile->name != NULL)
-    util_free(iofile->name);
-  if (name != NULL)
-    iofile->name = iof_copy_data(name, strlen(name) + 1);
-  else
-    iofile->name = NULL;
-}
-
-/* seek */
-
-int iof_file_seek (iof_file *iofile, long offset, int whence)
-{
-  if (iofile->flags & IOF_DATA)
-  {
-    switch (whence)
-    {
-      case SEEK_SET:
-        if (offset >= 0 && iofile->buf + offset <= iofile->end)
-        {
-          iofile->pos = iofile->buf + offset;
-          return 0;
-        }
-        return -1;
-      case SEEK_CUR:
-        if ((offset >= 0 && iofile->pos + offset <= iofile->end) || (offset < 0 && iofile->pos + offset >= iofile->buf))
-        {
-          iofile->pos += offset;
-          return 0;
-        }
-        return -1;
-      case SEEK_END:
-        if (offset <= 0 && iofile->end + offset >= iofile->buf)
-        {
-          iofile->pos = iofile->end + offset;
-          return 0;
-        }
-        return -1;
-    }
-    return -1;
-  }
-  return fseek(iof_file_get_fh(iofile), offset, whence);
-}
-
-/* */
-
-long iof_file_tell (iof_file *iofile)
-{
-  return (iofile->flags & IOF_DATA) ? (long)(iofile->pos - iofile->buf) : ftell(iof_file_get_fh(iofile));
-}
-
-size_t iof_file_size (iof_file *iofile)
-{ 
-  long pos, size;
-  FILE *file;
-  if (iofile->flags & IOF_DATA)
-    return (size_t)iof_space(iofile);
-  file = iof_file_get_fh(iofile);
-  pos = ftell(file);
-  fseek(file, 0, SEEK_END);
-  size = ftell(file);
-  fseek(file, pos, SEEK_SET);
-  return size;
-}
-
-int iof_file_eof (iof_file *iofile)
-{
-  if (iofile->flags & IOF_DATA)
-    return iofile->pos == iofile->end ? -1 : 0;
-  return feof(iof_file_get_fh(iofile));
-}
-
-int iof_file_flush (iof_file *iofile)
-{
-  if (iofile->flags & IOF_DATA)
-    return 0;
-  return fflush(iof_file_get_fh(iofile));
-}
-
-size_t iof_file_read (void *ptr, size_t size, size_t items, iof_file *iofile)
-{
-  if (iofile->flags & IOF_DATA)
-  {
-    size_t bytes = size * items;
-    if (bytes > (size_t)iof_left(iofile))
-      bytes = (size_t)iof_left(iofile);
-    memcpy(ptr, iofile->pos, bytes);
-    iofile->pos += bytes;
-    return bytes / size; // number of elements read
-  }
-  return fread(ptr, size, items, iof_file_get_fh(iofile));
-}
-
-static size_t iof_file_data_resizeto (iof_file *iofile, size_t space)
-{
-  uint8_t *newbuf;
-  size_t size;
-  size = iof_size(iofile);
-  if (iofile->flags & IOF_BUFFER_ALLOC)
-  {
-    newbuf = (uint8_t *)util_realloc(iofile->buf, space);
-  }
-  else
-  {
-    newbuf = (uint8_t *)util_malloc(space);
-    if (size > 0)
-      memcpy(newbuf, iofile->buf, size);
-    iofile->flags |= IOF_BUFFER_ALLOC;
-  }
-  iofile->buf = newbuf;
-  iofile->pos = newbuf + size;
-  iofile->end = newbuf + space;
-  return space - size;
-}
-
-#define iof_file_data_resize(iofile) iof_file_data_resizeto(iofile, iof_space(iofile) << 1)
-
-size_t iof_file_write (const void *ptr, size_t size, size_t items, iof_file *iofile)
-{
-  if (iofile->flags & IOF_DATA)
-  {
-    size_t space, sizesofar, bytes;
-    bytes = size * items;
-    if (bytes > (size_t)iof_left(iofile))
-    {      
-      if ((space = iof_space(iofile)) == 0) // allow iofile->buf/end initially NULL
-        space = BUFSIZ;
-      for (sizesofar = iof_size(iofile), space <<= 1; sizesofar + bytes > space; space <<= 1)
-        ;
-      if (iof_file_data_resizeto(iofile, space) == 0)
-        return 0;
-    }
-    memcpy(iofile->pos, ptr, bytes);
-    iofile->pos += bytes;
-    return bytes / size;
-  }
-  return fwrite(ptr, size, items, iof_file_get_fh(iofile));
-}
-
-size_t iof_file_ensure (iof_file *iofile, size_t bytes)
-{
-  if (iofile->flags & IOF_DATA)
-  {
-    size_t space, sizesofar, left;
-    left = (size_t)iof_left(iofile);
-    if (bytes > left)
-    {      
-      if ((space = iof_space(iofile)) == 0) // allow iofile->buf/end initially NULL
-        space = BUFSIZ;
-      for (sizesofar = iof_size(iofile), space <<= 1; sizesofar + bytes > space; space <<= 1);
-      return iof_file_data_resizeto(iofile, space);
-    }
-    return left;  
-  }
-  return 0;
-}
-
-int iof_file_getc (iof_file *iofile)
-{
-  if (iofile->flags & IOF_DATA)
-    return iofile->pos < iofile->end ? *iofile->pos++ : IOFEOF;
-  return fgetc(iof_file_get_fh(iofile));
-}
-
-int iof_file_putc (iof_file *iofile, int c)
-{
-  if (iofile->flags & IOF_DATA)
-  {
-    if (iofile->pos >= iofile->end)
-      if (iof_file_data_resize(iofile) == 0)
-        return IOFEOF;
-    *iofile->pos++ = (uint8_t)c;
-    return c;
-  }
-  return fputc(c, iof_file_get_fh(iofile));
-}
-
-static int iof_file_sync (iof_file *iofile, size_t *offset)
-{
-  if (iofile->offset != offset)
-  {
-    if (iofile->offset != NULL)
-      *iofile->offset = iof_file_tell(iofile);
-    iofile->offset = offset;
-    if (offset) // let offset be NULL
-      return iof_file_seek(iofile, (long)*offset, SEEK_SET);
-  }
-  return 0;
-}
-
-//#define iof_file_unsync(iofile, poffset) (void)((iofile)->offset == poffset && (((iofile)->offset = NULL), 0))
-#define iof_file_unsync(iofile, poffset) ((void)poffset, (iofile)->offset = NULL)
-
-/* iof seek */
-
-#define iof_reader_reset(I) ((I)->pos = (I)->end = (I)->buf)
-#define iof_reader_reseek_file(I, offset, whence) (fseek((I)->file, offset, whence) == 0 ? (iof_reader_reset(I), 0) : -1)
-#define iof_reader_reseek_iofile(I, offset, whence) (iof_file_seek((I)->iofile, offset, whence) == 0 ? (iof_reader_reset(I), 0) : -1)
-
-#define iof_writer_reset(O) ((O)->pos = (O)->buf)
-#define iof_writer_reseek_file(O, offset, whence) (iof_flush(O), (fseek((O)->file, offset, whence) == 0 ? (iof_writer_reset(O), 0) : -1))
-#define iof_writer_reseek_iofile(O, offset, whence) (iof_flush(O), (iof_file_seek((O)->iofile, offset, whence) == 0 ? (iof_writer_reset(O), 0) : -1))
-
-static int iof_reader_seek_data (iof *I, long offset, int whence)
-{
-  switch (whence)
-  {
-    case SEEK_SET:
-      if (offset >= 0 && I->buf + offset <= I->end)
-      {
-        I->pos = I->buf + offset;
-        return 0;
-      }
-      return -1;
-    case SEEK_CUR:
-      if ((offset >= 0 && I->pos + offset <= I->end) || (offset < 0 && I->pos + offset >= I->buf))
-      {
-        I->pos += offset;
-        return 0;
-      }
-      return -1;
-    case SEEK_END:
-      if (offset <= 0 && I->end + offset >= I->buf)
-      {
-        I->pos = I->end + offset;
-        return 0;
-      }
-      return -1;
-  }
-  return -1;
-}
-
-static int iof_reader_seek_iofile (iof *I, long offset, int whence)
-{
-  long fileoffset;
-  switch (whence)
-  {
-    case SEEK_SET:
-      fileoffset = iof_file_tell(I->iofile);
-      if (offset <= fileoffset && offset >= fileoffset - iof_space(I))
-      {
-        I->pos = I->end - (fileoffset - offset);
-        return 0;
-      }
-      return iof_reader_reseek_iofile(I, offset, SEEK_SET);
-    case SEEK_CUR:
-      if ((offset >= 0 && I->pos + offset <= I->end) || (offset < 0 && I->pos + offset >= I->buf))
-      {
-        I->pos += offset;
-        return 0;
-      }
-      return iof_reader_reseek_iofile(I, offset, SEEK_CUR);
-    case SEEK_END:
-      return iof_reader_reseek_iofile(I, offset, SEEK_END); // can we do better?
-  }
-  return -1;
-}
-
-static int iof_reader_seek_file (iof *I, long offset, int whence)
-{
-  long fileoffset;
-  switch (whence)
-  {
-    case SEEK_SET:
-      fileoffset = ftell(I->file);
-      if (offset <= fileoffset && offset >= fileoffset - iof_space(I))
-      {
-        I->pos = I->end - (fileoffset - offset);
-        return 0;
-      }
-      return iof_reader_reseek_file(I, offset, SEEK_SET);
-    case SEEK_CUR:
-      if ((offset >= 0 && I->pos + offset <= I->end) || (offset < 0 && I->pos + offset >= I->buf))
-      {
-        I->pos += offset;
-        return 0;
-      }
-      return iof_reader_reseek_file(I, offset, SEEK_CUR);
-    case SEEK_END:
-      return iof_reader_reseek_file(I, offset, SEEK_END); // can we do better?
-  }
-  return -1;
-}
-
-int iof_reader_seek (iof *I, long offset, int whence)
-{
-  I->flags &= ~IOF_STOPPED;
-  if (I->flags & IOF_FILE)
-    return iof_reader_seek_iofile(I, offset, whence);
-  if (I->flags & IOF_FILE_HANDLE)
-    return iof_reader_seek_file(I, offset, whence);
-  if (I->flags & IOF_DATA)
-    return iof_reader_seek_data(I, offset, whence);
-  return -1;
-}
-
-int iof_reader_reseek (iof *I, long offset, int whence)
-{
-  I->flags &= ~IOF_STOPPED;
-  if (I->flags & IOF_FILE)
-    return iof_reader_reseek_iofile(I, offset, whence);
-  if (I->flags & IOF_FILE_HANDLE)
-    return iof_reader_reseek_file(I, offset, whence);
-  if (I->flags & IOF_DATA)
-    return iof_reader_seek_data(I, offset, whence);
-  return -1;
-}
-
-static int iof_writer_seek_data (iof *O, long offset, int whence)
-{
-  /*
-  fseek() allows to seek after the end of file. Seeking does not increase the output file.
-  No byte is written before fwirte(). It seems to fill the gap with zeros. Until we really need that,
-  no seeking out of bounds for writers.
-  */
-  O->flags &= ~IOF_STOPPED;
-  return iof_reader_seek_data(O, offset, whence);
-}
-
-static int iof_writer_seek_iofile (iof *O, long offset, int whence)
-{
-  long fileoffset;
-  switch (whence)
-  {
-    case SEEK_SET:
-      fileoffset = iof_file_tell(O->iofile);
-      if (offset >= fileoffset && offset <= fileoffset + iof_space(O))
-      {
-        O->pos = O->buf + (offset - fileoffset);
-        return 0;
-      }
-      return iof_writer_reseek_iofile(O, offset, SEEK_SET);
-    case SEEK_CUR:
-      if ((offset >=0 && O->pos + offset <= O->end) || (offset < 0 && O->pos + offset >= O->buf))
-      {
-        O->pos += offset;
-        return 0;
-      }
-      return iof_writer_reseek_iofile(O, offset, SEEK_CUR);
-    case SEEK_END:
-      return iof_writer_reseek_iofile(O, offset, SEEK_END);
-  }
-  return -1;
-}
-
-static int iof_writer_seek_file (iof *O, long offset, int whence)
-{
-  long fileoffset;
-  switch (whence)
-  {
-    case SEEK_SET:
-      fileoffset = ftell(O->file);
-      if (offset >= fileoffset && offset <= fileoffset + iof_space(O))
-      {
-        O->pos = O->buf + (offset - fileoffset);
-        return 0;
-      }
-      return iof_writer_reseek_file(O, offset, SEEK_SET);
-    case SEEK_CUR:
-      if ((offset >=0 && O->pos + offset <= O->end) || (offset < 0 && O->pos + offset >= O->buf))
-      {
-        O->pos += offset;
-        return 0;
-      }
-      return iof_writer_reseek_file(O, offset, SEEK_CUR);
-    case SEEK_END:
-      return iof_writer_reseek_file(O, offset, SEEK_END);
-  }
-  return -1;
-}
-
-int iof_writer_seek (iof *I, long offset, int whence)
-{
-  I->flags &= ~IOF_STOPPED;
-  if (I->flags & IOF_FILE)
-    return iof_writer_seek_iofile(I, offset, whence);
-  if (I->flags & IOF_FILE_HANDLE)
-    return iof_writer_seek_file(I, offset, whence);
-  if (I->flags & IOF_DATA)
-    return iof_writer_seek_data(I, offset, whence);
-  return -1;
-}
-
-int iof_writer_reseek (iof *I, long offset, int whence)
-{
-  I->flags &= ~IOF_STOPPED;
-  if (I->flags & IOF_FILE)
-    return iof_writer_reseek_iofile(I, offset, whence);
-  if (I->flags & IOF_FILE_HANDLE)
-    return iof_writer_reseek_file(I, offset, whence);
-  if (I->flags & IOF_DATA)
-    return iof_writer_seek_data(I, offset, whence);
-  return -1;
-}
-
-int iof_seek (iof *F, long offset, int whence)
-{
-  return (F->flags & IOF_WRITER) ? iof_writer_seek(F, offset, whence) : iof_reader_seek(F, offset, whence);
-}
-
-int iof_reseek (iof *F, long offset, int whence)
-{
-  return (F->flags & IOF_WRITER) ? iof_writer_reseek(F, offset, whence) : iof_reader_reseek(F, offset, whence);
-}
-
-/* tell */
-
-long iof_reader_tell (iof *I)
-{
-  if (I->flags & IOF_FILE)
-    return iof_file_tell(I->iofile) - (long)iof_left(I);
-  if (I->flags & IOF_FILE_HANDLE)
-    return ftell(I->file) - (long)iof_left(I);
-  //if (I->flags & IOF_DATA)
-  return (long)iof_size(I);
-}
-
-long iof_writer_tell (iof *O)
-{
-  if (O->flags & IOF_FILE)
-    return iof_file_tell(O->iofile) + (long)iof_size(O);
-  if (O->flags & IOF_FILE_HANDLE)
-    return ftell(O->file) + (long)iof_size(O);
-  //if (I->flags & IOF_DATA)
-  return (long)iof_size(O);
-}
-
-long iof_tell (iof *I)
-{
-  return (I->flags & IOF_WRITER) ? iof_writer_tell(I) : iof_reader_tell(I);
-}
-
-size_t iof_fsize (iof *I)
-{
-  size_t pos, size;
-  if (I->flags & IOF_FILE)
-    return iof_file_size(I->iofile);
-  if (I->flags & IOF_FILE_HANDLE)
-  {
-    pos = (size_t)ftell(I->file);
-    fseek(I->file, 0, SEEK_END);
-    size = (size_t)ftell(I->file);
-    fseek(I->file, (long)pos, SEEK_SET);
-    return size;
-  }
-  //if (I->flags & IOF_DATA)
-  return (size_t)iof_space(I);
-}
-
-/* save reader tail */
-
-size_t iof_save_tail (iof *I)
-{
-  size_t size, left;
-  size = iof_size(I);
-  left = iof_left(I);
-  if (size >= left)
-    memcpy(I->buf, I->pos, left);
-  else
-    memmove(I->buf, I->pos, left);
-  return left;
-}
-
-size_t iof_input_save_tail (iof *I, size_t back)
-{
-  size_t size;
-  I->flags |= IOF_TAIL;
-  I->pos -= back;
-  size = iof_input(I);
-  I->pos += back;
-  I->flags &= ~IOF_TAIL;
-  return size; // + back - back
-}
-
-/* read from file */
-
-/* iof free*/
-
-static size_t file_read (iof *I);
-static size_t file_load (iof *I);
-
-static size_t file_reader (iof *I, iof_mode mode)
-{
-  switch (mode)
-  {
-    case IOFREAD:
-      return file_read(I);
-    case IOFLOAD:
-      return file_load(I);
-    case IOFCLOSE:
-      iof_free(I);
-      return 0;
-    default:
-      return 0;
-  }
-}
-
-iof * iof_setup_file_handle_reader (iof *I, void *buffer, size_t space, FILE *f)
-{
-  if (I == NULL)
-    iof_setup_reader(I, buffer, space);
-  else
-    iof_reader_buffer(I, buffer, space);
-  iof_setup_file(I, f);
-  I->more = file_reader;
-  return I;
-}
-
-iof * iof_setup_file_reader (iof *I, void *buffer, size_t space, const char *filename)
-{
-  FILE *f;
-  if ((f = fopen(filename, "rb")) == NULL)
-    return NULL;
-  if (I == NULL)
-    iof_setup_reader(I, buffer, space);
-  else
-    iof_reader_buffer(I, buffer, space);
-  iof_setup_file(I, f);
-  I->flags |= IOF_CLOSE_FILE;
-  I->more = file_reader;
-  return I;
-}
-
-/* write to file */
-
-static size_t file_write (iof *O, int flush);
-
-static size_t file_writer (iof *O, iof_mode mode)
-{
-  switch (mode)
-  {
-    case IOFWRITE:
-      return file_write(O, 0);
-    case IOFFLUSH:
-      return file_write(O, 1);
-    case IOFCLOSE:
-      file_write(O, 1);
-      iof_free(O);
-      return 0;
-    default:
-      return 0;
-  }
-}
-
-iof * iof_setup_file_handle_writer (iof *O, void *buffer, size_t space, FILE *f)
-{
-  if (O == NULL)
-    iof_setup_writer(O, buffer, space);
-  else
-    iof_writer_buffer(O, buffer, space);
-  iof_setup_file(O, f);
-  O->more = file_writer;
-  return O;
-}
-
-iof * iof_setup_file_writer (iof *O, void *buffer, size_t space, const char *filename)
-{
-  FILE *f;
-  if ((f = fopen(filename, "wb")) == NULL)
-    return NULL;
-  if (O == NULL)
-    iof_setup_writer(O, buffer, space);
-  else
-    iof_writer_buffer(O, buffer, space);
-  iof_setup_file(O, f);
-  O->flags |= IOF_CLOSE_FILE;
-  O->more = file_writer;
-  return O;
-}
-
-/* a dedicated handler for stdout/stderr */
-
-static size_t stdout_writer (iof *O, iof_mode mode)
-{
-  switch(mode)
-  {
-    case IOFWRITE:
-    {
-      fwrite(O->buf, sizeof(uint8_t), iof_size(O), stdout);
-      O->pos = O->buf;
-      return O->space;
-    }
-    case IOFCLOSE:
-    case IOFFLUSH:
-    {
-      fwrite(O->buf, sizeof(uint8_t), iof_size(O), stdout);
-      fflush(stdout);
-      O->pos = O->buf;
-      return 0;
-    }
-    default:
-      break;
-  }
-  return 0;
-}
-
-static size_t stderr_writer (iof *O, iof_mode mode)
-{
-  switch(mode)
-  {
-    case IOFWRITE:
-    {
-      fwrite(O->buf, sizeof(uint8_t), iof_size(O), stderr);
-      O->pos = O->buf;
-      return O->space;
-    }
-    case IOFCLOSE:
-    case IOFFLUSH:
-    {
-      fwrite(O->buf, sizeof(uint8_t), iof_size(O), stderr);
-      fflush(stderr);
-      O->pos = O->buf;
-      return 0;
-    }
-    default:
-      break;
-  }
-  return 0;
-}
-
-static uint8_t iof_stdout_buffer[BUFSIZ];
-iof iof_stdout = IOF_WRITER_STRUCT(stdout_writer, NULL, iof_stdout_buffer, BUFSIZ, 0);
-
-static uint8_t iof_stderr_buffer[BUFSIZ];
-iof iof_stderr = IOF_WRITER_STRUCT(stderr_writer, NULL, iof_stderr_buffer, BUFSIZ, 0);
-
-/* read from somewhere */
-
-iof * iof_reader (iof *I, void *link, iof_handler reader, const void *m, size_t bytes)
-{
-  I->space = 0;
-  I->link = link;
-  I->more = reader;
-  I->flags = 0;
-  I->refcount = 0;
-  if (m != NULL)
-  {
-    I->rbuf = I->rpos = (const uint8_t *)m;
-    I->rend = (const uint8_t *)m + bytes;
-    return I;
-  }
-  return NULL;
-}
-
-iof * iof_string_reader (iof *I, const void *s, size_t bytes)
-{
-  I->space = 0;
-  I->link = NULL;
-  I->more = NULL;
-  I->flags = 0; // iof_string() sets IOF_DATA
-  I->refcount = 0;
-  if (s != NULL)
-    return iof_string(I, s, bytes);
-  return NULL;
-}
-
-/* write somewhere */
-
-iof * iof_writer (iof *O, void *link, iof_handler writer, void *m, size_t bytes)
-{
-  O->space = 0;
-  O->link = link;
-  O->more = writer;
-  O->flags = 0;
-  O->refcount = 0;
-  if (m != NULL && bytes > 0)
-  {
-    O->buf = O->pos = (uint8_t *)m;
-    O->end = (uint8_t *)m + bytes;
-    return O;
-  }
-  // return iof_null(O);
-  return NULL;
-}
-
-/* write to growing bytes buffer */
-
-static size_t iof_mem_handler (iof *O, iof_mode mode)
-{
-  switch(mode)
-  {
-    case IOFWRITE:
-      return iof_resize_buffer(O);
-    case IOFCLOSE:
-      iof_free(O);
-      return 0;
-    default:
-      return 0;
-  }
-}
-
-iof * iof_setup_buffer (iof *O, void *buffer, size_t space)
-{
-  if (O == NULL)
-    iof_setup_writer(O, buffer, space);
-  else
-    iof_writer_buffer(O, buffer, space);
-  O->link = NULL;
-  O->flags |= IOF_DATA;
-  O->more = iof_mem_handler;
-  return O;
-}
-
-iof * iof_setup_buffermin (iof *O, void *buffer, size_t space, size_t min)
-{
-  if ((O = iof_setup_buffer(O, buffer, space)) != NULL && space < min) // just allocate min now to avoid further rewriting
-  {
-    O->buf = O->pos = (uint8_t *)util_malloc(min);
-    O->flags |= IOF_BUFFER_ALLOC;
-    O->end = O->buf + min;
-  }
-  return O;
-}
-
-iof * iof_buffer_create (size_t space)
-{
-  uint8_t *buffer;
-  iof *O;
-  space += sizeof(iof);
-  buffer = util_malloc(space);
-  if ((O = iof_setup_buffer(NULL, buffer, space)) != NULL)
-    O->flags |= IOF_ALLOC;
-  return O;
-}
-
-/* set/get */
-
-int iof_getc (iof *I)
-{
-  if (iof_readable(I))
-    return *I->pos++;
-  return IOFEOF;
-}
-
-int iof_putc (iof *O, int u)
-{
-  if (iof_writable(O))
-  {
-    iof_set(O, u);
-    return (uint8_t)u;
-  }
-  return IOFFULL;
-}
-
-size_t iof_skip (iof *I, size_t bytes)
-{
-  while (bytes)
-  {
-    if (iof_readable(I))
-      ++I->pos;
-    else
-      break;
-    --bytes;
-  }
-  return bytes;
-}
-
-/* from iof to iof */
-
-iof_status iof_pass (iof *I, iof *O)
-{
-  size_t leftin, leftout;
-  if ((leftin = iof_left(I)) == 0)
-    leftin = iof_input(I);
-  while (leftin)
-  {
-    if ((leftout = iof_left(O)) == 0)
-      if ((leftout = iof_output(O)) == 0)
-        return IOFFULL;
-    while (leftin > leftout)
-    {
-      memcpy(O->pos, I->pos, leftout);
-      I->pos += leftout;
-      O->pos = O->end; /* eq. += leftout */
-      leftin -= leftout;
-      if ((leftout = iof_output(O)) == 0)
-        return IOFFULL;
-    }
-    if (leftin)
-    {
-      memcpy(O->pos, I->pos, leftin);
-      I->pos = I->end; /* eq. += leftin */
-      O->pos += leftin;
-    }
-    leftin = iof_input(I);
-  }
-  return IOFEOF;
-}
-
-/* read n-bytes */
-
-size_t iof_read (iof *I, void *to, size_t size)
-{
-  size_t leftin, done = 0;
-  char *s = (char *)to;
-  
-  if ((leftin = iof_left(I)) == 0)
-    if ((leftin = iof_input(I)) == 0)
-      return done;
-  while (size > leftin)
-  {
-    memcpy(s, I->pos, leftin * sizeof(uint8_t));
-    size -= leftin;
-    done += leftin;
-    s += leftin;
-    I->pos = I->end;
-    if ((leftin = iof_input(I)) == 0)
-      return done;
-  }
-  if (size)
-  {
-    memcpy(s, I->pos, size * sizeof(uint8_t));
-    I->pos += size;
-    done += size;
-  }
-  return done;
-}
-
-/* rewrite FILE content (use fseek if needed) */
-
-size_t iof_write_file_handle (iof *O, FILE *file)
-{
-  size_t leftout, size, readout;
-  if ((leftout = iof_left(O)) == 0)
-    if ((leftout = iof_output(O)) == 0)
-      return 0;
-  size = 0;
-  do {
-    readout = fread(O->pos, 1, leftout, file);    
-    O->pos += readout;
-    size += readout;
-  } while(readout == leftout && (leftout = iof_output(O)) > 0);
-  return size;
-}
-
-size_t iof_write_file (iof *O, const char *filename)
-{
-  FILE *file;
-  size_t size;
-  if ((file = fopen(filename, "rb")) == NULL)
-    return 0;
-  size = iof_write_file_handle(O, file);
-  fclose(file);
-  return size;
-}
-
-size_t iof_write_iofile (iof *O, iof_file *iofile, int savepos)
-{
-  long offset;
-  size_t size;
-  FILE *file;
-  if (iofile->flags & IOF_DATA)
-    return iof_write(O, iofile->pos, (size_t)(iofile->end - iofile->pos));
-  file = iof_file_get_fh(iofile);
-  if (savepos)
-  {
-    offset = ftell(file);  
-    size = iof_write_file_handle(O, file);
-    fseek(file, offset, SEEK_SET);
-    return size;
-  }
-  return iof_write_file_handle(O, file);
-}
-
-/* write n-bytes */
-
-size_t iof_write (iof *O, const void *data, size_t size)
-{
-  size_t leftout, done = 0;
-  const char *s = (const char *)data;
-  if ((leftout = iof_left(O)) == 0)
-    if ((leftout = iof_output(O)) == 0)
-      return done;
-  while (size > leftout)
-  {
-    memcpy(O->pos, s, leftout * sizeof(uint8_t));
-    size -= leftout;
-    done += leftout;
-    s += leftout;
-    O->pos = O->end;
-    if ((leftout = iof_output(O)) == 0)
-      return done;
-  }
-  if (size)
-  {
-    memcpy(O->pos, s, size * sizeof(uint8_t));
-    O->pos += size;
-    done += size;
-  }
-  return done;
-}
-
-/* write '\0'-terminated string */
-
-iof_status iof_puts (iof *O, const void *data)
-{
-  const char *s = (const char *)data;
-  while (*s)
-  {
-    if (iof_writable(O))
-      iof_set(O, *s++);
-    else
-      return IOFFULL;
-  }
-  return IOFEOF; // ?
-}
-
-size_t iof_put_string (iof *O, const void *data)
-{
-  const char *p, *s = (const char *)data;
-  for (p = s; *p != '\0' && iof_writable(O); iof_set(O, *p++));
-  return p - s;
-}
-
-/* write byte n-times */
-
-/*
-iof_status iof_repc (iof *O, char c, size_t bytes)
-{
-  while (bytes)
-  {
-    if (iof_writable(O))
-      iof_set(O, c);
-    else
-      return IOFFULL;
-    --bytes;
-  }
-  return IOFEOF; // ?
-}
-*/
-
-size_t iof_repc (iof *O, char c, size_t bytes)
-{
-  size_t leftout, todo = bytes;
-  if ((leftout = iof_left(O)) == 0)
-    if ((leftout = iof_output(O)) == 0)
-      return 0;
-  while (bytes > leftout)
-  {
-    memset(O->pos, c, leftout);
-    bytes -= leftout;
-    O->pos = O->end;
-    if ((leftout = iof_output(O)) == 0)
-      return todo - bytes;
-  }
-  if (bytes)
-  {
-    memset(O->pos, c, bytes);
-    O->pos += bytes;
-  }
-  return todo;
-}
-
-/* putfs */
-
-#define IOF_FMT_SIZE 1024
-
-size_t iof_putfs (iof *O, const char *format, ...)
-{
-  static char buffer[IOF_FMT_SIZE];
-  va_list args;
-  va_start(args, format);
-  if (vsnprintf(buffer, IOF_FMT_SIZE, format, args) > 0)
-  {
-    va_end(args);
-    return iof_put_string(O, buffer);
-  }
-  else
-  {
-    va_end(args);
-    return iof_write(O, buffer, IOF_FMT_SIZE);
-  }
-}
-
-/* integer from iof; return 1 on success, 0 otherwise */
-
-int iof_get_int32 (iof *I, int32_t *number)
-{
-  int sign, c = iof_char(I);
-  iof_scan_sign(I, c, sign);
-  if (!base10_digit(c)) return 0;
-  iof_read_integer(I, c, *number);
-  if (sign) *number = -*number;
-  return 1;
-}
-
-int iof_get_intlw (iof *I, intlw_t *number)
-{
-  int sign, c = iof_char(I);
-  iof_scan_sign(I, c, sign);
-  if (!base10_digit(c)) return 0;
-  iof_read_integer(I, c, *number);
-  if (sign) *number = -*number;
-  return 1;
-}
-
-int iof_get_int64 (iof *I, int64_t *number)
-{
-  int sign, c = iof_char(I);
-  iof_scan_sign(I, c, sign);
-  if (!base10_digit(c)) return 0;
-  iof_read_integer(I, c, *number);
-  if (sign) *number = -*number;
-  return 1;
-}
-
-int iof_get_uint32 (iof *I, uint32_t *number)
-{
-  int c = iof_char(I);
-  if (!base10_digit(c)) return 0;
-  iof_read_integer(I, c, *number);
-  return 1;
-}
-
-int iof_get_uintlw (iof *I, uintlw_t *number)
-{
-  int c = iof_char(I);
-  if (!base10_digit(c)) return 0;
-  iof_read_integer(I, c, *number);
-  return 1;
-}
-
-int iof_get_uint64 (iof *I, uint64_t *number)
-{
-  int c = iof_char(I);
-  if (!base10_digit(c)) return 0;
-  iof_read_integer(I, c, *number);
-  return 1;
-}
-
-int iof_get_int32_radix (iof *I, int32_t *number, int radix)
-{
-  int sign, c = iof_char(I);
-  iof_scan_sign(I, c, sign);
-  if (!base10_digit(c)) return 0;
-  iof_read_radix(I, c, *number, radix);
-  if (sign) *number = -*number;
-  return 1;
-
-}
-
-int iof_get_intlw_radix (iof *I, intlw_t *number, int radix)
-{
-  int sign, c = iof_char(I);
-  iof_scan_sign(I, c, sign);
-  if (!base10_digit(c)) return 0;
-  iof_read_radix(I, c, *number, radix);
-  if (sign) *number = -*number;
-  return 1;
-}
-
-int iof_get_int64_radix (iof *I, int64_t *number, int radix)
-{
-  int sign, c = iof_char(I);
-  iof_scan_sign(I, c, sign);
-  if (!base10_digit(c)) return 0;
-  iof_read_radix(I, c, *number, radix);
-  if (sign) *number = -*number;
-  return 1;
-}
-
-int iof_get_uint32_radix (iof *I, uint32_t *number, int radix)
-{
-  int c = iof_char(I);
-  if (!base10_digit(c)) return 0;
-  iof_read_radix(I, c, *number, radix);
-  return 1;
-}
-
-int iof_get_uintlw_radix (iof *I, uintlw_t *number, int radix)
-{
-  int c = iof_char(I);
-  if (!base10_digit(c)) return 0;
-  iof_read_radix(I, c, *number, radix);
-  return 1;
-}
-
-int iof_get_uint64_radix (iof *I, uint64_t *number, int radix)
-{
-  int c = iof_char(I);
-  if (!base10_digit(c)) return 0;
-  iof_read_radix(I, c, *number, radix);
-  return 1;
-}
-
-/* get roman to uint16_t, cf. roman_to_uint16() from utilnumber.c*/
-
-/* todo: some trick in place of this macro horror? */
-
-#define roman1000(c) (c == 'M' || c == 'm')
-#define roman500(c)  (c == 'D' || c == 'd')
-#define roman100(c)  (c == 'C' || c == 'c')
-#define roman50(c)   (c == 'L' || c == 'l')
-#define roman10(c)   (c == 'X' || c == 'x')
-#define roman5(c)    (c == 'V' || c == 'v')
-#define roman1(c)    (c == 'I' || c == 'i')
-
-#define roman100s(I, c) \
-  (roman100(c) ? (100 + ((c = iof_next(I), roman100(c)) ? (100 + ((c = iof_next(I), roman100(c)) ? (c = iof_next(I), 100) : 0)) : 0)) : 0)
-#define roman10s(I, c) \
-  (roman10(c) ? (10 + ((c = iof_next(I), roman10(c)) ? (10 + ((c = iof_next(I), roman10(c)) ? (c = iof_next(I), 10) : 0)) : 0)) : 0)
-#define roman1s(I, c) \
-  (roman1(c) ? (1 + ((c = iof_next(I), roman1(c)) ? (1 + ((c = iof_next(I), roman1(c)) ? (c = iof_next(I), 1) : 0)) : 0)) : 0)
-
-int iof_get_roman (iof *I, uint16_t *number)
-{
-  int c;
-  /* M */
-  for (*number = 0, c = iof_char(I); roman1000(c); *number += 1000, c = iof_next(I));
-  /* D C */
-  if (roman500(c))
-  {
-    c = iof_next(I);
-    *number += 500 + roman100s(I, c);
-  }
-  else if (roman100(c))
-  {
-    c = iof_next(I);
-    if (roman1000(c))
-    {
-      c = iof_next(I);
-      *number += 900;
-    }
-    else if (roman500(c))
-    {
-      c = iof_next(I);
-      *number += 400;
-    }
-    else
-      *number += 100 + roman100s(I, c);
-  }
-  /* L X */
-  if (roman50(c))
-  {
-    c = iof_next(I);
-    *number += 50 + roman10s(I, c);
-  }
-  else if (roman10(c))
-  {
-    c = iof_next(I);
-    if (roman100(c))
-    {
-      c = iof_next(I);
-      *number += 90;
-    }
-    else if (roman50(c))
-    {
-      c = iof_next(I);
-      *number += 40;
-    }
-    else
-      *number += 10 + roman10s(I, c);
-  }
-  /* V I */
-  if (roman5(c))
-  {
-    c = iof_next(I);
-    *number += 5 + roman1s(I, c);
-  }
-  else if (roman1(c))
-  {
-    c = iof_next(I);
-    if (roman10(c))
-    {
-      c = iof_next(I);
-      *number += 9;
-    }
-    else if (roman5(c))
-    {
-      c = iof_next(I);
-      *number += 4;
-    }
-    else
-      *number += 1 + roman1s(I, c);
-  }
-  return 1;
-}
-
-/* double from iof; return 1 on success */
-
-int iof_get_double (iof *I, double *number) // cf. string_to_double()
-{
-  int sign, exponent10, c = iof_char(I);
-  iof_scan_sign(I, c, sign);
-  iof_scan_decimal(I, c, *number);
-  if (c == '.')
-  {
-    c = iof_next(I);
-    iof_scan_fraction(I, c, *number, exponent10);
-  }
-  else
-    exponent10 = 0;
-  if (c == 'e' || c == 'E')
-  {
-    c = iof_next(I);
-    iof_scan_exponent10(I, c, exponent10);
-  }
-  double_exp10(*number, exponent10);
-  if (sign) *number = -*number;
-  return 1;
-}
-
-int iof_get_float (iof *I, float *number) // cf. string_to_float() in utilnumber.c
-{
-  int sign, exponent10, c = iof_char(I);
-  iof_scan_sign(I, c, sign);
-  iof_scan_decimal(I, c, *number);
-  if (c == '.')
-  {
-    c = iof_next(I);
-    iof_scan_fraction(I, c, *number, exponent10);
-  }
-  else
-    exponent10 = 0;
-  if (c == 'e' || c == 'E')
-  {
-    c = iof_next(I);
-    iof_scan_exponent10(I, c, exponent10);
-  }
-  float_exp10(*number, exponent10);
-  if (sign) *number = -*number;
-  return 1;
-}
-
-int iof_conv_double (iof *I, double *number) // cf. convert_to_double() in utilnumber.c
-{
-  int sign, exponent10, c = iof_char(I);
-  iof_scan_sign(I, c, sign);
-  iof_scan_decimal(I, c, *number);
-  if (c == '.' || c == ',')
-  {
-    c = iof_next(I);
-    iof_scan_fraction(I, c, *number, exponent10);
-    if (exponent10 < 0)
-      double_negative_exp10(*number, exponent10);
-  }
-  if (sign) *number = -*number;
-  return 1;
-}
-
-int iof_conv_float (iof *I, float *number) // cf. convert_to_float()
-{
-  int sign, exponent10, c = iof_char(I);
-  iof_scan_sign(I, c, sign);
-  iof_scan_decimal(I, c, *number);
-  if (c == '.' || c == ',')
-  {
-    c = iof_next(I);
-    iof_scan_fraction(I, c, *number, exponent10);
-    if (exponent10 < 0)
-      float_negative_exp10(*number, exponent10);
-  }
-  if (sign) *number = -*number;
-  return 1;
-}
-
-/* integer to iof; return a number of written bytes */
-
-#define iof_copy_number_buffer(O, s, p) for (p = s; *p && iof_writable(O); iof_set(O, *p), ++p)
-
-size_t iof_put_int32 (iof *O, int32_t number)
-{
-  const char *s, *p;
-  s = int32_to_string(number);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-size_t iof_put_intlw (iof *O, intlw_t number)
-{
-  const char *s, *p;
-  s = intlw_to_string(number);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-size_t iof_put_int64 (iof *O, int64_t number)
-{
-  const char *s, *p;
-  s = int64_to_string(number);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-size_t iof_put_uint32 (iof *O, uint32_t number)
-{
-  const char *s, *p;
-  s = uint32_to_string(number);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-size_t iof_put_uintlw (iof *O, uintlw_t number)
-{
-  const char *s, *p;
-  s = uintlw_to_string(number);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-size_t iof_put_uint64 (iof *O, uint64_t number)
-{
-  const char *s, *p;
-  s = uint64_to_string(number);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-size_t iof_put_int32_radix (iof *O, int32_t number, int radix)
-{
-  const char *s, *p;
-  s = int32_to_radix(number, radix);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-size_t iof_put_intlw_radix (iof *O, intlw_t number, int radix)
-{
-  const char *s, *p;
-  s = intlw_to_radix(number, radix);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-size_t iof_put_int64_radix (iof *O, int64_t number, int radix)
-{
-  const char *s, *p;
-  s = int64_to_radix(number, radix);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-size_t iof_put_uint32_radix (iof *O, uint32_t number, int radix)
-{
-  const char *s, *p;
-  s = uint32_to_radix(number, radix);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-size_t iof_put_uintlw_radix (iof *O, uintlw_t number, int radix)
-{
-  const char *s, *p;
-  s = uintlw_to_radix(number, radix);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-size_t iof_put_uint64_radix (iof *O, uint64_t number, int radix)
-{
-  const char *s, *p;
-  s = uint64_to_radix(number, radix);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-/* roman numerals */
-
-size_t iof_put_roman_uc (iof *O, uint16_t number)
-{
-  const char *s, *p;
-  s = uint16_to_roman_uc(number);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-size_t iof_put_roman_lc (iof *O, uint16_t number)
-{
-  const char *s, *p;
-  s = uint16_to_roman_lc(number);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-/* double/float to iof; return the number of written bytes */
-
-size_t iof_put_double (iof *O, double number, int digits)
-{
-  const char *s, *p;
-  s = double_to_string(number, digits);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-size_t iof_put_float (iof *O, float number, int digits)
-{
-  const char *s, *p;
-  s = float_to_string(number, digits);
-  iof_copy_number_buffer(O, s, p);
-  return p - s;
-}
-
-/* iof to binary integer; pretty common */
-
-int iof_get_be_uint2 (iof *I, uint32_t *pnumber)
-{
-  int c1, c2;
-  if ((c1 = iof_get(I)) < 0 || (c2 = iof_get(I)) < 0)
-    return 0;
-  *pnumber = (c1<<8)|c2;
-  return 1;
-}
-
-int iof_get_be_uint3 (iof *I, uint32_t *pnumber)
-{
-  int c1, c2, c3;
-  if ((c1 = iof_get(I)) < 0 || (c2 = iof_get(I)) < 0 || (c3 = iof_get(I)) < 0)
-    return 0;
-  *pnumber = (c1<<16)|(c2<<8)|c3;
-  return 1;
-}
-
-int iof_get_be_uint4 (iof *I, uint32_t *pnumber)
-{
-  int c1, c2, c3, c4;
-  if ((c1 = iof_get(I)) < 0 || (c2 = iof_get(I)) < 0 || (c3 = iof_get(I)) < 0 || (c4 = iof_get(I)) < 0)
-    return 0;
-  *pnumber = (c1<<24)|(c2<<16)|(c3<<8)|c4;
-  return 1;
-}
-
-int iof_get_le_uint2 (iof *I, uint32_t *pnumber)
-{
-  int c1, c2;
-  if ((c1 = iof_get(I)) < 0 || (c2 = iof_get(I)) < 0)
-    return 0;
-  *pnumber = (c2<<8)|c1;
-  return 1;
-}
-
-int iof_get_le_uint3 (iof *I, uint32_t *pnumber)
-{
-  int c1, c2, c3;
-  if ((c1 = iof_get(I)) < 0 || (c2 = iof_get(I)) < 0 || (c3 = iof_get(I)) < 0)
-    return 0;
-  *pnumber = (c3<<16)|(c2<<8)|c1;
-  return 1;
-}
-
-int iof_get_le_uint4 (iof *I, uint32_t *pnumber)
-{
-  int c1, c2, c3, c4;
-  if ((c1 = iof_get(I)) < 0 || (c2 = iof_get(I)) < 0 || (c3 = iof_get(I)) < 0 || (c4 = iof_get(I)) < 0)
-    return 0;
-  *pnumber = (c4<<24)|(c3<<16)|(c2<<8)|c1;
-  return 1;
-}
-
-/* iof input data */
-
-uint8_t * iof_file_input_data (iof_file *iofile, size_t *psize, int *isnew)
-{
-  uint8_t *data;
-  if (iofile->flags & IOF_DATA)
-  {
-    data = iofile->buf;
-    *psize = iofile->end - iofile->buf;
-    *isnew = 0;
-    return data;
-  }
-  if (iof_file_reopen(iofile))
-  {
-    data = iof_copy_file_handle_data(iof_file_get_fh(iofile), psize);
-    *isnew = 1;
-    iof_file_reclose(iofile);
-    return data;
-  }
-  return NULL;
-}
-
-/*
-uint8_t * iof_file_reader_data (iof_file *iofile, size_t *size)
-{
-  uint8_t *data;
-  if (!(iofile->flags & IOF_DATA) || iofile->pos == NULL || (*size = (size_t)iof_left(iofile)) == 0)
-    return NULL;  
-  if (iofile->flags & IOF_BUFFER_ALLOC)
-  {
-    data = iofile->buf; // iofile->pos; // returned must be freeable, makes sense when ->buf == ->pos
-    iofile->flags &= ~IOF_BUFFER_ALLOC;
-    iofile->buf = iofile->pos = iofile->end = NULL;
-    return data;
-  }
-  data = (uint8_t *)util_malloc(*size);
-  memcpy(data, iofile->buf, *size);
-  return data;
-}
-
-uint8_t * iof_file_writer_data (iof_file *iofile, size_t *size)
-{
-  uint8_t *data;
-  if (!(iofile->flags & IOF_DATA) || iofile->buf == NULL || (*size = (size_t)iof_size(iofile)) == 0)
-    return NULL;  
-  if (iofile->flags & IOF_BUFFER_ALLOC)
-  {
-    iofile->flags &= ~IOF_BUFFER_ALLOC;
-    data = iofile->buf;
-    iofile->buf = iofile->pos = iofile->end = NULL;
-    return data;
-  }
-  data = (uint8_t *)util_malloc(*size);
-  memcpy(data, iofile->buf, *size);
-  return data;
-}
-*/
-
-uint8_t * iof_reader_data (iof *I, size_t *psize)
-{
-  uint8_t *data;
-  *psize = (size_t)iof_left(I);
-  if (I->flags & IOF_BUFFER_ALLOC)
-  {
-    data = I->buf; // actually I->pos, but we have to return something freeable
-    I->flags &= ~IOF_BUFFER_ALLOC;
-    I->buf = NULL;
-  }
-  else
-  {
-    data = util_malloc(*psize);
-    memcpy(data, I->pos, *psize);
-  }
-  iof_close(I);
-  return data;
-}
-
-
-uint8_t * iof_writer_data (iof *O, size_t *psize)
-{
-  uint8_t *data;
-  *psize = (size_t)iof_size(O);
-  if (O->flags & IOF_BUFFER_ALLOC)
-  {
-    data = O->buf;
-    O->flags &= ~IOF_BUFFER_ALLOC;
-    O->buf = NULL;
-  }
-  else
-  {
-    data = util_malloc(*psize);
-    memcpy(data, O->buf, *psize);
-  }
-  iof_close(O);
-  return data;
-}
-
-size_t iof_reader_to_file_handle (iof *I, FILE *file)
-{
-  size_t size;
-  for (size = 0; iof_readable(I); I->pos = I->end)
-    size += fwrite(I->buf, sizeof(uint8_t), iof_left(I), file);
-  return size;
-}
-
-size_t iof_reader_to_file (iof *I, const char *filename)
-{
-  FILE *file;
-  size_t size;
-  if ((file = fopen(filename, "wb")) == NULL)
-    return 0;
-  for (size = 0; iof_readable(I); I->pos = I->end)
-    size += fwrite(I->buf, sizeof(uint8_t), iof_left(I), file);
-  fclose(file);
-  return size;
-}
-
-/* debug */
-
-size_t iof_data_to_file (const void *data, size_t size, const char *filename)
-{
-  FILE *fh;
-  if ((fh = fopen(filename, "wb")) == NULL)
-    return 0;
-  // size = fwrite(data, size, sizeof(uint8_t), fh); // WRONG, this always returns 1, as fwrite returns the number of elements successfully written out
-  size = fwrite(data, sizeof(uint8_t), size, fh);
-  fclose(fh);
-  return size;
-}
-
-size_t iof_result_to_file_handle (iof *F, FILE *file)
-{
-  const void *data;
-  size_t size;
-  data = iof_result(F, size);
-	return iof_data_to_file_handle(data, size, file);
-}
-
-size_t iof_result_to_file (iof *F, const char *filename)
-{
-  const void *data;
-  size_t size;
-  data = iof_result(F, size);
-  return iof_data_to_file(data, size, filename);
-}
-
-void iof_debug (iof *I, const char *filename)
-{
-  FILE *file = fopen(filename, "wb");
-  if (file != NULL)
-  {
-    fprintf(file, ">>> buf %p <<<\n", I->buf);
-    fwrite(I->buf, sizeof(uint8_t), iof_size(I), file);
-    fprintf(file, "\n>>> pos %p (%ld) <<<\n", I->pos, (long)iof_size(I));
-    fwrite(I->pos, sizeof(uint8_t), iof_left(I), file);
-    fprintf(file, "\n>>> end %p (%ld) <<<\n", I->end, (long)iof_left(I));
-    fwrite(I->end, sizeof(uint8_t), I->space - iof_space(I), file);
-    fprintf(file, "\n>>> end of buffer %p (%ld) <<<\n", I->buf + I->space, (long)(I->buf + I->space - I->end));
-    fclose(file);
-  }
-}
-
-/* common filters api */
-
-/* sizes of filter states on x64
-size of iof_filter: 640 (no longer used; sizeof(iof) + sizeof larger state)
-size of file_state: 16
-size of stream_state: 16
-size of flate_state: 104
-size of lzw_state: 56
-size of predictor_state: 104
-size of basexx_state: 48
-size of basexx_state: 48
-size of basexx_state: 48
-size of eexec_state: 40
-size of runlength_state: 24
-size of rc4_state: 24
-size of aes_state: 72
-size of img_state: 576
-size of img: 496
-*/
-
-typedef struct iof_heap iof_heap;
-
-struct iof_heap {
-  uint8_t *data, *pos;
-  size_t size, space;
-  iof_heap *next, *prev;
-  int refcount;
-};
-
-typedef struct {
-  iof_heap *heap;
-} iof_heap_ghost;
-
-static iof_heap * iof_buffers_heap = NULL;
-static iof_heap * iof_filters_heap = NULL;
-
-#define IOF_HEAP_FILTERS_COUNT 4
-#define IOF_BUFFER_SIZE 262144 // (1<<18)
-#define IOF_FILTER_SIZE 1024
-// sizeof(iof_filter) on x64 is now 640, img_state 576, img 496, others 16-104
-#define IOF_BUFFER_HEAP_SIZE (IOF_HEAP_FILTERS_COUNT * (IOF_BUFFER_SIZE + sizeof(iof_heap_ghost)))
-#define IOF_FILTER_HEAP_SIZE (IOF_HEAP_FILTERS_COUNT * (IOF_FILTER_SIZE + sizeof(iof_heap_ghost)))
-
-static iof_heap * iof_heap_new (size_t space)
-{
-  iof_heap *iofheap;
-  iofheap = (iof_heap *)util_malloc(sizeof(iof_heap) + space);
-  iofheap->data = iofheap->pos = (uint8_t *)(iofheap + 1);
-  iofheap->size = iofheap->space = space;
-  iofheap->next = NULL;
-  iofheap->prev = NULL;
-  iofheap->refcount = 0;
-  return iofheap;
-}
-
-#define iof_heap_free(iofheap) util_free(iofheap)
-
-void iof_filters_init (void)
-{
-  if (iof_buffers_heap == NULL)
-    iof_buffers_heap = iof_heap_new(IOF_BUFFER_HEAP_SIZE);
-  if (iof_filters_heap == NULL)
-    iof_filters_heap = iof_heap_new(IOF_FILTER_HEAP_SIZE);
-}
-
-void iof_filters_free (void)
-{
-  iof_heap *heap, *next;
-  for (heap = iof_buffers_heap; heap != NULL; heap = next)
-  {
-    next = heap->next;
-    if (heap->refcount != 0)
-      loggerf("not closed iof filters left (%d)", heap->refcount);
-    if (next != NULL)
-      loggerf("iof filters heap left");
-    iof_heap_free(heap);
-  }
-  iof_buffers_heap = NULL;
-  for (heap = iof_filters_heap; heap != NULL; heap = next)
-  {
-    next = heap->next;
-    if (heap->refcount != 0)
-      loggerf("not closed iof buffers left (%d)", heap->refcount);
-    if (next != NULL)
-      loggerf("iof buffers heap left");
-    iof_heap_free(heap);
-  }
-  iof_filters_heap = NULL;
-}
-
-#define iof_heap_get(hp, ghost, data, siz) \
- (ghost = (iof_heap_ghost *)((hp)->pos), \
-  ghost->heap = hp, \
-  data = (uint8_t *)(ghost + 1), \
-  (hp)->pos += siz, \
-  (hp)->size -= siz, \
-  ++(hp)->refcount)
-
-
-static void * iof_heap_take (iof_heap **pheap, size_t size)
-{
-  uint8_t *data;
-  iof_heap_ghost *ghost;
-  iof_heap *heap, *newheap, *next;
-
-  heap = *pheap;
-  size += sizeof(iof_heap_ghost);
-  if (heap->size >= size)
-  { /* take cheap mem from main heap */
-    iof_heap_get(heap, ghost, data, size);
-    return data;
-  }
-  if (size <= heap->space >> 1)
-  { /* make new cheap heap, make it front */
-    *pheap = newheap = iof_heap_new(heap->space);
-    newheap->next = heap;
-    heap->prev = newheap;
-    iof_heap_get(newheap, ghost, data, size);
-    return data;
-  }
-  /* size much larger than expected? should not happen.
-     make a single-item heap, keep the front heap intact. */
-  newheap = iof_heap_new(size);
-  if ((next = heap->next) != NULL)
-  {
-    newheap->next = next;
-    next->prev = newheap;
-  }
-  heap->next = newheap;
-  newheap->prev = heap;
-  iof_heap_get(newheap, ghost, data, size);
-  return data;
-}
-
-void iof_heap_back (void *data)
-{
-  iof_heap_ghost *ghost;
-  iof_heap *heap, *next, *prev;
-
-  ghost = ((iof_heap_ghost *)data) - 1;
-  heap = ghost->heap;
-  if (heap->refcount == 0)
-    loggerf("invalid use of iof heap, refcount < 0");
-  if (--heap->refcount <= 0)
-  {
-    if ((prev = heap->prev) != NULL)
-    { /* free the heap */
-      if ((next = heap->next) != NULL)
-        prev->next = next, next->prev = prev;
-      else
-        prev->next = NULL;
-      iof_heap_free(heap);
-    }
-    else
-    { /* this is the front heap, just reset */
-      heap->pos = heap->data;
-      heap->size = heap->space;
-    }
-  }
-}
-
-void * iof_filter_new (size_t size)
-{ // to be removed
-  void *data;
-
-  iof_filters_init();
-  data = iof_heap_take(&iof_filters_heap, size);
-  return memset(data, 0, size);
-}
-
-static uint8_t * iof_filter_buffer_new (size_t *psize)
-{
-  iof_filters_init();
-  *psize = IOF_BUFFER_SIZE;
-  return iof_heap_take(&iof_buffers_heap, IOF_BUFFER_SIZE);
-}
-
-iof * iof_filter_reader_new (iof_handler handler, size_t statesize, void **pstate)
-{
-  iof *F;
-  void *filter;
-  uint8_t *buffer;
-  size_t buffersize;
-
-  iof_filters_init();
-  filter = iof_heap_take(&iof_filters_heap, sizeof(iof) + statesize);
-  F = (iof *)memset(filter, 0, sizeof(iof) + statesize);
-  buffer = iof_filter_buffer_new(&buffersize);
-  iof_reader_buffer(F, buffer, buffersize);
-  F->flags |= IOF_HEAP|IOF_BUFFER_HEAP;
-  F->more = handler;
-  *pstate = (F + 1);
-  return F;
-}
-
-iof * iof_filter_reader_with_buffer_new (iof_handler handler, size_t statesize, void **pstate, void *buffer, size_t buffersize)
-{ // for filters that has own buffer (string, some image filters)
-  iof *F;
-  void *filter;
-  iof_filters_init();
-  filter = iof_heap_take(&iof_filters_heap, sizeof(iof) + statesize);
-  F = (iof *)memset(filter, 0, sizeof(iof) + statesize);
-  iof_reader_buffer(F, buffer, buffersize);
-  F->flags |= IOF_HEAP;
-  F->more = handler;
-  *pstate = (F + 1);
-  return F;
-}
-
-iof * iof_filter_writer_new (iof_handler handler, size_t statesize, void **pstate)
-{
-  iof *F;
-  void *filter;
-  uint8_t *buffer;
-  size_t buffersize;
-
-  iof_filters_init();
-  filter = iof_heap_take(&iof_filters_heap, sizeof(iof) + statesize);
-  F = (iof *)memset(filter, 0, sizeof(iof) + statesize);
-  buffer = iof_filter_buffer_new(&buffersize);
-  iof_writer_buffer(F, buffer, buffersize);
-  F->flags |= IOF_HEAP|IOF_BUFFER_HEAP;
-  F->more = handler;
-  *pstate = (F + 1);
-  return F;
-}
-
-iof * iof_filter_writer_with_buffer_new (iof_handler handler, size_t statesize, void **pstate, void *buffer, size_t size)
-{
-  iof *F;
-  void *filter;
-  size_t buffersize;
-
-  iof_filters_init();
-  filter = iof_heap_take(&iof_filters_heap, sizeof(iof) + statesize);
-  F = (iof *)memset(filter, 0, sizeof(iof) + statesize);
-  buffer = iof_filter_buffer_new(&buffersize);
-  iof_writer_buffer(F, buffer, buffersize);
-  F->flags |= IOF_HEAP;
-  F->more = handler;
-  *pstate = (F + 1);
-  return F;
-}
-
-/* close */
-
-#define iof_close_next(F) ((void)(iof_decref((F)->next), (F)->next = NULL, 0))
-/* when filter creation fails, we should take care to destroy the filter but leave ->next intact */
-#define iof_clear_next(F) ((void)(iof_unref((F)->next), (F)->next = NULL, 0))
-
-#define iof_close_buffer(F) ((void)\
-  ((F)->buf != NULL ? \
-      ((F->flags & IOF_BUFFER_ALLOC) ? (util_free((F)->buf), (F)->buf = NULL, 0) : \
-      ((F->flags & IOF_BUFFER_HEAP) ? (iof_filter_buffer_free((F)->buf), (F)->buf = NULL, 0) : ((F)->buf = NULL, 0))) : 0))
-
-/* closing underlying file handle */
-
-static void iof_close_file (iof *F)
-{
-  FILE *file;
-  //if (F->flags & IOF_FILE_HANDLE)
-  //{
-    if ((file = F->file) != NULL)
-    {
-      if (F->flags & IOF_CLOSE_FILE)
-        fclose(F->file);
-      F->file = NULL;
-    }
-  //}
-}
-
-/* a very special variant for reader filters initiated with iof_file_reopen(). It also calls
-   iof_file_reclose(), which takes an effect only if previously reopened, but better to keep
-   all this thin ice separated. Used in filters: iofile_reader, iofile_stream_reader, image
-   decoders. */
-
-static void iof_close_iofile (iof *F)
-{
-  iof_file *iofile;
-  //if (F->flags & IOF_FILE)
-  //{
-    if ((iofile = F->iofile) != NULL)
-    {
-      iof_file_unsync(iofile, NULL);
-      iof_file_reclose(iofile); // takes an effect iff prevoiusly reopened
-      iof_file_decref(iofile);
-      F->iofile = NULL;
-    }
-  //}
-}
-
-void iof_free (iof *F)
-{
-  if (F->flags & IOF_FILE_HANDLE)
-    iof_close_file(F);
-  else if (F->flags & IOF_FILE)
-    iof_close_iofile(F);
-  else if (F->flags & IOF_NEXT)
-    iof_close_next(F);
-  iof_close_buffer(F);
-  if (F->flags & IOF_HEAP)
-    iof_filter_free(F);
-  else if (F->flags & IOF_ALLOC)
-    util_free(F);
-}
-
-void iof_discard (iof *F)
-{ // so far used only on failed filters creation; as iof_free() but don't dare to release ->next
-  if (F->flags & IOF_FILE_HANDLE)
-    iof_close_file(F);
-  else if (F->flags & IOF_FILE)
-    iof_close_iofile(F);
-  else if (F->flags & IOF_NEXT)
-    iof_close_next(F);
-  iof_close_buffer(F);
-  if (F->flags & IOF_HEAP)
-    iof_filter_free(F);
-  else if (F->flags & IOF_ALLOC)
-    util_free(F);
-}
-
-/* resizing buffer */
-
-size_t iof_resize_buffer_to (iof *O, size_t space)
-{
-  uint8_t *buf;
-
-  if (O->flags & IOF_BUFFER_ALLOC)
-  {
-    buf = (uint8_t *)util_realloc(O->buf, space);
-  }
-  else
-  {
-    buf = (uint8_t *)util_malloc(space);
-    memcpy(buf, O->buf, iof_size(O));
-    if (O->flags & IOF_BUFFER_HEAP)
-    {
-      iof_filter_buffer_free(O->buf);
-      O->flags &= ~IOF_BUFFER_HEAP;
-    }
-    O->flags |= IOF_BUFFER_ALLOC;
-
-  }
-  O->pos = buf + iof_size(O);
-  O->end = buf + space;
-  O->buf = buf;
-  O->space = space;
-  return iof_left(O);
-}
-
-/* */
-
-size_t iof_decoder_retval (iof *I, const char *type, iof_status status)
-{
-  switch (status)
-  {
-    case IOFERR:
-    case IOFEMPTY:             // should never happen as we set state.flush = 1 on decoders init
-      loggerf("%s decoder error (%d, %s)", type, status, iof_status_kind(status));
-      I->flags |= IOF_STOPPED;
-      return 0;
-    case IOFEOF:               // this is the last chunk,
-      I->flags |= IOF_STOPPED; // so stop it and fall
-    case IOFFULL:              // prepare pointers to read from I->buf
-      I->end = I->pos;
-      I->pos = I->buf;
-      return I->end - I->buf;
-  }
-  loggerf("%s decoder bug, invalid retval %d", type, status);
-  return 0;
-}
-
-size_t iof_encoder_retval (iof *O, const char *type, iof_status status)
-{
-  switch (status)
-  {
-    case IOFERR:
-    case IOFFULL:
-      loggerf("%s encoder error (%d, %s)", type, status, iof_status_kind(status));
-      return 0;
-    case IOFEMPTY:
-      O->pos = O->buf;
-      O->end = O->buf + O->space;
-      return O->space;
-    case IOFEOF:
-      return 0;
-  }
-  loggerf("%s encoder bug, invalid retval %d", type, status);
-  return 0;
-}
-
-/* file/stream state */
-
-typedef struct {
-  size_t length;
-  size_t offset;
-} file_state;
-
-
-#define file_state_init(state, off, len) ((state)->offset = off, (state)->length = len)
-
-typedef struct {
-  size_t length;
-  size_t offset;
-} stream_state;
-
-#define stream_state_init(state, off, len) ((state)->offset = off, (state)->length = len)
-
-static size_t file_read (iof *I)
-{
-  size_t bytes, tail;
-  if (I->flags & IOF_STOPPED)
-    return 0;
-  tail = iof_tail(I);
-  if ((bytes = tail + fread(I->buf + tail, sizeof(uint8_t), I->space - tail, I->file)) < I->space)
-    I->flags |= IOF_STOPPED;
-  I->pos = I->buf;
-  I->end = I->buf + bytes;
-  return bytes;
-}
-
-static size_t iofile_read (iof *I, size_t *poffset)
-{
-  size_t bytes, tail;
-  if (I->flags & IOF_STOPPED)
-    return 0;
-  iof_file_sync(I->iofile, poffset);
-  tail = iof_tail(I);
-  if ((bytes = tail + iof_file_read(I->buf + tail, sizeof(uint8_t), I->space - tail, I->iofile)) < I->space)
-  {
-    I->flags |= IOF_STOPPED;
-    iof_file_unsync(I->iofile, poffset);
-  }
-  I->pos = I->buf;
-  I->end = I->buf + bytes;
-  return bytes;
-}
-
-static size_t file_load (iof *I)
-{
-  size_t bytes, left, tail;
-  if (I->flags & IOF_STOPPED)
-    return 0;
-  tail = iof_tail(I);
-  I->pos = I->buf + tail;
-  I->end = I->buf + I->space; /* don't assume its done when initializing the filter */
-  left = I->space - tail;
-  do {
-    bytes = fread(I->pos, sizeof(uint8_t), left, I->file);
-    I->pos += bytes;
-  } while (bytes == left && (left = iof_resize_buffer(I)) > 0);
-  I->flags |= IOF_STOPPED;
-  return iof_loaded(I);
-}
-
-static size_t iofile_load (iof *I, size_t *poffset)
-{
-  size_t bytes, left, tail;
-  if (I->flags & IOF_STOPPED)
-    return 0;
-  tail = iof_tail(I);
-  I->pos = I->buf + tail;
-  I->end = I->buf + I->space; /* don't assume its done when initializing the filter */
-  left = I->space - tail;
-  iof_file_sync(I->iofile, poffset);
-  do {
-    bytes = iof_file_read(I->pos, sizeof(uint8_t), left, I->iofile);
-    I->pos += bytes;
-  } while (bytes == left && (left = iof_resize_buffer(I)) > 0);
-  I->flags |= IOF_STOPPED;
-  iof_file_unsync(I->iofile, poffset);
-  return iof_loaded(I);
-}
-
-static size_t filter_file_reader (iof *I, iof_mode mode)
-{
-  switch (mode)
-  {
-    case IOFREAD:
-      return file_read(I);
-    case IOFLOAD:
-      return file_load(I);
-    case IOFCLOSE:
-      iof_free(I);
-      return 0;
-    default:
-      return 0;
-  }
-}
-
-static size_t filter_iofile_reader (iof *I, iof_mode mode)
-{
-  file_state *state;
-  state = iof_filter_state(file_state *, I);
-  switch (mode)
-  {
-    case IOFREAD:
-      return iofile_read(I, &state->offset);
-    case IOFLOAD:
-      return iofile_load(I, &state->offset);
-    case IOFCLOSE:
-      iof_free(I);
-      return 0;
-    default:
-      return 0;
-  }
-}
-
-static size_t file_write (iof *O, int flush)
-{
-  size_t bytes;
-  if ((bytes = iof_size(O)) > 0)
-    if (bytes != fwrite(O->buf, sizeof(uint8_t), bytes, O->file))
-      return 0;
-  if (flush)
-    fflush(O->file);
-  O->end = O->buf + O->space; // remains intact actually
-  O->pos = O->buf;
-  return O->space;
-}
-
-static size_t iofile_write (iof *O, size_t *poffset, int flush)
-{
-  size_t bytes;
-  iof_file_sync(O->iofile, poffset);
-  if ((bytes = iof_size(O)) > 0)
-  {
-    if (bytes != iof_file_write(O->buf, sizeof(uint8_t), bytes, O->iofile))
-    {
-      iof_file_unsync(O->iofile, poffset);
-      return 0;
-    }
-  }
-  if (flush)
-    iof_file_flush(O->iofile);
-  O->end = O->buf + O->space; // remains intact actually
-  O->pos = O->buf;
-  return O->space;
-}
-
-static size_t filter_file_writer (iof *O, iof_mode mode)
-{
-  switch (mode)
-  {
-    case IOFWRITE:
-      return file_write(O, 0);
-    case IOFFLUSH:
-      return file_write(O, 1);
-    case IOFCLOSE:
-      file_write(O, 1);
-      iof_free(O);
-      return 0;
-    default:
-      return 0;
-  }
-}
-
-static size_t filter_iofile_writer (iof *O, iof_mode mode)
-{
-  file_state *state;
-  state = iof_filter_state(file_state *, O);
-  switch (mode)
-  {
-    case IOFWRITE:
-      return iofile_write(O, &state->offset, 0);
-    case IOFFLUSH:
-      return iofile_write(O, &state->offset, 1);
-    case IOFCLOSE:
-      iofile_write(O, &state->offset, 1);
-      iof_free(O);
-      return 0;
-    default:
-      return 0;
-  }
-}
-
-/* filter from FILE* */
-
-iof * iof_filter_file_handle_reader (FILE *file)
-{
-  iof *I;
-  file_state *state;
-  if (file == NULL)
-    return NULL;
-  I = iof_filter_reader(filter_file_reader, sizeof(file_state), &state);
-  iof_setup_file(I, file);
-  file_state_init(state, 0, 0);
-  return I;
-}
-
-iof * iof_filter_file_handle_writer (FILE *file)
-{
-  iof *O;
-  file_state *state;
-  if (file == NULL)
-    return NULL;
-  O = iof_filter_writer(filter_file_writer, sizeof(file_state), &state);
-  iof_setup_file(O, file);
-  file_state_init(state, 0, 0);
-  return O;
-}
-
-/* filter from iof_file * */
-
-iof * iof_filter_iofile_reader (iof_file *iofile, size_t offset)
-{
-  iof *I;
-  file_state *state;
-  if (!iof_file_reopen(iofile))
-    return NULL;
-  I = iof_filter_reader(filter_iofile_reader, sizeof(file_state), &state);
-  iof_setup_iofile(I, iofile);
-  file_state_init(state, offset, 0);
-  return I;
-}
-
-iof * iof_filter_iofile_writer (iof_file *iofile, size_t offset)
-{
-  iof *O;
-  file_state *state;
-  O = iof_filter_writer(filter_iofile_writer, sizeof(file_state), &state);
-  iof_setup_iofile(O, iofile);
-  file_state_init(state, offset, 0);
-  return O;
-}
-
-/* filter from filename */
-
-iof * iof_filter_file_reader (const char *filename)
-{
-  iof *I;
-  file_state *state;
-  FILE *file;
-  if ((file = fopen(filename, "rb")) == NULL)
-    return NULL;
-  I = iof_filter_reader(filter_file_reader, sizeof(file_state), &state);
-  iof_setup_file(I, file);
-  file_state_init(state, 0, 0);
-  I->flags |= IOF_CLOSE_FILE;
-  return I;
-}
-
-iof * iof_filter_file_writer (const char *filename)
-{
-  iof *O;
-  file_state *state;
-  FILE *file;
-  if ((file = fopen(filename, "wb")) == NULL)
-    return NULL;
-  O = iof_filter_writer(filter_file_writer, sizeof(file_state), &state);
-  iof_setup_file(O, file);
-  file_state_init(state, 0, 0);
-  O->flags |= IOF_CLOSE_FILE;
-  return O;
-}
-
-/* from string */
-
-static size_t dummy_handler (iof *I, iof_mode mode)
-{
-  switch (mode)
-  {
-    case IOFCLOSE:
-      iof_free(I);
-      return 0;
-    default:
-      return 0;
-  }
-}
-
-iof * iof_filter_string_reader (const void *s, size_t length)
-{
-  iof *I;
-  void *dummy;
-  I = iof_filter_reader_with_buffer(dummy_handler, 0, &dummy, NULL, 0);
-  I->rbuf = I->rpos = (const uint8_t *)s;
-  I->rend = (const uint8_t *)s + length;
-  // I->space = length;
-  return I;
-}
-
-iof * iof_filter_string_writer (const void *s, size_t length)
-{
-  iof *O;
-  void *dummy;
-  O = iof_filter_reader_with_buffer(dummy_handler, 0, &dummy, NULL, 0);
-  O->rbuf = O->rpos = (const uint8_t *)s;
-  O->rend = (const uint8_t *)s + length;
-  // O->space = length;
-  return O;
-}
-
-iof * iof_filter_buffer_writer (size_t size)
-{ // filter alternative of iof_buffer_create()
-  iof *O;
-  void *dummy;
-  uint8_t *buffer;
-  if (size > IOF_BUFFER_SIZE)
-  {
-    buffer = (uint8_t *)util_malloc(size);
-    O = iof_filter_writer_with_buffer(iof_mem_handler, 0, &dummy, buffer, size);
-    O->flags |= IOF_BUFFER_ALLOC;
-    return O;
-  }
-	return iof_filter_writer(iof_mem_handler, 0, &dummy);
-}
-
-/* stream */
-
-static size_t file_stream_read (iof *I, size_t *plength)
-{
-  size_t bytes, tail;
-  if (I->flags & IOF_STOPPED || *plength == 0)
-    return 0;
-  tail = iof_tail(I);
-  if (I->space - tail >= *plength)
-  {
-    bytes = tail + fread(I->buf + tail, sizeof(uint8_t), *plength, I->file);
-    I->flags |= IOF_STOPPED;
-    *plength = 0;
-  }
-  else
-  {
-    bytes = tail + fread(I->buf + tail, sizeof(uint8_t), I->space - tail, I->file);
-    *plength -= bytes - tail;
-  }
-  I->pos = I->buf;
-  I->end = I->buf + bytes;
-  return bytes;
-}
-
-static size_t iofile_stream_read (iof *I, size_t *plength, size_t *poffset)
-{
-  size_t bytes, tail;
-  if (I->flags & IOF_STOPPED || *plength == 0)
-    return 0;
-  tail = iof_tail(I);
-  iof_file_sync(I->iofile, poffset);
-  if (I->space - tail >= *plength)
-  {
-    bytes = tail + iof_file_read(I->buf + tail, sizeof(uint8_t), *plength, I->iofile);
-    iof_file_unsync(I->iofile, poffset);
-    I->flags |= IOF_STOPPED;
-    *plength = 0;
-  }
-  else
-  {
-    bytes = tail + iof_file_read(I->buf + tail, sizeof(uint8_t), I->space - tail, I->iofile);
-    *plength -= bytes - tail;
-  }
-  I->pos = I->buf;
-  I->end = I->buf + bytes;
-  return bytes;
-}
-
-static size_t file_stream_load (iof *I, size_t *plength)
-{
-  size_t bytes, tail;
-  if (I->flags & IOF_STOPPED || *plength == 0)
-    return 0;
-  tail = iof_tail(I);
-  if (I->space - tail < *plength)
-    if (iof_resize_buffer_to(I, tail + *plength) == 0)
-      return 0;
-  bytes = tail + fread(I->buf + tail, sizeof(uint8_t), *plength, I->file);
-  I->flags |= IOF_STOPPED;
-  *plength = 0;
-  I->pos = I->buf;
-  I->end = I->buf + bytes;
-  return bytes;
-}
-
-static size_t iofile_stream_load (iof *I, size_t *plength, size_t *poffset)
-{
-  size_t bytes, tail;
-  if (I->flags & IOF_STOPPED || *plength == 0)
-    return 0;
-  iof_file_sync(I->iofile, poffset);
-  tail = iof_tail(I);
-  if (I->space - tail < *plength)
-    if (iof_resize_buffer_to(I, tail + *plength) == 0)
-      return 0;
-  bytes = tail + iof_file_read(I->buf + tail, sizeof(uint8_t), *plength, I->iofile);
-  iof_file_unsync(I->iofile, poffset);
-  I->flags |= IOF_STOPPED;
-  *plength = 0;
-  I->pos = I->buf;
-  I->end = I->buf + bytes;
-  return bytes;
-}
-
-static size_t filter_file_stream_reader (iof *I, iof_mode mode)
-{
-  stream_state *state;
-  state = iof_filter_state(stream_state *, I);
-  switch(mode)
-  {
-    case IOFREAD:
-      return file_stream_read(I, &state->length);
-    case IOFLOAD:
-      return file_stream_load(I, &state->length);
-    case IOFCLOSE:
-      iof_free(I);
-      return 0;
-    default:
-      return 0;
-  }
-}
-
-static size_t filter_iofile_stream_reader (iof *I, iof_mode mode)
-{
-  stream_state *state;
-  state = iof_filter_state(stream_state *, I);
-  switch(mode)
-  {
-    case IOFREAD:
-      return iofile_stream_read(I, &state->length, &state->offset);
-    case IOFLOAD:
-      return iofile_stream_load(I, &state->length, &state->offset);
-    case IOFCLOSE:
-      iof_free(I);
-      return 0;
-    default:
-      return 0;
-  }
-}
-
-iof * iof_filter_stream_reader (FILE *file, size_t offset, size_t length)
-{
-  iof *I;
-  stream_state *state;
-  I = iof_filter_reader(filter_file_stream_reader, sizeof(stream_state), &state);
-  iof_setup_file(I, file);
-  stream_state_init(state, offset, length);
-  fseek(file, (long)offset, SEEK_SET); // or perhaps it should be call in file_stream_read(), like iof_file_sync()?
-  return I;
-}
-
-iof * iof_filter_stream_coreader (iof_file *iofile, size_t offset, size_t length)
-{
-  iof *I;
-  stream_state *state;
-  if (!iof_file_reopen(iofile))
-    return NULL;
-  I = iof_filter_reader(filter_iofile_stream_reader, sizeof(stream_state), &state);
-  iof_setup_iofile(I, iofile);
-  stream_state_init(state, offset, length);
-  return I;
-}
-
-static size_t file_stream_write (iof *O, size_t *plength, int flush)
-{
-  size_t bytes;
-  if ((bytes = iof_size(O)) > 0)
-  {
-    if (bytes != fwrite(O->buf, sizeof(uint8_t), bytes, O->file))
-    {
-      *plength += bytes;
-      return 0;
-    }
-  }
-  if (flush)
-    fflush(O->file);
-  *plength += bytes;
-  O->end = O->buf + O->space; // remains intact
-  O->pos = O->buf;
-  return O->space;
-}
-
-static size_t iofile_stream_write (iof *O, size_t *plength, size_t *poffset, int flush)
-{
-  size_t bytes;
-  if ((bytes = iof_size(O)) > 0)
-  {
-    iof_file_sync(O->iofile, poffset);
-    if (bytes != iof_file_write(O->buf, sizeof(uint8_t), bytes, O->iofile))
-    {
-      *plength += bytes;
-      iof_file_unsync(O->iofile, poffset);
-      return 0;
-    }
-  }
-  if (flush)
-    iof_file_flush(O->iofile);
-  *plength += bytes;
-  O->end = O->buf + O->space; // remains intact
-  O->pos = O->buf;
-  return O->space;
-}
-
-static size_t filter_file_stream_writer (iof *O, iof_mode mode)
-{
-  stream_state *state;
-  state = iof_filter_state(stream_state *, O);
-  switch (mode)
-  {
-    case IOFWRITE:
-      return file_stream_write(O, &state->length, 0);
-    case IOFFLUSH:
-      return file_stream_write(O, &state->length, 1);
-    case IOFCLOSE:
-      file_stream_write(O, &state->length, 1);
-      iof_free(O);
-      return 0;
-    default:
-      return 0;
-  }
-}
-
-static size_t filter_iofile_stream_writer (iof *O, iof_mode mode)
-{
-  stream_state *state;
-  state = iof_filter_state(stream_state *, O);
-  switch (mode)
-  {
-    case IOFWRITE:
-      return iofile_stream_write(O, &state->length, &state->offset, 0);
-    case IOFFLUSH:
-      return iofile_stream_write(O, &state->length, &state->offset, 1);
-    case IOFCLOSE:
-      iofile_stream_write(O, &state->length, &state->offset, 1);
-      iof_free(O);
-      return 0;
-    default:
-      return 0;
-  }
-}
-
-iof * iof_filter_stream_writer (FILE *file)
-{
-  iof *O;
-  stream_state *state;
-  O = iof_filter_writer(filter_file_stream_writer, sizeof(stream_state), &state);
-  iof_setup_file(O, file);
-  stream_state_init(state, 0, 0);
-  return O;
-}
-
-iof * iof_filter_stream_cowriter (iof_file *iofile, size_t offset)
-{
-  iof *O;
-  stream_state *state;
-  O = iof_filter_writer(filter_iofile_stream_writer, sizeof(stream_state), &state);
-  iof_setup_iofile(O, iofile);
-  stream_state_init(state, offset, 0);
-  return O;
-}
-
-/* very specific for images; get input from already created strem filter, exchange the filter but keep the buffer */
-
-FILE * iof_filter_file_reader_source (iof *I, size_t *poffset, size_t *plength)
-{
-  stream_state *sstate;
-  file_state *fstate;
-  if (I->more == filter_file_stream_reader) // I is the result of iof_filter_stream_reader()
-  {
-    sstate = iof_filter_state(stream_state *, I);
-    *poffset = sstate->offset;
-    *plength = sstate->length; // might be 0 but it is ok for file readers
-    return I->file;
-  }
-  if (I->more == filter_file_reader)
-  {
-    fstate = iof_filter_state(file_state *, I);
-    *poffset = fstate->offset;
-    *plength = fstate->length; // might be 0 but it is ok for file readers
-    return I->file;
-  }
-  return NULL;
-}
-
-iof_file * iof_filter_file_coreader_source (iof *I, size_t *poffset, size_t *plength)
-{
-  stream_state *sstate;
-  file_state *fstate;
-  if (I->more == filter_iofile_stream_reader) // I is the result of iof_filter_stream_coreader()
-  {
-    sstate = iof_filter_state(stream_state *, I);
-    *poffset = sstate->offset;
-    *plength = sstate->length;
-    return I->iofile;
-  }
-  if (I->more == filter_iofile_reader)
-  {
-    fstate = iof_filter_state(file_state *, I);
-    *poffset = fstate->offset;
-    *plength = fstate->length;
-    return I->iofile;
-  }
-  return NULL;
-}
-
-iof * iof_filter_reader_replacement (iof *P, iof_handler handler, size_t statesize, void **pstate)
-{ // called after iof_filter_file_reader_source(), no need to check if F is filter from iof heap and if has buffer from iof heap
-  iof *F;
-  F = iof_filter_reader_with_buffer(handler, statesize, pstate, P->buf, P->space);
-  F->flags |= IOF_BUFFER_HEAP;
-  //iof_reader_buffer(P, NULL, 0);
-  //P->flags &= ~IOF_BUFFER_HEAP;
-  iof_filter_free(P);
-  return F;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

Deleted: trunk/Build/source/texk/web2c/luatexdir/luapplib/util/utilsha.c-OK
===================================================================
--- trunk/Build/source/texk/web2c/luatexdir/luapplib/util/utilsha.c-OK	2018-09-05 21:32:42 UTC (rev 48592)
+++ trunk/Build/source/texk/web2c/luatexdir/luapplib/util/utilsha.c-OK	2018-09-05 21:35:27 UTC (rev 48593)
@@ -1,1198 +0,0 @@
-/* sha2 implementation by Aaron D. Gifford (http://www.aarongifford.com) */
-
-#define BYTE_ORDER LITTLE_ENDIAN
-
-/* begin of sha2.c */
-
-/*
- * FILE:	sha2.c
- * AUTHOR:	Aaron D. Gifford - http://www.aarongifford.com/
- *
- * Copyright (c) 2000-2001, Aaron D. Gifford
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holder nor the names of contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
- */
-
-#include <string.h>	/* memcpy()/memset() or bcopy()/bzero() */
-#include <assert.h>	/* assert() */
-//#include "sha2.h"
-#include "utilsha.h"
-
-/*
- * ASSERT NOTE:
- * Some sanity checking code is included using assert().  On my FreeBSD
- * system, this additional code can be removed by compiling with NDEBUG
- * defined.  Check your own systems manpage on assert() to see how to
- * compile WITHOUT the sanity checking code on your system.
- *
- * UNROLLED TRANSFORM LOOP NOTE:
- * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
- * loop version for the hash transform rounds (defined using macros
- * later in this file).  Either define on the command line, for example:
- *
- *   cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
- *
- * or define below:
- *
- *   #define SHA2_UNROLL_TRANSFORM
- *
- */
-
-
-/*** SHA-256/384/512 Machine Architecture Definitions *****************/
-/*
- * BYTE_ORDER NOTE:
- *
- * Please make sure that your system defines BYTE_ORDER.  If your
- * architecture is little-endian, make sure it also defines
- * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
- * equivilent.
- *
- * If your system does not define the above, then you can do so by
- * hand like this:
- *
- *   #define LITTLE_ENDIAN 1234
- *   #define BIG_ENDIAN    4321
- *
- * And for little-endian machines, add:
- *
- *   #define BYTE_ORDER LITTLE_ENDIAN
- *
- * Or for big-endian machines:
- *
- *   #define BYTE_ORDER BIG_ENDIAN
- *
- * The FreeBSD machine this was written on defines BYTE_ORDER
- * appropriately by including <sys/types.h> (which in turn includes
- * <machine/endian.h> where the appropriate definitions are actually
- * made).
- */
-#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
-#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
-#endif
-
-/*
- * Define the followingsha2_* types to types of the correct length on
- * the native archtecture.   Most BSD systems and Linux define u_intXX_t
- * types.  Machines with very recent ANSI C headers, can use the
- * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H
- * during compile or in the sha.h header file.
- *
- * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
- * will need to define these three typedefs below (and the appropriate
- * ones in sha.h too) by hand according to their system architecture.
- *
- * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
- * types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
- *
- * PJ: replace by uintX_t
- */
-
-//typedef uint8_t  sha2_byte;	/* Exactly 1 byte */
-//typedef uint32_t sha2_word32;	/* Exactly 4 bytes */
-//typedef uint64_t sha2_word64;	/* Exactly 8 bytes */
-
-/*** SHA-256/384/512 Various Length Definitions ***********************/
-/* NOTE: Most of these are in sha2.h */
-#define SHA256_SHORT_BLOCK_LENGTH	(SHA256_BLOCK_LENGTH - 8)
-#define SHA384_SHORT_BLOCK_LENGTH	(SHA384_BLOCK_LENGTH - 16)
-#define SHA512_SHORT_BLOCK_LENGTH	(SHA512_BLOCK_LENGTH - 16)
-
-
-/*** ENDIAN REVERSAL MACROS *******************************************/
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define REVERSE32(w,x)	{ \
-	uint32_t tmp = (w); \
-	tmp = (tmp >> 16) | (tmp << 16); \
-	(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
-}
-#define REVERSE64(w,x)	{ \
-	uint64_t tmp = (w); \
-	tmp = (tmp >> 32) | (tmp << 32); \
-	tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
-	      ((tmp & 0x00ff00ff00ff00ffULL) << 8); \
-	(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
-	      ((tmp & 0x0000ffff0000ffffULL) << 16); \
-}
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-
-/*
- * Macro for incrementally adding the unsigned 64-bit integer n to the
- * unsigned 128-bit integer (represented using a two-element array of
- * 64-bit words):
- */
-#define ADDINC128(w,n)	{ \
-	(w)[0] += (uint64_t)(n); \
-	if ((w)[0] < (n)) { \
-		(w)[1]++; \
-	} \
-}
-
-/*
- * Macros for copying blocks of memory and for zeroing out ranges
- * of memory.  Using these macros makes it easy to switch from
- * using memset()/memcpy() and using bzero()/bcopy().
- *
- * Please define either SHA2_USE_MEMSET_MEMCPY or define
- * SHA2_USE_BZERO_BCOPY depending on which function set you
- * choose to use:
- */
-#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
-/* Default to memset()/memcpy() if no option is specified */
-#define	SHA2_USE_MEMSET_MEMCPY	1
-#endif
-#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
-/* Abort with an error if BOTH options are defined */
-#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
-#endif
-
-#ifdef SHA2_USE_MEMSET_MEMCPY
-#define MEMSET_BZERO(p,l)	memset((p), 0, (l))
-#define MEMCPY_BCOPY(d,s,l)	memcpy((d), (s), (l))
-#endif
-#ifdef SHA2_USE_BZERO_BCOPY
-#define MEMSET_BZERO(p,l)	bzero((p), (l))
-#define MEMCPY_BCOPY(d,s,l)	bcopy((s), (d), (l))
-#endif
-
-
-/*** THE SIX LOGICAL FUNCTIONS ****************************************/
-/*
- * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
- *
- *   NOTE:  The naming of R and S appears backwards here (R is a SHIFT and
- *   S is a ROTATION) because the SHA-256/384/512 description document
- *   (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
- *   same "backwards" definition.
- */
-/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
-#define R(b,x) 		((x) >> (b))
-/* 32-bit Rotate-right (used in SHA-256): */
-#define S32(b,x)	(((x) >> (b)) | ((x) << (32 - (b))))
-/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
-#define S64(b,x)	(((x) >> (b)) | ((x) << (64 - (b))))
-
-/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
-#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
-#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-
-/* Four of six logical functions used in SHA-256: */
-#define Sigma0_256(x)	(S32(2,  (x)) ^ S32(13, (x)) ^ S32(22, (x)))
-#define Sigma1_256(x)	(S32(6,  (x)) ^ S32(11, (x)) ^ S32(25, (x)))
-#define sigma0_256(x)	(S32(7,  (x)) ^ S32(18, (x)) ^ R(3 ,   (x)))
-#define sigma1_256(x)	(S32(17, (x)) ^ S32(19, (x)) ^ R(10,   (x)))
-
-/* Four of six logical functions used in SHA-384 and SHA-512: */
-#define Sigma0_512(x)	(S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
-#define Sigma1_512(x)	(S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
-#define sigma0_512(x)	(S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7,   (x)))
-#define sigma1_512(x)	(S64(19, (x)) ^ S64(61, (x)) ^ R( 6,   (x)))
-
-/*** INTERNAL FUNCTION PROTOTYPES *************************************/
-/* NOTE: These should not be accessed directly from outside this
- * library -- they are intended for private internal visibility/use
- * only.
- */
-static void SHA512_Last(SHA512_CTX*);
-static void SHA256_Transform(SHA256_CTX*, const uint32_t*);
-static void SHA512_Transform(SHA512_CTX*, const uint64_t*);
-
-
-/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
-/* Hash constant words K for SHA-256: */
-static const uint32_t K256[64] = {
-	0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
-	0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
-	0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
-	0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
-	0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
-	0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
-	0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
-	0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
-	0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
-	0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
-	0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
-	0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
-	0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
-	0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
-	0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
-	0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
-};
-
-/* Initial hash value H for SHA-256: */
-static const uint32_t sha256_initial_hash_value[8] = {
-	0x6a09e667UL,
-	0xbb67ae85UL,
-	0x3c6ef372UL,
-	0xa54ff53aUL,
-	0x510e527fUL,
-	0x9b05688cUL,
-	0x1f83d9abUL,
-	0x5be0cd19UL
-};
-
-/* Hash constant words K for SHA-384 and SHA-512: */
-static const uint64_t K512[80] = {
-	0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
-	0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
-	0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
-	0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
-	0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
-	0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
-	0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
-	0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
-	0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
-	0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
-	0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
-	0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
-	0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
-	0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
-	0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
-	0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
-	0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
-	0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
-	0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
-	0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
-	0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
-	0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
-	0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
-	0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
-	0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
-	0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
-	0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
-	0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
-	0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
-	0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
-	0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
-	0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
-	0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
-	0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
-	0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
-	0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
-	0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
-	0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
-	0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
-	0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
-};
-
-/* Initial hash value H for SHA-384 */
-static const uint64_t sha384_initial_hash_value[8] = {
-	0xcbbb9d5dc1059ed8ULL,
-	0x629a292a367cd507ULL,
-	0x9159015a3070dd17ULL,
-	0x152fecd8f70e5939ULL,
-	0x67332667ffc00b31ULL,
-	0x8eb44a8768581511ULL,
-	0xdb0c2e0d64f98fa7ULL,
-	0x47b5481dbefa4fa4ULL
-};
-
-/* Initial hash value H for SHA-512 */
-static const uint64_t sha512_initial_hash_value[8] = {
-	0x6a09e667f3bcc908ULL,
-	0xbb67ae8584caa73bULL,
-	0x3c6ef372fe94f82bULL,
-	0xa54ff53a5f1d36f1ULL,
-	0x510e527fade682d1ULL,
-	0x9b05688c2b3e6c1fULL,
-	0x1f83d9abfb41bd6bULL,
-	0x5be0cd19137e2179ULL
-};
-
-/*
- * Constant used by SHA256/384/512_End() functions for converting the
- * digest to a readable hexadecimal character string:
- */
-
-//static const char *sha2_hex_digits = "0123456789abcdef"; // PJ
-
-
-/*** SHA-256: *********************************************************/
-static void SHA256_Init(SHA256_CTX* context) {
-	if (context == (SHA256_CTX*)0) {
-		return;
-	}
-	MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
-	MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);
-	context->bitcount = 0;
-}
-
-#ifdef SHA2_UNROLL_TRANSFORM
-
-/* Unrolled SHA-256 round macros: */
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-
-#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
-	REVERSE32(*data++, W256[j]); \
-	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
-             K256[j] + W256[j]; \
-	(d) += T1; \
-	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
-	j++
-
-
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
-	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
-	     K256[j] + (W256[j] = *data++); \
-	(d) += T1; \
-	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
-	j++
-
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND256(a,b,c,d,e,f,g,h)	\
-	s0 = W256[(j+1)&0x0f]; \
-	s0 = sigma0_256(s0); \
-	s1 = W256[(j+14)&0x0f]; \
-	s1 = sigma1_256(s1); \
-	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
-	     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
-	(d) += T1; \
-	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
-	j++
-
-void SHA256_Transform(SHA256_CTX* context, const uint32_t* data) {
-	uint32_t	a, b, c, d, e, f, g, h, s0, s1;
-	uint32_t	T1, *W256;
-	int		j;
-
-	W256 = (uint32_t*)context->buffer;
-
-	/* Initialize registers with the prev. intermediate value */
-	a = context->state[0];
-	b = context->state[1];
-	c = context->state[2];
-	d = context->state[3];
-	e = context->state[4];
-	f = context->state[5];
-	g = context->state[6];
-	h = context->state[7];
-
-	j = 0;
-	do {
-		/* Rounds 0 to 15 (unrolled): */
-		ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
-		ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
-		ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
-		ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
-		ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
-		ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
-		ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
-		ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
-	} while (j < 16);
-
-	/* Now for the remaining rounds to 64: */
-	do {
-		ROUND256(a,b,c,d,e,f,g,h);
-		ROUND256(h,a,b,c,d,e,f,g);
-		ROUND256(g,h,a,b,c,d,e,f);
-		ROUND256(f,g,h,a,b,c,d,e);
-		ROUND256(e,f,g,h,a,b,c,d);
-		ROUND256(d,e,f,g,h,a,b,c);
-		ROUND256(c,d,e,f,g,h,a,b);
-		ROUND256(b,c,d,e,f,g,h,a);
-	} while (j < 64);
-
-	/* Compute the current intermediate hash value */
-	context->state[0] += a;
-	context->state[1] += b;
-	context->state[2] += c;
-	context->state[3] += d;
-	context->state[4] += e;
-	context->state[5] += f;
-	context->state[6] += g;
-	context->state[7] += h;
-
-	/* Clean up */
-	a = b = c = d = e = f = g = h = T1 = 0;
-}
-
-#else /* SHA2_UNROLL_TRANSFORM */
-
-static void SHA256_Transform(SHA256_CTX* context, const uint32_t* data) {
-	uint32_t	a, b, c, d, e, f, g, h, s0, s1;
-	uint32_t	T1, T2, *W256;
-	int		j;
-
-	W256 = (uint32_t*)context->buffer;
-
-	/* Initialize registers with the prev. intermediate value */
-	a = context->state[0];
-	b = context->state[1];
-	c = context->state[2];
-	d = context->state[3];
-	e = context->state[4];
-	f = context->state[5];
-	g = context->state[6];
-	h = context->state[7];
-
-	j = 0;
-	do {
-#if BYTE_ORDER == LITTLE_ENDIAN
-		/* Copy data while converting to host byte order */
-		REVERSE32(*data++,W256[j]);
-		/* Apply the SHA-256 compression function to update a..h */
-		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-		/* Apply the SHA-256 compression function to update a..h with copy */
-		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-		T2 = Sigma0_256(a) + Maj(a, b, c);
-		h = g;
-		g = f;
-		f = e;
-		e = d + T1;
-		d = c;
-		c = b;
-		b = a;
-		a = T1 + T2;
-
-		j++;
-	} while (j < 16);
-
-	do {
-		/* Part of the message block expansion: */
-		s0 = W256[(j+1)&0x0f];
-		s0 = sigma0_256(s0);
-		s1 = W256[(j+14)&0x0f];
-		s1 = sigma1_256(s1);
-
-		/* Apply the SHA-256 compression function to update a..h */
-		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
-		     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
-		T2 = Sigma0_256(a) + Maj(a, b, c);
-		h = g;
-		g = f;
-		f = e;
-		e = d + T1;
-		d = c;
-		c = b;
-		b = a;
-		a = T1 + T2;
-
-		j++;
-	} while (j < 64);
-
-	/* Compute the current intermediate hash value */
-	context->state[0] += a;
-	context->state[1] += b;
-	context->state[2] += c;
-	context->state[3] += d;
-	context->state[4] += e;
-	context->state[5] += f;
-	context->state[6] += g;
-	context->state[7] += h;
-
-	/* Clean up */
-	a = b = c = d = e = f = g = h = T1 = T2 = 0;
-}
-
-#endif /* SHA2_UNROLL_TRANSFORM */
-
-static void SHA256_Update(SHA256_CTX* context, const uint8_t *data, size_t len) {
-	unsigned int	freespace, usedspace;
-
-	if (len == 0) {
-		/* Calling with no data is valid - we do nothing */
-		return;
-	}
-
-	/* Sanity check: */
-	assert(context != (SHA256_CTX*)0 && data != (uint8_t*)0);
-
-	usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
-	if (usedspace > 0) {
-		/* Calculate how much free space is available in the buffer */
-		freespace = SHA256_BLOCK_LENGTH - usedspace;
-
-		if (len >= freespace) {
-			/* Fill the buffer completely and process it */
-			MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
-			context->bitcount += freespace << 3;
-			len -= freespace;
-			data += freespace;
-			SHA256_Transform(context, (uint32_t*)context->buffer);
-		} else {
-			/* The buffer is not yet full */
-			MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
-			context->bitcount += len << 3;
-			/* Clean up: */
-			usedspace = freespace = 0;
-			return;
-		}
-	}
-	while (len >= SHA256_BLOCK_LENGTH) {
-		/* Process as many complete blocks as we can */
-		SHA256_Transform(context, (const uint32_t*)data);
-		context->bitcount += SHA256_BLOCK_LENGTH << 3;
-		len -= SHA256_BLOCK_LENGTH;
-		data += SHA256_BLOCK_LENGTH;
-	}
-	if (len > 0) {
-		/* There's left-overs, so save 'em */
-		MEMCPY_BCOPY(context->buffer, data, len);
-		context->bitcount += len << 3;
-	}
-	/* Clean up: */
-	usedspace = freespace = 0;
-}
-
-static void SHA256_Final(uint8_t digest[], SHA256_CTX* context) {
-	uint32_t	*d = (uint32_t*)digest;
-	unsigned int	usedspace;
-
-	/* Sanity check: */
-	assert(context != (SHA256_CTX*)0);
-
-	/* If no digest buffer is passed, we don't bother doing this: */
-	if (digest != (uint8_t*)0) {
-		usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
-#if BYTE_ORDER == LITTLE_ENDIAN
-		/* Convert FROM host byte order */
-		REVERSE64(context->bitcount,context->bitcount);
-#endif
-		if (usedspace > 0) {
-			/* Begin padding with a 1 bit: */
-			context->buffer[usedspace++] = 0x80;
-
-			if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
-				/* Set-up for the last transform: */
-				MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
-			} else {
-				if (usedspace < SHA256_BLOCK_LENGTH) {
-					MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
-				}
-				/* Do second-to-last transform: */
-				SHA256_Transform(context, (uint32_t*)context->buffer);
-
-				/* And set-up for the last transform: */
-				MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
-			}
-		} else {
-			/* Set-up for the last transform: */
-			MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
-
-			/* Begin padding with a 1 bit: */
-			*context->buffer = 0x80;
-		}
-		/* Set the bit count: */
-		//*(uint64_t*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; // aliasing violation warning
-    context->buffer64[SHA256_SHORT_BLOCK_LENGTH / sizeof(uint64_t)] = context->bitcount;
-
-		/* Final transform: */
-		SHA256_Transform(context, (uint32_t*)context->buffer);
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-		{
-			/* Convert TO host byte order */
-			int	j;
-			for (j = 0; j < 8; j++) {
-				REVERSE32(context->state[j],context->state[j]);
-				*d++ = context->state[j];
-			}
-		}
-#else
-		MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH);
-#endif
-	}
-
-	/* Clean up state data: */
-	MEMSET_BZERO(context, sizeof(*context));
-	usedspace = 0;
-}
-
-/*
-static char *SHA256_End(SHA256_CTX* context, char buffer[]) {
-	uint8_t	digest[SHA256_DIGEST_LENGTH], *d = digest;
-	int		i;
-
-	/ * Sanity check: * /
-	assert(context != (SHA256_CTX*)0);
-
-	if (buffer != (char*)0) {
-		SHA256_Final(digest, context);
-
-		for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
-			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
-			*buffer++ = sha2_hex_digits[*d & 0x0f];
-			d++;
-		}
-		*buffer = (char)0;
-	} else {
-		MEMSET_BZERO(context, sizeof(context));
-	}
-	MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
-	return buffer;
-}
-
-static char* SHA256_Data(const uint8_t* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) {
-	SHA256_CTX	context;
-
-	SHA256_Init(&context);
-	SHA256_Update(&context, data, len);
-	return SHA256_End(&context, digest);
-}
-*/
-
-
-/*** SHA-512: *********************************************************/
-static void SHA512_Init(SHA512_CTX* context) {
-	if (context == (SHA512_CTX*)0) {
-		return;
-	}
-	MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
-	MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH);
-	context->bitcount[0] = context->bitcount[1] =  0;
-}
-
-#ifdef SHA2_UNROLL_TRANSFORM
-
-/* Unrolled SHA-512 round macros: */
-#if BYTE_ORDER == LITTLE_ENDIAN
-
-#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
-	REVERSE64(*data++, W512[j]); \
-	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
-             K512[j] + W512[j]; \
-	(d) += T1, \
-	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
-	j++
-
-
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
-	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
-             K512[j] + (W512[j] = *data++); \
-	(d) += T1; \
-	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
-	j++
-
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND512(a,b,c,d,e,f,g,h)	\
-	s0 = W512[(j+1)&0x0f]; \
-	s0 = sigma0_512(s0); \
-	s1 = W512[(j+14)&0x0f]; \
-	s1 = sigma1_512(s1); \
-	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
-             (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
-	(d) += T1; \
-	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
-	j++
-
-static void SHA512_Transform(SHA512_CTX* context, const uint64_t* data) {
-	uint64_t	a, b, c, d, e, f, g, h, s0, s1;
-	uint64_t	T1, *W512 = (uint64_t*)context->buffer;
-	int		j;
-
-	/* Initialize registers with the prev. intermediate value */
-	a = context->state[0];
-	b = context->state[1];
-	c = context->state[2];
-	d = context->state[3];
-	e = context->state[4];
-	f = context->state[5];
-	g = context->state[6];
-	h = context->state[7];
-
-	j = 0;
-	do {
-		ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
-		ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
-		ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
-		ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
-		ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
-		ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
-		ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
-		ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
-	} while (j < 16);
-
-	/* Now for the remaining rounds up to 79: */
-	do {
-		ROUND512(a,b,c,d,e,f,g,h);
-		ROUND512(h,a,b,c,d,e,f,g);
-		ROUND512(g,h,a,b,c,d,e,f);
-		ROUND512(f,g,h,a,b,c,d,e);
-		ROUND512(e,f,g,h,a,b,c,d);
-		ROUND512(d,e,f,g,h,a,b,c);
-		ROUND512(c,d,e,f,g,h,a,b);
-		ROUND512(b,c,d,e,f,g,h,a);
-	} while (j < 80);
-
-	/* Compute the current intermediate hash value */
-	context->state[0] += a;
-	context->state[1] += b;
-	context->state[2] += c;
-	context->state[3] += d;
-	context->state[4] += e;
-	context->state[5] += f;
-	context->state[6] += g;
-	context->state[7] += h;
-
-	/* Clean up */
-	a = b = c = d = e = f = g = h = T1 = 0;
-}
-
-#else /* SHA2_UNROLL_TRANSFORM */
-
-static void SHA512_Transform(SHA512_CTX* context, const uint64_t* data) {
-	uint64_t	a, b, c, d, e, f, g, h, s0, s1;
-	uint64_t	T1, T2, *W512 = (uint64_t*)context->buffer;
-	int		j;
-
-	/* Initialize registers with the prev. intermediate value */
-	a = context->state[0];
-	b = context->state[1];
-	c = context->state[2];
-	d = context->state[3];
-	e = context->state[4];
-	f = context->state[5];
-	g = context->state[6];
-	h = context->state[7];
-
-	j = 0;
-	do {
-#if BYTE_ORDER == LITTLE_ENDIAN
-		/* Convert TO host byte order */
-		REVERSE64(*data++, W512[j]);
-		/* Apply the SHA-512 compression function to update a..h */
-		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-		/* Apply the SHA-512 compression function to update a..h with copy */
-		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-		T2 = Sigma0_512(a) + Maj(a, b, c);
-		h = g;
-		g = f;
-		f = e;
-		e = d + T1;
-		d = c;
-		c = b;
-		b = a;
-		a = T1 + T2;
-
-		j++;
-	} while (j < 16);
-
-	do {
-		/* Part of the message block expansion: */
-		s0 = W512[(j+1)&0x0f];
-		s0 = sigma0_512(s0);
-		s1 = W512[(j+14)&0x0f];
-		s1 =  sigma1_512(s1);
-
-		/* Apply the SHA-512 compression function to update a..h */
-		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
-		     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
-		T2 = Sigma0_512(a) + Maj(a, b, c);
-		h = g;
-		g = f;
-		f = e;
-		e = d + T1;
-		d = c;
-		c = b;
-		b = a;
-		a = T1 + T2;
-
-		j++;
-	} while (j < 80);
-
-	/* Compute the current intermediate hash value */
-	context->state[0] += a;
-	context->state[1] += b;
-	context->state[2] += c;
-	context->state[3] += d;
-	context->state[4] += e;
-	context->state[5] += f;
-	context->state[6] += g;
-	context->state[7] += h;
-
-	/* Clean up */
-	a = b = c = d = e = f = g = h = T1 = T2 = 0;
-}
-
-#endif /* SHA2_UNROLL_TRANSFORM */
-
-static void SHA512_Update(SHA512_CTX* context, const uint8_t *data, size_t len) {
-	unsigned int	freespace, usedspace;
-
-	if (len == 0) {
-		/* Calling with no data is valid - we do nothing */
-		return;
-	}
-
-	/* Sanity check: */
-	assert(context != (SHA512_CTX*)0 && data != (uint8_t*)0);
-
-	usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
-	if (usedspace > 0) {
-		/* Calculate how much free space is available in the buffer */
-		freespace = SHA512_BLOCK_LENGTH - usedspace;
-
-		if (len >= freespace) {
-			/* Fill the buffer completely and process it */
-			MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
-			ADDINC128(context->bitcount, freespace << 3);
-			len -= freespace;
-			data += freespace;
-			SHA512_Transform(context, (uint64_t*)context->buffer);
-		} else {
-			/* The buffer is not yet full */
-			MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
-			ADDINC128(context->bitcount, len << 3);
-			/* Clean up: */
-			usedspace = freespace = 0;
-			return;
-		}
-	}
-	while (len >= SHA512_BLOCK_LENGTH) {
-		/* Process as many complete blocks as we can */
-		SHA512_Transform(context, (const uint64_t*)data);
-		ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
-		len -= SHA512_BLOCK_LENGTH;
-		data += SHA512_BLOCK_LENGTH;
-	}
-	if (len > 0) {
-		/* There's left-overs, so save 'em */
-		MEMCPY_BCOPY(context->buffer, data, len);
-		ADDINC128(context->bitcount, len << 3);
-	}
-	/* Clean up: */
-	usedspace = freespace = 0;
-}
-
-static void SHA512_Last(SHA512_CTX* context) {
-	unsigned int	usedspace;
-
-	usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
-#if BYTE_ORDER == LITTLE_ENDIAN
-	/* Convert FROM host byte order */
-	REVERSE64(context->bitcount[0],context->bitcount[0]);
-	REVERSE64(context->bitcount[1],context->bitcount[1]);
-#endif
-	if (usedspace > 0) {
-		/* Begin padding with a 1 bit: */
-		context->buffer[usedspace++] = 0x80;
-
-		if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
-			/* Set-up for the last transform: */
-			MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
-		} else {
-			if (usedspace < SHA512_BLOCK_LENGTH) {
-				MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
-			}
-			/* Do second-to-last transform: */
-			SHA512_Transform(context, (uint64_t*)context->buffer);
-
-			/* And set-up for the last transform: */
-			MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2);
-		}
-	} else {
-		/* Prepare for final transform: */
-		MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
-
-		/* Begin padding with a 1 bit: */
-		*context->buffer = 0x80;
-	}
-	/* Store the length of input data (in bits): */
-	//*(uint64_t*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; // aliasing violation warning
-	//*(uint64_t*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];
-  context->buffer64[SHA512_SHORT_BLOCK_LENGTH / sizeof(uint64_t)] = context->bitcount[1];
-  context->buffer64[SHA512_SHORT_BLOCK_LENGTH / sizeof(uint64_t) + 1] = context->bitcount[0];
-
-	/* Final transform: */
-	SHA512_Transform(context, (uint64_t*)context->buffer);
-}
-
-static void SHA512_Final(uint8_t digest[], SHA512_CTX* context) {
-	uint64_t	*d = (uint64_t*)digest;
-
-	/* Sanity check: */
-	assert(context != (SHA512_CTX*)0);
-
-	/* If no digest buffer is passed, we don't bother doing this: */
-	if (digest != (uint8_t*)0) {
-		SHA512_Last(context);
-
-		/* Save the hash data for output: */
-#if BYTE_ORDER == LITTLE_ENDIAN
-		{
-			/* Convert TO host byte order */
-			int	j;
-			for (j = 0; j < 8; j++) {
-				REVERSE64(context->state[j],context->state[j]);
-				*d++ = context->state[j];
-			}
-		}
-#else
-		MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH);
-#endif
-	}
-
-	/* Zero out state data */
-	MEMSET_BZERO(context, sizeof(*context));
-}
-
-/*
-static char *SHA512_End(SHA512_CTX* context, char buffer[]) {
-	uint8_t	digest[SHA512_DIGEST_LENGTH], *d = digest;
-	int		i;
-
-	/ * Sanity check: * /
-	assert(context != (SHA512_CTX*)0);
-
-	if (buffer != (char*)0) {
-		SHA512_Final(digest, context);
-
-		for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
-			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
-			*buffer++ = sha2_hex_digits[*d & 0x0f];
-			d++;
-		}
-		*buffer = (char)0;
-	} else {
-		MEMSET_BZERO(context, sizeof(context));
-	}
-	MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
-	return buffer;
-}
-
-static char* SHA512_Data(const uint8_t* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) {
-	SHA512_CTX	context;
-
-	SHA512_Init(&context);
-	SHA512_Update(&context, data, len);
-	return SHA512_End(&context, digest);
-}
-*/
-
-/*** SHA-384: *********************************************************/
-static void SHA384_Init(SHA384_CTX* context) {
-	if (context == (SHA384_CTX*)0) {
-		return;
-	}
-	MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH);
-	MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH);
-	context->bitcount[0] = context->bitcount[1] = 0;
-}
-
-static void SHA384_Update(SHA384_CTX* context, const uint8_t* data, size_t len) {
-	SHA512_Update((SHA512_CTX*)context, data, len);
-}
-
-static void SHA384_Final(uint8_t digest[], SHA384_CTX* context) {
-	uint64_t	*d = (uint64_t*)digest;
-
-	/* Sanity check: */
-	assert(context != (SHA384_CTX*)0);
-
-	/* If no digest buffer is passed, we don't bother doing this: */
-	if (digest != (uint8_t*)0) {
-		SHA512_Last((SHA512_CTX*)context);
-
-		/* Save the hash data for output: */
-#if BYTE_ORDER == LITTLE_ENDIAN
-		{
-			/* Convert TO host byte order */
-			int	j;
-			for (j = 0; j < 6; j++) {
-				REVERSE64(context->state[j],context->state[j]);
-				*d++ = context->state[j];
-			}
-		}
-#else
-		MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH);
-#endif
-	}
-
-	/* Zero out state data */
-	MEMSET_BZERO(context, sizeof(*context));
-}
-
-/*
-static char *SHA384_End(SHA384_CTX* context, char buffer[]) {
-	uint8_t	digest[SHA384_DIGEST_LENGTH], *d = digest;
-	int		i;
-
-	/ * Sanity check: * /
-	assert(context != (SHA384_CTX*)0);
-
-	if (buffer != (char*)0) {
-		SHA384_Final(digest, context);
-
-		for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
-			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];
-			*buffer++ = sha2_hex_digits[*d & 0x0f];
-			d++;
-		}
-		*buffer = (char)0;
-	} else {
-		MEMSET_BZERO(context, sizeof(context));
-	}
-	MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
-	return buffer;
-}
-
-static char* SHA384_Data(const uint8_t* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) {
-	SHA384_CTX	context;
-
-	SHA384_Init(&context);
-	SHA384_Update(&context, data, len);
-	return SHA384_End(&context, digest);
-}
-*/
-
-/* end of sha2.c */
-
-void sha256_init (sha256_state *state)
-{
-  SHA256_Init(state);
-}
-
-void sha384_init (sha384_state *state)
-{
-  SHA384_Init(state);
-}
-
-void sha512_init (sha512_state *state)
-{
-  SHA512_Init(state);
-}
-
-
-void sha256_add (sha256_state *state, const void *data, size_t size)
-{
-  SHA256_Update(state, (const uint8_t *)data, size);
-}
-
-void sha384_add (sha384_state *state, const void *data, size_t size)
-{
-  SHA384_Update(state, (const uint8_t *)data, size);
-}
-
-void sha512_add (sha512_state *state, const void *data, size_t size)
-{
-  SHA512_Update(state, (const uint8_t *)data, size);
-}
-
-
-void sha256_put (sha256_state *state, uint8_t digest[SHA256_DIGEST_LENGTH])
-{
-  SHA256_Final(digest, state);
-}
-
-void sha384_put (sha384_state *state, uint8_t digest[SHA384_DIGEST_LENGTH])
-{
-  SHA384_Final(digest, state);
-}
-
-void sha512_put (sha384_state *state, uint8_t digest[SHA512_DIGEST_LENGTH])
-{
-  SHA512_Final(digest, state);
-}
-
-
-void sha256 (const void *data, size_t size, uint8_t digest[SHA256_DIGEST_LENGTH])
-{
-  sha256_state state;
-  SHA256_Init(&state);
-  SHA256_Update(&state, (const uint8_t *)data, size);
-  SHA256_Final(digest, &state);
-}
-
-void sha384 (const void *data, size_t size, uint8_t digest[SHA384_DIGEST_LENGTH])
-{
-  sha384_state state;
-  SHA384_Init(&state);
-  SHA384_Update(&state, (const uint8_t *)data, size);
-  SHA384_Final(digest, &state);
-}
-
-void sha512 (const void *data, size_t size, uint8_t digest[SHA512_DIGEST_LENGTH])
-{
-  sha512_state state;
-  SHA512_Init(&state);
-  SHA512_Update(&state, (const uint8_t *)data, size);
-  SHA512_Final(digest, &state);
-}
-
-static sha256_state sha256state;
-static sha384_state sha384state;
-static sha512_state sha512state;
-
-
-void sha256init (void)
-{
-  SHA256_Init(&sha256state);
-}
-
-void sha384init (void)
-{
-  SHA384_Init(&sha384state);
-}
-
-void sha512init (void)
-{
-  SHA512_Init(&sha512state);
-}
-
-
-void sha256add (const void *data, size_t size)
-{
-  SHA256_Update(&sha256state, (const uint8_t *)data, size);
-}
-
-void sha384add (const void *data, size_t size)
-{
-  SHA384_Update(&sha384state, (const uint8_t *)data, size);
-}
-
-void sha512add (const void *data, size_t size)
-{
-  SHA512_Update(&sha512state, (const uint8_t *)data, size);
-}
-
-
-void sha256put (uint8_t digest[SHA256_DIGEST_LENGTH])
-{
-  SHA256_Final(digest, &sha256state);
-}
-
-void sha384put (uint8_t digest[SHA384_DIGEST_LENGTH])
-{
-  SHA384_Final(digest, &sha384state);
-}
-
-void sha512put (uint8_t digest[SHA512_DIGEST_LENGTH])
-{
-  SHA512_Final(digest, &sha512state);
-}



More information about the tex-live-commits mailing list