about summary refs log tree commit diff
path: root/converter/other/jbig/libjbig
diff options
context:
space:
mode:
Diffstat (limited to 'converter/other/jbig/libjbig')
-rw-r--r--converter/other/jbig/libjbig/ANNOUNCE172
-rw-r--r--converter/other/jbig/libjbig/COPYING339
-rw-r--r--converter/other/jbig/libjbig/Makefile24
-rw-r--r--converter/other/jbig/libjbig/include/jbig.h233
-rw-r--r--converter/other/jbig/libjbig/include/jbig_ar.h53
-rw-r--r--converter/other/jbig/libjbig/jbig.c3285
-rw-r--r--converter/other/jbig/libjbig/jbig.txt810
-rw-r--r--converter/other/jbig/libjbig/jbig_ar.c417
8 files changed, 5333 insertions, 0 deletions
diff --git a/converter/other/jbig/libjbig/ANNOUNCE b/converter/other/jbig/libjbig/ANNOUNCE
new file mode 100644
index 00000000..15ce550d
--- /dev/null
+++ b/converter/other/jbig/libjbig/ANNOUNCE
@@ -0,0 +1,172 @@
+
+JBIG-KIT lossless image compression library
+-------------------------------------------
+
+by Markus Kuhn
+
+
+The latest release of JBIG-KIT can be downloaded from
+
+  http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+
+JBIG-KIT implements a highly effective data compression algorithm for
+bi-level high-resolution images such as fax pages or scanned
+documents.
+
+JBIG-KIT provides two variants of a portable library of compression
+and decompression functions with a documented interface. You can very
+easily include into your image or document processing software. In
+addition, JBIG-KIT provides ready-to-use compression and decompression
+programs with a simple command line interface (similar to the
+converters found in Jef Poskanzer's PBM graphics file conversion
+package).
+
+JBIG-KIT implements the specification
+
+  International Standard ISO/IEC 11544:1993 and ITU-T Recommendation
+  T.82(1993), "Information technology - Coded representation of picture
+  and audio information - progressive bi-level image compression",
+  <http://www.itu.int/rec/T-REC-T.82>,
+
+which is commonly referred to as the "JBIG1 standard". JBIG (Joint
+Bi-level Image experts Group) is the committee which developed this
+international standard for the lossless compression of images using
+arithmetic coding. Like the well-known compression algorithms JPEG and
+MPEG, JBIG has also been developed and published by the International
+Organization for Standardization (ISO) and the International
+Telecommunication Union (ITU). See also
+
+  http://www.jpeg.org/jbig/
+  http://www.iso.ch/
+  http://www.itu.int/
+
+The JBIG compression algorithm offers the following features:
+
+  - Close to state-of-the-art lossless compression ratio for high
+    resolution bi-level images.
+
+  - About 1.1 to 1.5 times better compression ratio on typical
+    scanned documents compared to G4 fax compression (ITU-T T.6),
+    which has been the best compression algorithm for scanned
+    documents available prior to JBIG.
+
+  - Up to 30 times better compression of scanned images with dithered
+    images compared to G4 fax compression.
+
+  - About 2 times better compression on typical 300 dpi documents
+    compared to 'gzip -9' on raw bitmaps.
+    
+  - About 3-4 times better compression than GIF on typical 300 dpi
+    documents.
+
+  - Even much better competitive compression results on computer
+    generated images which are free of scanning distortions.
+
+  - JBIG supports hierarchical "progressive" encoding, that means it is
+    possible to encode a low resolution image first, followed by
+    resolution enhancement data. This allows, for instance, a document
+    browser to display already a good 75 dpi low resolution version of
+    an image, while the data necessary to reconstruct the full 300 dpi
+    version for laser printer reproduction is still arriving (say
+    over a slow network link or mass storage medium).
+
+  - The various resolution layers of a JBIG image in progressive
+    encoding mode together require not much more space than a
+    normal non-progressive mode encoded image (which JBIG also
+    supports).
+
+  - The progressive encoding mode utilizes a quite sophisticated
+    resolution reduction algorithm which offers high quality low
+    resolution versions that preserve the shape of characters as well
+    as the integrity of thin lines and dithered images.
+
+  - JBIG supports multiple bit planes and can this way also be used
+    for grayscale and color images, although the main field of
+    application is compression of bi-level images, i.e. images with
+    only two different pixel values. For grayscale images with up to
+    6 bit per pixel, JBIG performs superior to JPEG's lossless
+    mode.
+
+JBIG-KIT can be used as free software under the GNU General Public
+License. Other license arrangements more suitable for commercial
+applications are available as well, please contact the author for
+details. JBIG-KIT provides two portable libraries implemented in
+ANSI/ISO C for encoding and decoding JBIG data streams, along with
+documentation. The first library, jbig.c, implements nearly all of the
+options that the JBIG standard provides, but keeps the entire
+uncompressed image in memory. The second library, jbig85.c, implements
+only the ITU-R T.85 subset of the standard that black/white fax
+machines use (single bit per pixel, no "progressive" encoding), and
+keeps only three lines of the uncompressed image in memory, making it
+particularly attractive for low-memory embedded applications.
+
+The libraries are not intended for 8-bit or 16-bit machine
+architectures (e.g., old MS-DOS C compilers). For maximum performance,
+a 32-bit processor is required (64-bit systems work too, of course).
+On architectures with 16-bit pointer arithmetic, the full-featured
+jbig.c library can process only very small images.
+
+Special features of the full-featured jbig.c variant:
+
+  - Fully reentrant multithread-capable design (no global or static
+    variables, isolated malloc()/free() calls, etc.)
+
+  - Capable of handling incomplete and growing JBIG data streams in
+    order to allow earliest display of low resolution versions
+
+  - Capable of handling several incoming data streams simultaneously
+    in one single process and thread
+
+  - Especially designed with applications in mind that want to display
+    incoming data as early as possible (e.g., similar to the way in
+    which Netscape Navigator handles incoming GIF images)
+
+  - Implements all JBIG features and options including progressive and
+    sequential encoding, multiple bit planes, user specified
+    resolution reduction and deterministic prediction tables, adaptive
+    template changes for optimal performance on half-tone images,
+    deterministic prediction, typical prediction in lowest and
+    differential layers, various stripe orderings, etc; only the SEQ
+    and HITOLO options are currently not supported by the decoder
+    (they are normally never required, but could be added later in
+    case of user requirements)
+
+  - Suitable for fax applications, satisfies ITU-T T.85 profile
+
+  - Efficient code, optimized utilization of 32-bit processor
+    registers
+
+  - Very easy to use documented C library interface
+
+  - Included Gray code conversion routines for efficient encoding
+    of grayscale images
+
+  - Ready-to-use pbmtojbg and jbgtopbm converters.
+
+Special features of the light-weight jbig85.c variant:
+
+  - Suitable for low-memory embedded applications
+
+  - Implements only the JBIG1 subset defined in the ITU-T T.85
+    profile (single bit plane, no differential layers)
+
+  - Requires only three pixel rows of the uncompressed image to be
+    kept in memory
+
+  - Handles all NEWLEN modes of operation required by ITU-T T.85 with
+    just a single pass over the data, automatically performing the
+    necessary lookahead after the last stripe
+
+  - Codec buffers only a few bytes of arithmetic-codec data and outputs
+    resulting bytes or lines as soon as they are available.
+
+I will try to provide free support and maintenance for this software
+for the foreseeable future, depending on my available time.
+
+Happy compressing ...
+
+Markus Kuhn
+
+--
+Markus Kuhn, Computer Laboratory, University of Cambridge
+http://www.cl.cam.ac.uk/~mgk25/ || CB3 0FD, Great Britain
diff --git a/converter/other/jbig/libjbig/COPYING b/converter/other/jbig/libjbig/COPYING
new file mode 100644
index 00000000..a43ea212
--- /dev/null
+++ b/converter/other/jbig/libjbig/COPYING
@@ -0,0 +1,339 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                          675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/converter/other/jbig/libjbig/Makefile b/converter/other/jbig/libjbig/Makefile
new file mode 100644
index 00000000..2e574903
--- /dev/null
+++ b/converter/other/jbig/libjbig/Makefile
@@ -0,0 +1,24 @@
+ifeq ($(SRCDIR)x,x)
+  SRCDIR = $(CURDIR)/../../../..
+  BUILDDIR = $(SRCDIR)
+endif
+SUBDIR = converter/other/jbig/libjbig
+VPATH=.:$(SRCDIR)/$(SUBDIR)
+
+include $(BUILDDIR)/config.mk
+
+LIBJBIG_OBJECTS = jbig.o jbig_ar.o
+
+OBJECTS = $(LIBJBIG_OBJECTS)
+MERGE_OBJECTS = $(LIBJBIG_OBJECTS)
+
+COMP_INCLUDES = -I$(SRCDIR)/$(SUBDIR)/include
+
+all: libjbig.a
+
+include $(SRCDIR)/common.mk
+
+libjbig.a: $(LIBJBIG_OBJECTS)
+	$(AR) -rc $@ $^
+	$(RANLIB) $@
+
diff --git a/converter/other/jbig/libjbig/include/jbig.h b/converter/other/jbig/libjbig/include/jbig.h
new file mode 100644
index 00000000..67994107
--- /dev/null
+++ b/converter/other/jbig/libjbig/include/jbig.h
@@ -0,0 +1,233 @@
+/*
+ *  Header file for the portable JBIG compression library
+ *
+ *  Copyright 1995-2014 -- Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/
+ */
+
+#ifndef JBG_H
+#define JBG_H
+
+#include <stddef.h>
+#include "jbig_ar.h"
+
+/*
+ * JBIG-KIT version number
+ */
+
+#define JBG_VERSION    "2.1"
+#define JBG_VERSION_MAJOR 2
+#define JBG_VERSION_MINOR 1
+
+/*
+ * JBIG-KIT licence agreement reference code:
+ * If you use JBIG-KIT under a commercial licence, please replace
+ * below the letters GPL with the reference code that you received
+ * with your licence agreement. (This code is typically a letter "A"
+ * followed by four decimal digits, e.g. "A1234".)
+ */
+
+#define JBG_LICENCE    "GPL"
+
+/*
+ * Buffer block for SDEs which are temporarily stored by encoder
+ */
+
+#define JBG_BUFSIZE 4000
+
+struct jbg_buf {
+  unsigned char d[JBG_BUFSIZE];              /* one block of a buffer list */
+  int len;                             /* length of the data in this block */
+  struct jbg_buf *next;                           /* pointer to next block */
+  struct jbg_buf *previous;                   /* pointer to previous block *
+					       * (unused in freelist)      */
+  struct jbg_buf *last;     /* only used in list head: final block of list */
+  struct jbg_buf **free_list;   /* pointer to pointer to head of free list */
+};
+
+/*
+ * Maximum number of ATMOVEs per stripe that decoder can handle
+ */
+
+#define JBG_ATMOVES_MAX  64
+
+/*
+ * Option and order flags
+ */
+
+#define JBG_HITOLO     0x08
+#define JBG_SEQ        0x04
+#define JBG_ILEAVE     0x02
+#define JBG_SMID       0x01
+
+#define JBG_LRLTWO     0x40
+#define JBG_VLENGTH    0x20
+#define JBG_TPDON      0x10
+#define JBG_TPBON      0x08
+#define JBG_DPON       0x04
+#define JBG_DPPRIV     0x02
+#define JBG_DPLAST     0x01
+
+/* encoding options that will not be indicated in the header */
+
+#define JBG_DELAY_AT   0x100  /* Delay ATMOVE until the first line of the next
+			       * stripe. Option available for compatibility
+			       * with conformance test example in clause 7.2. */
+
+#define JBG_SDRST      0x200  /* Use SDRST instead of SDNORM. This option is
+			       * there for anyone who needs to generate
+			       * test data that covers the SDRST cases. */
+
+/*
+ * Possible error code return values
+ */
+
+#define JBG_EOK        (0 << 4)
+#define JBG_EOK_INTR   (1 << 4)
+#define JBG_EAGAIN     (2 << 4)
+#define JBG_ENOMEM     (3 << 4)
+#define JBG_EABORT     (4 << 4)
+#define JBG_EMARKER    (5 << 4)
+#define JBG_EINVAL     (6 << 4)
+#define JBG_EIMPL      (7 << 4)
+#define JBG_ENOCONT    (8 << 4)
+
+/*
+ * Status of a JBIG encoder
+ */
+
+struct jbg_enc_state {
+  int d;                            /* resolution layer of the input image */
+  unsigned long xd, yd;    /* size of the input image (resolution layer d) */
+  unsigned long yd1;    /* BIH announced height of image, use yd1 != yd to
+                        emulate T.85-style NEWLEN height updates for tests */
+  int planes;                         /* number of different bitmap planes */
+  int dl;                       /* lowest resolution layer in the next BIE */
+  int dh;                      /* highest resolution layer in the next BIE */
+  unsigned long l0;                /* number of lines per stripe at lowest *
+                                    * resolution layer 0                   */
+  unsigned long stripes;    /* number of stripes required  (determ. by l0) */
+  unsigned char **lhp[2];    /* pointers to lower/higher resolution images */
+  int *highres;                 /* index [plane] of highres image in lhp[] */
+  int order;                                    /* SDE ordering parameters */
+  int options;                                      /* encoding parameters */
+  unsigned mx, my;                           /* maximum ATMOVE window size */
+  int *tx;       /* array [plane] with x-offset of adaptive template pixel */
+  char *dppriv;         /* optional private deterministic prediction table */
+  char *res_tab;           /* table for the resolution reduction algorithm */
+  struct jbg_buf ****sde;      /* array [stripe][layer][plane] pointers to *
+				* buffers for stored SDEs                  */
+  struct jbg_arenc_state *s;  /* array [planes] for arithm. encoder status */
+  struct jbg_buf *free_list; /* list of currently unused SDE block buffers */
+  void (*data_out)(unsigned char *start, size_t len, void *file);
+                                                    /* data write callback */
+  void *file;                            /* parameter passed to data_out() */
+  char *tp;    /* buffer for temp. values used by diff. typical prediction */
+  unsigned char *comment; /* content of comment marker segment to be added
+                             at next opportunity (will be reset to NULL
+                             as soon as comment has been written)          */
+  unsigned long comment_len;       /* length of data pointed to by comment */
+};
+
+
+/*
+ * Status of a JBIG decoder
+ */
+
+struct jbg_dec_state {
+  /* data from BIH */
+  int d;                             /* resolution layer of the full image */
+  int dl;                            /* first resolution layer in this BIE */
+  unsigned long xd, yd;     /* size of the full image (resolution layer d) */
+  int planes;                         /* number of different bitmap planes */
+  unsigned long l0;                /* number of lines per stripe at lowest *
+				    * resolution layer 0                   */
+  unsigned long stripes;    /* number of stripes required  (determ. by l0) */
+  int order;                                    /* SDE ordering parameters */
+  int options;                                      /* encoding parameters */
+  int mx, my;                                /* maximum ATMOVE window size */
+  char *dppriv;         /* optional private deterministic prediction table */
+
+  /* loop variables */
+  unsigned long ii[3];  /* current stripe, layer, plane (outer loop first) */
+
+  /*
+   * Pointers to array [planes] of lower/higher resolution images.
+   * lhp[d & 1] contains image of layer d. 
+   */
+  unsigned char **lhp[2];
+
+  /* status information */
+  int **tx, **ty;   /* array [plane][layer-dl] with x,y-offset of AT pixel */
+  struct jbg_ardec_state **s;    /* array [plane][layer-dl] for arithmetic *
+				  * decoder status */
+  int **reset;     /* array [plane][layer-dl] remembers if previous stripe *
+		    * in that plane/resolution ended with SDRST.           */
+  unsigned long bie_len;                    /* number of bytes read so far */
+  unsigned char buffer[20]; /* used to store BIH or marker segments fragm. */
+  int buf_len;                                /* number of bytes in buffer */
+  unsigned long comment_skip;      /* remaining bytes of a COMMENT segment */
+  unsigned long x;              /* x position of next pixel in current SDE */
+  unsigned long i; /* line in current SDE (first line of each stripe is 0) */ 
+  int at_moves;                /* number of AT moves in the current stripe */
+  unsigned long at_line[JBG_ATMOVES_MAX];           /* lines at which an   *
+					             * AT move will happen */
+  int at_tx[JBG_ATMOVES_MAX], at_ty[JBG_ATMOVES_MAX]; /* ATMOVE offsets in *
+						       * current stripe    */
+  unsigned long line_h1, line_h2, line_h3;     /* variables of decode_pscd */
+  unsigned long line_l1, line_l2, line_l3;
+  int pseudo;         /* flag for TPBON/TPDON:  next pixel is pseudo pixel */
+  int **lntp;        /* flag [plane][layer-dl] for TP: line is not typical */
+
+  unsigned long xmax, ymax;         /* if possible abort before image gets *
+				     * larger than this size */
+  int dmax;                                      /* abort after this layer */
+};
+
+
+/* some macros (too trivial for a function) */
+
+#define jbg_dec_getplanes(s)     ((s)->planes)
+
+
+/* function prototypes */
+
+void jbg_enc_init(struct jbg_enc_state *s, unsigned long x, unsigned long y,
+		  int planes, unsigned char **p,
+		  void (*data_out)(unsigned char *start, size_t len,
+				   void *file),
+		  void *file);
+int jbg_enc_lrlmax(struct jbg_enc_state *s, unsigned long mwidth,
+		   unsigned long mheight);
+void jbg_enc_layers(struct jbg_enc_state *s, int d);
+int  jbg_enc_lrange(struct jbg_enc_state *s, int dl, int dh);
+void jbg_enc_options(struct jbg_enc_state *s, int order, int options,
+		     unsigned long l0, int mx, int my);
+void jbg_enc_out(struct jbg_enc_state *s);
+void jbg_enc_free(struct jbg_enc_state *s);
+
+void jbg_dec_init(struct jbg_dec_state *s);
+void jbg_dec_maxsize(struct jbg_dec_state *s, unsigned long xmax,
+		     unsigned long ymax);
+int  jbg_dec_in(struct jbg_dec_state *s, unsigned char *data, size_t len,
+		size_t *cnt);
+unsigned long jbg_dec_getwidth(const struct jbg_dec_state *s);
+unsigned long jbg_dec_getheight(const struct jbg_dec_state *s);
+unsigned char *jbg_dec_getimage(const struct jbg_dec_state *s, int plane);
+unsigned long jbg_dec_getsize(const struct jbg_dec_state *s);
+void jbg_dec_merge_planes(const struct jbg_dec_state *s, int use_graycode,
+			  void (*data_out)(unsigned char *start, size_t len,
+					   void *file), void *file);
+unsigned long jbg_dec_getsize_merged(const struct jbg_dec_state *s);
+void jbg_dec_free(struct jbg_dec_state *s);
+
+const char *jbg_strerror(int errnum);
+void jbg_int2dppriv(unsigned char *dptable, const char *internal);
+void jbg_dppriv2int(char *internal, const unsigned char *dptable);
+unsigned long jbg_ceil_half(unsigned long x, int n);
+void jbg_split_planes(unsigned long x, unsigned long y, int has_planes,
+		      int encode_planes,
+		      const unsigned char *src, unsigned char **dest,
+		      int use_graycode);
+int jbg_newlen(unsigned char *bie, size_t len);
+
+#endif /* JBG_H */
diff --git a/converter/other/jbig/libjbig/include/jbig_ar.h b/converter/other/jbig/libjbig/include/jbig_ar.h
new file mode 100644
index 00000000..d58b1ae0
--- /dev/null
+++ b/converter/other/jbig/libjbig/include/jbig_ar.h
@@ -0,0 +1,53 @@
+/*
+ *  Header file for the arithmetic encoder and decoder of
+ *  the portable JBIG compression library
+ *
+ *  Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+ */
+
+#ifndef JBG_AR_H
+#define JBG_AR_H
+
+/*
+ * Status of arithmetic encoder
+ */
+
+struct jbg_arenc_state {
+  unsigned char st[4096];    /* probability status for contexts, MSB = MPS */
+  unsigned long c;                /* register C: base of coding intervall, *
+                                   * layout as in Table 23                 */
+  unsigned long a;       /* register A: normalized size of coding interval */
+  long sc;     /* number of buffered 0xff values that might still overflow */
+  int ct;  /* bit shift counter, determines when next byte will be written */
+  int buffer;                /* buffer for most recent output byte != 0xff */
+  void (*byte_out)(int, void *);  /* function that receives all PSCD bytes */
+  void *file;                              /* parameter passed to byte_out */
+};
+
+/*
+ * Status of arithmetic decoder
+ */
+
+struct jbg_ardec_state {
+  unsigned char st[4096];    /* probability status for contexts, MSB = MPS */
+  unsigned long c;                /* register C: base of coding intervall, *
+                                   * layout as in Table 25                 */
+  unsigned long a;       /* register A: normalized size of coding interval */
+  unsigned char *pscd_ptr;               /* pointer to next PSCD data byte */
+  unsigned char *pscd_end;                   /* pointer to byte after PSCD */
+  int ct;    /* bit-shift counter, determines when next byte will be read;
+              * special value -1 signals that zero-padding has started     */
+  int startup;          /* boolean flag that controls initial fill of s->c */
+  int nopadding;        /* boolean flag that triggers return -2 between
+			 * reaching PSCD end and decoding the first symbol
+			 * that might never have been encoded in the first
+			 * place */
+};
+
+void arith_encode_init(struct jbg_arenc_state *s, int reuse_st);
+void arith_encode_flush(struct jbg_arenc_state *s);
+void arith_encode(struct jbg_arenc_state *s, int cx, int pix);
+void arith_decode_init(struct jbg_ardec_state *s, int reuse_st);
+int  arith_decode(struct jbg_ardec_state *s, int cx);
+
+#endif /* JBG_AR_H */
diff --git a/converter/other/jbig/libjbig/jbig.c b/converter/other/jbig/libjbig/jbig.c
new file mode 100644
index 00000000..d7141a75
--- /dev/null
+++ b/converter/other/jbig/libjbig/jbig.c
@@ -0,0 +1,3285 @@
+/*
+ *  Portable JBIG image compression library
+ *
+ *  Copyright 1995-2014 -- Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/
+ *
+ *  This module implements a portable standard C encoder and decoder
+ *  using the JBIG1 lossless bi-level image compression algorithm
+ *  specified in International Standard ISO 11544:1993 and
+ *  ITU-T Recommendation T.82. See the file jbig.txt for usage
+ *  instructions and application examples.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 
+ *  If you want to use this program under different license conditions,
+ *  then contact the author for an arrangement.
+ */
+
+#ifdef DEBUG
+#include <stdio.h>
+#else
+#define NDEBUG
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "jbig.h"
+
+#define MX_MAX  127
+   /* maximal mx offset for adaptive template in the encoder */
+
+#define TPB2CX  0x195  /* contexts for TP special pixels */
+#define TPB3CX  0x0e5
+#define TPDCX   0xc3f
+
+/* marker codes */
+#define MARKER_STUFF    0x00
+#define MARKER_RESERVE  0x01
+#define MARKER_SDNORM   0x02
+#define MARKER_SDRST    0x03
+#define MARKER_ABORT    0x04
+#define MARKER_NEWLEN   0x05
+#define MARKER_ATMOVE   0x06
+#define MARKER_COMMENT  0x07
+#define MARKER_ESC      0xff
+
+/* loop array indices */
+#define STRIPE  0
+#define LAYER   1
+#define PLANE   2
+
+/* special jbg_buf pointers (instead of NULL) */
+#define SDE_DONE ((struct jbg_buf *) -1)
+#define SDE_TODO ((struct jbg_buf *) 0)
+
+/* object code version id */
+
+const char jbg_version[] = 
+  "JBIG-KIT " JBG_VERSION " -- (c) 1995-2014 Markus Kuhn -- "
+  "Licence: " JBG_LICENCE "\n";
+
+/*
+ * The following array specifies for each combination of the 3
+ * ordering bits, which ii[] variable represents which dimension
+ * of s->sde.
+ */
+static const int iindex[8][3] = {
+  { 2, 1, 0 },    /* no ordering bit set */
+  { -1, -1, -1},  /* SMID -> illegal combination */
+  { 2, 0, 1 },    /* ILEAVE */
+  { 1, 0, 2 },    /* SMID + ILEAVE */
+  { 0, 2, 1 },    /* SEQ */
+  { 1, 2, 0 },    /* SEQ + SMID */
+  { 0, 1, 2 },    /* SEQ + ILEAVE */
+  { -1, -1, -1 }  /* SEQ + SMID + ILEAVE -> illegal combination */
+};
+
+#define _(String) String  /* to mark translatable string for GNU gettext */
+
+/*
+ * Array with English ASCII error messages that correspond
+ * to return values from public functions in this library.
+ */
+static const char *errmsg[] = {
+  _("All OK"),                                               /* JBG_EOK */
+  _("Reached specified image size"),                         /* JBG_EOK_INTR */
+  _("Unexpected end of input data stream"),                  /* JBG_EAGAIN */
+  _("Not enough memory available"),                          /* JBG_ENOMEM */
+  _("ABORT marker segment encountered"),                     /* JBG_EABORT */
+  _("Unknown marker segment encountered"),                   /* JBG_EMARKER */
+  _("Input data stream contains invalid data"),              /* JBG_EINVAL */
+  _("Input data stream uses unimplemented JBIG features"),   /* JBG_EIMPL */
+  _("Incremental BIE does not continue previous one")        /* JBG_ENOCONT */
+};
+
+
+/*
+ * The following three functions are the only places in this code, were
+ * C library memory management functions are called. The whole JBIG
+ * library has been designed in order to allow multi-threaded
+ * execution. No static or global variables are used, so all fuctions
+ * are fully reentrant. However if you want to use this multi-thread
+ * capability and your malloc, realloc and free are not reentrant,
+ * then simply add the necessary semaphores or mutex primitives below.
+ * In contrast to C's malloc() and realloc(), but like C's calloc(),
+ * these functions take two parameters nmemb and size that are multiplied
+ * before being passed on to the corresponding C function. 
+ * This we can catch all overflows during a size_t multiplication a
+ * a single place.
+ */
+
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t) -1)     /* largest value of size_t */
+#endif
+
+static void *checked_malloc(size_t nmemb, size_t size)
+{
+  void *p;
+
+  /* Full manual exception handling is ugly here for performance
+   * reasons. If an adequate handling of lack of memory is required,
+   * then use C++ and throw a C++ exception instead of abort(). */
+
+  /* assert that nmemb * size <= SIZE_MAX */
+  if (size > SIZE_MAX / nmemb)
+    abort();
+  
+  p = malloc(nmemb * size);
+
+  if (!p)
+    abort();
+
+#if 0
+  fprintf(stderr, "%p = malloc(%lu * %lu)\n", p,
+	  (unsigned long) nmemb, (unsigned long) size);
+#endif
+
+  return p;
+}
+
+
+static void *checked_realloc(void *ptr, size_t nmemb, size_t size)
+{
+  void *p;
+
+  /* Full manual exception handling is ugly here for performance
+   * reasons. If an adequate handling of lack of memory is required,
+   * then use C++ and throw a C++ exception here instead of abort(). */
+
+  /* assert that nmemb * size <= SIZE_MAX */
+  if (size > SIZE_MAX / nmemb)
+    abort();
+  
+  p = realloc(ptr, nmemb * size);
+
+  if (!p)
+    abort();
+
+#if 0
+  fprintf(stderr, "%p = realloc(%p, %lu * %lu)\n", p, ptr,
+	  (unsigned long) nmemb, (unsigned long) size);
+#endif
+
+  return p;
+}
+
+
+static void checked_free(void *ptr)
+{
+  free(ptr);
+
+#if 0
+  fprintf(stderr, "free(%p)\n", ptr);
+#endif
+
+}
+
+
+
+
+/*
+ * Memory management for buffers which are used for temporarily
+ * storing SDEs by the encoder.
+ *
+ * The following functions manage a set of struct jbg_buf storage
+ * containers were each can keep JBG_BUFSIZE bytes. The jbg_buf
+ * containers can be linked to form linear double-chained lists for
+ * which a number of operations are provided. Blocks which are
+ * tempoarily not used any more are returned to a freelist which each
+ * encoder keeps. Only the destructor of the encoder actually returns
+ * the block via checked_free() to the stdlib memory management.
+ */
+
+
+/*
+ * Allocate a new buffer block and initialize it. Try to get it from
+ * the free_list, and if it is empty, call checked_malloc().
+ */
+static struct jbg_buf *jbg_buf_init(struct jbg_buf **free_list)
+{
+  struct jbg_buf *new_block;
+  
+  /* Test whether a block from the free list is available */
+  if (*free_list) {
+    new_block = *free_list;
+    *free_list = new_block->next;
+  } else {
+    /* request a new memory block */
+    new_block = (struct jbg_buf *) checked_malloc(1, sizeof(struct jbg_buf));
+  }
+  new_block->len = 0;
+  new_block->next = NULL;
+  new_block->previous = NULL;
+  new_block->last = new_block;
+  new_block->free_list = free_list;
+
+  return new_block;
+}
+
+
+/*
+ * Return an entire free_list to the memory management of stdlib.
+ * This is only done by jbg_enc_free().
+ */
+static void jbg_buf_free(struct jbg_buf **free_list)
+{
+  struct jbg_buf *tmp;
+  
+  while (*free_list) {
+    tmp = (*free_list)->next;
+    checked_free(*free_list);
+    *free_list = tmp;
+  }
+  
+  return;
+}
+
+
+/*
+ * Append a single byte to a single list that starts with the block
+ * *(struct jbg_buf *) head. The type of *head is void here in order to
+ * keep the interface of the arithmetic encoder gereric, which uses this
+ * function as a call-back function in order to deliver single bytes
+ * for a PSCD.
+ */
+static void jbg_buf_write(int b, void *head)
+{
+  struct jbg_buf *now;
+
+  now = ((struct jbg_buf *) head)->last;
+  if (now->len < JBG_BUFSIZE - 1) {
+    now->d[now->len++] = b;
+    return;
+  }
+  now->next = jbg_buf_init(((struct jbg_buf *) head)->free_list);
+  now->next->previous = now;
+  now->next->d[now->next->len++] = b;
+  ((struct jbg_buf *) head)->last = now->next;
+
+  return;
+}
+
+
+/*
+ * Remove any trailing zero bytes from the end of a linked jbg_buf list,
+ * however make sure that no zero byte is removed which directly
+ * follows a 0xff byte (i.e., keep MARKER_ESC MARKER_STUFF sequences
+ * intact). This function is used to remove any redundant final zero
+ * bytes from a PSCD.
+ */
+static void jbg_buf_remove_zeros(struct jbg_buf *head)
+{
+  struct jbg_buf *last;
+
+  while (1) {
+    /* remove trailing 0x00 in last block of list until this block is empty */
+    last = head->last;
+    while (last->len && last->d[last->len - 1] == 0)
+      last->len--;
+    /* if block became really empty, remove it in case it is not the
+     * only remaining block and then loop to next block */
+    if (last->previous && !last->len) {
+      head->last->next = *head->free_list;
+      *head->free_list = head->last;
+      head->last = last->previous;
+      head->last->next = NULL;
+    } else
+      break;
+  }
+
+  /*
+   * If the final non-zero byte is 0xff (MARKER_ESC), then we just have
+   * removed a MARKER_STUFF and we will append it again now in order
+   * to preserve PSCD status of byte stream.
+   */
+  if (head->last->len && head->last->d[head->last->len - 1] == MARKER_ESC)
+    jbg_buf_write(MARKER_STUFF, head);
+ 
+  return;
+}
+
+
+/*
+ * The jbg_buf list which starts with block *new_prefix is concatenated
+ * with the list which starts with block **start and *start will then point
+ * to the first block of the new list.
+ */
+static void jbg_buf_prefix(struct jbg_buf *new_prefix, struct jbg_buf **start)
+{
+  new_prefix->last->next = *start;
+  new_prefix->last->next->previous = new_prefix->last;
+  new_prefix->last = new_prefix->last->next->last;
+  *start = new_prefix;
+  
+  return;
+}
+
+
+/*
+ * Send the contents of a jbg_buf list that starts with block **head to
+ * the call back function data_out and return the blocks of the jbg_buf
+ * list to the freelist from which these jbg_buf blocks have been taken.
+ * After the call, *head == NULL.
+ */
+static void jbg_buf_output(struct jbg_buf **head,
+			void (*data_out)(unsigned char *start,
+					 size_t len, void *file),
+			void *file)
+{
+  struct jbg_buf *tmp;
+  
+  while (*head) {
+    data_out((*head)->d, (*head)->len, file);
+    tmp = (*head)->next;
+    (*head)->next = *(*head)->free_list;
+    *(*head)->free_list = *head;
+    *head = tmp;
+  }
+  
+  return;
+}
+
+
+/*
+ * Calculate y = ceil(x/2) applied n times, which is equivalent to
+ * y = ceil(x/(2^n)). This function is used to
+ * determine the number of pixels per row or column after n resolution
+ * reductions. E.g. X[d-1] = jbg_ceil_half(X[d], 1) and X[0] =
+ * jbg_ceil_half(X[d], d) as defined in clause 6.2.3 of T.82.
+ */
+unsigned long jbg_ceil_half(unsigned long x, int n)
+{
+  unsigned long mask;
+  
+  assert(n >= 0 && n < 32);
+  mask = (1UL << n) - 1;     /* the lowest n bits are 1 here */
+  return (x >> n) + ((mask & x) != 0);
+}
+
+
+/*
+ * Set L0 (the number of lines in a stripe at lowest resolution)
+ * to a default value, such that there are about 35 stripes, as
+ * suggested in Annex C of ITU-T T.82, without exceeding the
+ * limit 128/2^D suggested in Annex A.
+ */
+static void jbg_set_default_l0(struct jbg_enc_state *s)
+{
+  s->l0 = jbg_ceil_half(s->yd, s->d) / 35;   /* 35 stripes/image */
+  while ((s->l0 << s->d) > 128)              /* but <= 128 lines/stripe */
+    --s->l0;
+  if (s->l0 < 2) s->l0 = 2;
+}
+
+
+/*
+ * Calculate the number of stripes, as defined in clause 6.2.3 of T.82.
+ */
+static unsigned long jbg_stripes(unsigned long l0, unsigned long yd,
+			  unsigned long d)
+{
+  unsigned long y0 = jbg_ceil_half(yd, d);
+
+  return y0 / l0 + (y0 % l0 != 0);
+}
+
+
+/*
+ * Resolution reduction table given by ITU-T T.82 Table 17
+ */
+
+static char jbg_resred[4096] = {
+  0,0,0,1,0,0,0,1,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,1,1,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,
+  0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,1,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,
+  0,0,1,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,
+  0,1,1,1,1,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,
+  0,0,1,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,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
+  0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
+  0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,0,1,1,1,1,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,
+  0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,1,0,0,1,1,1,0,1,1,
+  0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,1,1,0,1,1,0,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,1,0,0,1,1,0,1,1,0,1,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,1,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
+  1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,
+  0,0,1,1,0,0,0,1,0,0,0,1,0,0,1,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,1,1,1,1,1,0,1,1,1,0,
+  0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,
+  0,0,0,1,0,0,0,1,0,1,1,0,1,0,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,
+  1,1,1,0,1,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
+  1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,
+  0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,1,0,1,0,0,1,0,0,1,1,0,1,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,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,1,1,1,1,0,1,1,
+  1,0,0,1,0,0,1,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,
+  0,0,1,0,1,1,1,1,0,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,
+  0,0,0,0,1,0,0,1,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,1,1,0,1,1,0,1,1,0,1,1,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,1,1,1,0,1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,
+  0,0,1,0,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1,
+  0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,1,0,0,1,0,0,1,1,
+  0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,1,0,1,0,1,
+  0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,
+  0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,1,0,1,0,1,1,0,0,0,1,0,0,1,1,
+  0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,1,1,0,0,1,1,
+  0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,1,
+  0,0,1,0,0,1,1,1,0,0,0,0,1,0,0,1,0,0,0,1,1,1,1,0,1,0,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,1,0,
+  0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,1,1,0,1,1,1,
+  0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,1,1,0,1,0,0,0,1,1,0,1,0,0,0,0,1,1,1,1,0,0,1,1,1,0,1,1,0,0,1,1,
+  0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,1,0,0,0,1,0,1,1,1,1,0,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,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
+  0,0,0,1,0,0,1,0,1,1,1,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,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
+  0,0,1,1,1,1,1,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,
+  0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
+  0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+  0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,
+  0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,1,1,0,1,1,
+  0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,1,1,1,0,1,1,1,
+  0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,
+  0,0,0,0,1,0,0,1,0,0,1,1,0,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,
+  1,0,1,0,1,0,0,1,1,0,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,0,1,1,0,1,1,1,
+  0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,0,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,1,0,1,0,1,0,1,1,0,1,0,1,0,0,0,1,1,1,1,1,1,1,1,1,
+  1,1,1,0,1,0,0,0,1,1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
+  1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,1,1,0,1,1,
+  0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0,0,1,1,0,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,1,0,1,0,0,0,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
+  1,0,0,0,1,0,0,0,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,0,1,1,0,
+  0,0,1,1,1,1,1,1,0,0,0,0,1,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,1,1,1,1,
+  0,0,0,0,1,0,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+  0,0,1,0,1,0,1,1,0,0,1,0,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,
+  0,0,1,0,1,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,0,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1,
+  0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,
+  0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,1,0,1,0,1,
+  0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,
+  0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,1,
+  0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1,
+  0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,
+  1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,
+  0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1,
+  0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,
+  0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,
+  0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,1,0,1,1,1,1,1,1,1,
+  0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,
+  0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,1,1,0,0,0,1,0,1,1,1,0,1,1,1
+};
+
+/*
+ * Deterministic prediction tables given by ITU-T T.82 tables
+ * 19 to 22. The table below is organized differently, the
+ * index bits are permutated for higher efficiency.
+ */
+
+static char jbg_dptable[256 + 512 + 2048 + 4096] = {
+  /* phase 0: offset=0 */
+  0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,0,2,2,2,2,2,2,2,
+  0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,0,2,0,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  /* phase 1: offset=256 */
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,0,2,0,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  0,2,2,2,2,1,2,1,2,2,2,2,1,1,1,1,2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,2,
+  0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,2,2,2,2,0,2,2,2,2,2,2,2,
+  0,2,0,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,0,0,2,2,2,2,2,0,0,2,2,2,2,2,
+  0,2,2,2,2,1,2,1,2,2,2,2,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,
+  1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,1,1,2,2,2,2,2,0,2,2,2,2,2,2,
+  2,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,0,2,0,2,2,2,2,2,0,2,2,2,2,2,2,2,
+  0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,2,
+  2,2,2,2,2,1,1,1,2,2,2,2,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,0,1,2,0,2,0,2,2,2,2,2,0,2,0,2,2,2,2,1,
+  0,2,0,2,2,1,2,1,2,2,2,2,1,1,1,1,0,0,0,0,2,2,2,2,0,2,0,2,2,2,2,1,
+  2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,0,0,0,2,2,2,2,2,
+  2,2,2,2,2,1,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,1,2,1,2,2,2,2,1,
+  2,2,2,2,2,2,2,2,0,2,0,2,2,1,2,2,2,2,2,2,2,2,2,2,0,0,0,2,2,2,2,2,
+  /* phase 2: offset=768 */
+  2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1,
+  0,2,2,2,2,1,2,1,2,2,2,2,1,2,1,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,
+  2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,1,2,1,2,2,2,2,2,1,1,1,
+  2,0,2,2,2,1,2,1,0,2,2,2,1,2,1,2,2,2,2,0,2,2,2,2,0,2,0,2,2,2,2,2,
+  0,2,0,0,1,1,1,1,2,2,2,2,1,1,1,1,0,2,0,2,1,1,1,1,2,2,2,2,1,1,1,1,
+  2,2,0,2,2,2,1,2,2,2,2,2,1,2,1,2,2,2,0,2,2,1,2,1,0,2,0,2,1,1,1,1,
+  2,0,0,2,2,2,2,2,0,2,0,2,2,0,2,0,2,0,2,0,2,2,2,1,2,2,0,2,1,1,2,1,
+  2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1,
+  0,0,0,0,2,2,2,2,0,0,0,0,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,0,2,2,2,2,1,0,2,2,2,1,1,1,1,2,0,2,2,2,2,2,2,0,2,0,2,2,1,2,1,
+  2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,
+  0,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,
+  2,2,0,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,2,2,1,2,1,0,2,2,2,1,1,1,1,
+  2,2,2,0,2,2,2,2,2,2,0,2,2,0,2,0,2,1,2,2,2,2,2,2,1,2,1,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,1,
+  0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,1,1,1,2,2,2,2,1,1,1,1,
+  2,2,2,1,2,2,2,2,2,2,1,2,0,0,0,0,2,2,0,2,2,1,2,2,2,2,2,2,1,1,1,1,
+  2,0,0,0,2,2,2,2,0,2,2,2,2,2,2,0,2,2,2,0,2,2,2,2,2,0,0,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,0,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,1,
+  0,2,0,2,2,1,1,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,
+  2,0,2,0,2,1,2,1,0,2,0,2,2,2,1,2,2,0,2,0,2,2,2,2,0,2,0,2,2,2,1,2,
+  2,2,2,0,2,2,2,2,2,2,0,2,2,2,2,2,2,2,1,2,2,2,2,2,2,0,1,2,2,2,2,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+  0,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,
+  2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,1,2,1,0,2,2,2,1,1,1,1,
+  2,0,2,0,2,1,2,2,0,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,1,2,2,
+  2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,2,1,2,1,
+  2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,0,0,2,2,2,1,2,2,2,
+  0,0,2,0,2,2,2,2,0,2,0,2,2,0,2,0,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,
+  2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,1,
+  2,2,0,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1,
+  0,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,
+  2,0,0,2,2,2,2,2,0,2,0,2,2,2,2,2,1,0,1,2,2,2,2,1,0,2,2,2,1,1,1,1,
+  2,2,2,2,2,2,2,2,2,2,0,2,2,0,2,0,2,1,2,2,2,2,2,2,2,2,0,2,2,1,2,2,
+  0,2,0,0,1,1,1,1,0,2,2,2,1,1,1,1,2,2,2,2,2,2,2,2,2,0,2,2,1,2,1,1,
+  2,2,0,2,2,1,2,2,2,2,2,2,1,2,2,2,2,0,2,2,2,2,2,2,0,2,0,2,1,2,1,1,
+  2,0,2,0,2,2,2,2,0,2,0,2,2,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,
+  2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+  0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  0,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,2,2,2,2,2,1,1,2,2,2,2,2,1,2,2,2,
+  2,0,2,2,2,1,2,1,0,2,2,2,2,2,1,2,2,0,2,0,2,2,2,2,0,2,0,2,2,1,2,2,
+  0,2,0,0,2,2,2,2,1,2,2,2,2,2,2,0,2,1,2,2,2,2,2,2,1,2,2,2,2,2,2,2,
+  0,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,1,0,2,2,
+  0,0,0,2,2,1,1,1,2,2,2,2,1,2,2,2,2,0,2,0,2,2,2,1,2,2,2,2,1,2,1,2,
+  0,0,0,0,2,2,2,2,2,2,0,2,2,1,2,2,2,1,2,1,2,2,2,2,1,2,1,2,0,2,2,2,
+  2,0,2,0,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+  0,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,1,2,2,2,2,2,0,2,2,1,2,2,0,0,0,2,2,2,2,2,1,2,2,0,2,2,2,1,2,1,2,
+  2,0,2,0,2,2,2,2,0,2,0,2,2,1,2,2,0,2,0,0,2,2,2,2,2,2,2,2,2,1,2,2,
+  2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,1,
+  1,2,0,2,2,1,2,1,2,2,2,2,1,2,2,2,2,0,2,0,2,2,2,2,2,0,2,2,1,1,1,1,
+  0,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,1,2,1,
+  2,2,0,0,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,
+  2,2,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,
+  2,0,2,0,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,1,0,2,0,2,2,2,1,2,
+  2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+  2,0,2,0,2,2,2,2,2,0,2,0,2,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,2,1,2,1,
+  2,2,2,2,2,1,2,1,0,2,0,2,2,2,2,2,2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,1,
+  2,0,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,0,
+  2,0,2,0,2,2,2,1,2,2,2,0,2,2,2,1,2,0,2,0,2,2,2,2,0,0,0,2,2,2,2,1,
+  2,0,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,
+  /* phase 3: offset=2816 */
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,
+  0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,0,2,2,2,1,2,0,2,2,2,1,2,2,2,2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,
+  2,2,2,1,2,2,2,0,1,1,1,1,0,0,0,0,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,0,0,0,1,1,1,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,
+  2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,2,0,2,0,2,1,2,1,
+  2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,
+  2,0,2,2,2,1,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,0,2,0,1,1,2,1,
+  2,2,2,0,2,2,2,1,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,
+  0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,
+  2,0,0,2,2,1,1,2,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,1,1,1,2,0,0,0,
+  2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,2,2,2,0,2,2,2,1,2,0,2,0,2,1,2,1,
+  2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,
+  2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,
+  0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,
+  2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,0,2,0,2,1,2,1,0,0,2,0,1,1,2,1,
+  2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,0,0,0,2,1,1,1,
+  2,2,2,1,2,2,2,0,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,
+  2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+  2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,
+  2,0,2,2,2,1,2,2,0,0,2,0,1,1,2,1,2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,
+  2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,0,0,0,1,1,1,1,
+  2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,2,1,0,2,2,0,1,2,
+  2,2,2,1,2,2,2,0,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+  2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+  0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,
+  2,1,2,1,2,0,2,0,1,2,1,1,0,2,0,0,0,0,2,1,1,1,2,0,0,0,0,0,1,1,1,1,
+  2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,0,2,1,2,1,2,0,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,0,2,2,2,1,2,2,2,0,0,2,2,1,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,
+  0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,
+  2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,0,0,0,0,1,1,1,1,
+  2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,0,0,0,2,1,1,1,
+  2,2,2,0,2,2,2,1,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+  2,0,2,2,2,1,2,2,2,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+  2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,1,2,1,2,0,2,0,1,2,1,1,0,2,0,0,2,0,2,2,2,1,2,2,0,2,1,2,1,2,0,2,
+  2,2,2,1,2,2,2,0,2,2,1,2,2,2,0,2,2,1,2,2,2,0,2,2,2,2,0,2,2,2,1,2,
+  0,0,2,0,1,1,2,1,0,0,1,0,1,1,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,0,2,2,2,1,1,2,2,2,0,2,2,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,
+  2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+  2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,0,0,2,2,1,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,
+  0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,
+  2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,2,2,1,2,2,2,0,2,1,2,1,2,0,2,0,
+  2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1,2,0,0,0,2,1,1,1,
+  2,2,2,2,2,2,2,2,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,1,2,1,2,0,2,0,2,0,2,2,2,1,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,1,1,1,2,0,0,0,
+  2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1,
+  2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,
+  2,1,2,1,2,0,2,0,2,1,2,2,2,0,2,2,2,2,2,0,2,2,2,1,2,0,2,0,2,1,2,1,
+  2,0,2,0,2,1,2,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+  2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,0,1,0,0,1,0,1,1,
+  2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,1,2,2,1,0,2,0,2,2,2,1,2,2,2,
+  2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,
+  2,0,2,0,2,1,2,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+  0,2,0,0,1,2,1,1,2,0,0,0,2,1,1,1,2,2,2,2,2,2,2,2,1,0,1,2,0,1,0,2,
+  2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,1,2,2,2,0,2,2,1,1,2,2,0,0,2,2,
+  0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,1,2,1,2,0,2,0,2,1,2,2,2,0,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,
+  0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,1,2,2,2,0,2,2,2,
+  2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,2,
+  0,0,0,0,1,1,1,1,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,2,0,2,2,2,1,2,
+  2,0,2,0,2,1,2,1,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,
+  0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,1,2,2,2,0,1,1,2,1,0,0,2,0,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,0,2,2,2,1,2,
+  2,0,2,0,2,1,2,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,
+  0,2,0,0,1,2,1,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1,2,
+  2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+  2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,0,2,1,1,1,2,0,0,2,2,2,1,2,2,2,
+  2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1,
+  0,0,2,2,1,1,2,2,0,2,1,2,1,2,0,2,2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,
+  2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,
+  2,2,0,0,2,2,1,1,2,2,0,0,2,2,1,1,2,2,2,2,2,2,2,2,2,2,0,0,2,2,1,1,
+  2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1,
+  2,2,2,0,2,2,2,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,1,1,1,2,0,0,0,2,
+  2,2,2,2,2,2,2,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,
+  2,0,2,0,2,1,2,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1,
+  2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,2,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,
+  2,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,0,2,0,2,1,2,1,2,1,2,0,2,0,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,0,2,0,2,1,2,1,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,
+  2,0,2,1,2,1,2,0,0,2,1,2,1,2,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+  2,0,2,0,2,1,2,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,
+  2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,1,2,1,2,0,2,0,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+  2,0,2,0,2,1,2,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+};
+
+
+/*
+ * Initialize the status struct for the encoder.
+ */
+void jbg_enc_init(struct jbg_enc_state *s, unsigned long x, unsigned long y,
+                  int planes, unsigned char **p,
+                  void (*data_out)(unsigned char *start, size_t len,
+				   void *file),
+		  void *file)
+{
+  unsigned long l, lx;
+  int i;
+
+  assert(x > 0 && y > 0 && planes > 0 && planes < 256);
+  s->xd = x;
+  s->yd = y;
+  s->yd1 = y; /* This is the hight initially announced in BIH. To provoke
+                 generation of NEWLEN for T.85 compatibility tests,
+                 overwrite with new value s->yd1 > s->yd  */
+  s->planes = planes;
+  s->data_out = data_out;
+  s->file = file;
+
+  s->d = 0;
+  s->dl = 0;
+  s->dh = s->d;
+  jbg_set_default_l0(s);
+  s->mx = 8;
+  s->my = 0;
+  s->order = JBG_ILEAVE | JBG_SMID;
+  s->options = JBG_TPBON | JBG_TPDON | JBG_DPON;
+  s->comment = NULL;
+  s->dppriv = jbg_dptable;
+  s->res_tab = jbg_resred;
+  
+  s->highres = (int *) checked_malloc(planes, sizeof(int));
+  s->lhp[0] = p;
+  s->lhp[1] = (unsigned char **)
+    checked_malloc(planes, sizeof(unsigned char *));
+  for (i = 0; i < planes; i++) {
+    s->highres[i] = 0;
+    s->lhp[1][i] = (unsigned char *)
+      checked_malloc(jbg_ceil_half(y, 1), jbg_ceil_half(x, 1+3));
+  }
+  
+  s->free_list = NULL;
+  s->s = (struct jbg_arenc_state *) 
+    checked_malloc(s->planes, sizeof(struct jbg_arenc_state));
+  s->tx = (int *) checked_malloc(s->planes, sizeof(int));
+  lx = jbg_ceil_half(x, 1);
+  s->tp = (char *) checked_malloc(lx, sizeof(char));
+  for (l = 0; l < lx; s->tp[l++] = 2) ;
+  s->sde = NULL;
+
+  return;
+}
+
+
+/*
+ * This function selects the number of differential layers based on
+ * the maximum size requested for the lowest resolution layer. If
+ * possible, a number of differential layers is selected, which will
+ * keep the size of the lowest resolution layer below or equal to the
+ * given width x and height y. However not more than 6 differential
+ * resolution layers will be used. In addition, a reasonable value for
+ * l0 (height of one stripe in the lowest resolution layer) is
+ * selected, which obeys the recommended limitations for l0 in annex A
+ * and C of the JBIG standard. The selected number of resolution layers
+ * is returned. 
+ */
+int jbg_enc_lrlmax(struct jbg_enc_state *s, unsigned long x, 
+		   unsigned long y)
+{
+  for (s->d = 0; s->d < 6; s->d++)
+    if (jbg_ceil_half(s->xd, s->d) <= x && jbg_ceil_half(s->yd, s->d) <= y)
+      break;
+  s->dl = 0;
+  s->dh = s->d;
+  jbg_set_default_l0(s);
+  return s->d;
+}
+
+
+/*
+ * As an alternative to jbg_enc_lrlmax(), the following function allows
+ * to specify the number of layers directly. The stripe height and layer
+ * range is also adjusted automatically here.
+ */
+void jbg_enc_layers(struct jbg_enc_state *s, int d)
+{
+  if (d < 0 || d > 31)
+    return;
+  s->d  = d;
+  s->dl = 0;
+  s->dh = s->d;
+  jbg_set_default_l0(s);
+  return;
+}
+
+
+/*
+ * Specify the highest and lowest resolution layers which will be
+ * written to the output file. Call this function not before
+ * jbg_enc_layers() or jbg_enc_lrlmax(), because these two functions
+ * reset the lowest and highest resolution layer to default values.
+ * Negative values are ignored. The total number of layers is returned.
+ */
+int jbg_enc_lrange(struct jbg_enc_state *s, int dl, int dh)
+{
+  if (dl >= 0     && dl <= s->d) s->dl = dl;
+  if (dh >= s->dl && dh <= s->d) s->dh = dh;
+
+  return s->d;
+}
+
+
+/*
+ * The following function allows to specify the bits describing the
+ * options of the format as well as the maximum AT movement window and
+ * the number of layer 0 lines per stripes.
+ */
+void jbg_enc_options(struct jbg_enc_state *s, int order, int options,
+		     unsigned long l0, int mx, int my)
+{
+  if (order >= 0 && order <= 0x0f) s->order = order;
+  if (options >= 0) s->options = options;
+  if (l0 > 0) s->l0 = l0;
+  if (mx >= 0 && mx < 128) s->mx = mx;
+  if (my >= 0 && my < 256) s->my = my;
+
+  return;
+}
+
+
+/*
+ * This function actually does all the tricky work involved in producing
+ * a SDE, which is stored in the appropriate s->sde[][][] element
+ * for later output in the correct order.
+ */
+static void encode_sde(struct jbg_enc_state *s,
+		       long stripe, int layer, int plane)
+{
+  unsigned char *hp, *lp1, *lp2, *p0, *p1, *q1, *q2;
+  unsigned long hl, ll, hx, hy, lx, ly, hbpl, lbpl;
+  unsigned long line_h0 = 0, line_h1 = 0;
+  unsigned long line_h2, line_h3, line_l1, line_l2, line_l3;
+  struct jbg_arenc_state *se;
+  unsigned long y;  /* current line number in highres image */
+  unsigned long i;  /* current line number within highres stripe */
+  unsigned long j;  /* current column number in highres image */
+  long o;
+  unsigned a, p, t;
+  int ltp, ltp_old, cx;
+  unsigned long c_all, c[MX_MAX + 1], cmin, cmax, clmin, clmax;
+  int tmax, at_determined;
+  int new_tx;
+  long new_tx_line = -1;
+  int reset;
+  struct jbg_buf *new_jbg_buf;
+
+#ifdef DEBUG
+  static long tp_lines, tp_exceptions, tp_pixels, dp_pixels;
+  static long encoded_pixels;
+#endif
+
+  /* return immediately if this stripe has already been encoded */
+  if (s->sde[stripe][layer][plane] != SDE_TODO)
+    return;
+
+#ifdef DEBUG
+  if (stripe == 0)
+    tp_lines = tp_exceptions = tp_pixels = dp_pixels = encoded_pixels = 0;
+  fprintf(stderr, "encode_sde: s/d/p = %2ld/%2d/%2d\n",
+	  stripe, layer, plane);
+#endif
+
+  /* number of lines per stripe in highres image */
+  hl = s->l0 << layer;
+  /* number of lines per stripe in lowres image */
+  ll = hl >> 1;
+  /* current line number in highres image */
+  y = stripe * hl;
+  /* number of pixels in highres image */
+  hx = jbg_ceil_half(s->xd, s->d - layer);
+  hy = jbg_ceil_half(s->yd, s->d - layer);
+  /* number of pixels in lowres image */
+  lx = jbg_ceil_half(hx, 1);
+  ly = jbg_ceil_half(hy, 1);
+  /* bytes per line in highres and lowres image */
+  hbpl = jbg_ceil_half(hx, 3);
+  lbpl = jbg_ceil_half(lx, 3);
+  /* pointer to first image byte of highres stripe */
+  hp = s->lhp[s->highres[plane]][plane] + stripe * hl * hbpl;
+  lp2 = s->lhp[1 - s->highres[plane]][plane] + stripe * ll * lbpl;
+  lp1 = lp2 + lbpl;
+  
+  /* check whether we can refer to any state of a previous stripe */
+  reset = (stripe == 0) || (s->options & JBG_SDRST);
+
+  /* initialize arithmetic encoder */
+  se = s->s + plane;
+  arith_encode_init(se, !reset);
+  s->sde[stripe][layer][plane] = jbg_buf_init(&s->free_list);
+  se->byte_out = jbg_buf_write;
+  se->file = s->sde[stripe][layer][plane];
+
+  /* initialize adaptive template movement algorithm */
+  c_all = 0;
+  for (t = 0; t <= s->mx; t++)
+    c[t] = 0;
+  if (stripe == 0)    /* the SDRST case is handled at the end */
+    s->tx[plane] = 0;
+  new_tx = -1;
+  at_determined = 0;  /* we haven't yet decided the template move */
+  if (s->mx == 0)
+    at_determined = 1;
+
+  /* initialize typical prediction */
+  ltp = 0;
+  if (reset)
+    ltp_old = 0;
+  else {
+    ltp_old = 1;
+    p1 = hp - hbpl;
+    if (y > 1) {
+      q1 = p1 - hbpl;
+      while (p1 < hp && (ltp_old = (*p1++ == *q1++)) != 0) ;
+    } else
+      while (p1 < hp && (ltp_old = (*p1++ == 0)) != 0) ;
+  }
+
+  if (layer == 0) {
+
+    /*
+     *  Encode lowest resolution layer
+     */
+
+    for (i = 0; i < hl && y < hy; i++, y++) {
+
+      /* check whether it is worth to perform an ATMOVE */
+      if (!at_determined && c_all > 2048) {
+	cmin = clmin = 0xffffffffL;
+	cmax = clmax = 0;
+	tmax = 0;
+	for (t = (s->options & JBG_LRLTWO) ? 5 : 3; t <= s->mx; t++) {
+	  if (c[t] > cmax) cmax = c[t];
+	  if (c[t] < cmin) cmin = c[t];
+	  if (c[t] > c[tmax]) tmax = t;
+	}
+	clmin = (c[0] < cmin) ? c[0] : cmin;
+	clmax = (c[0] > cmax) ? c[0] : cmax;
+	if (c_all - cmax < (c_all >> 3) &&
+	    cmax - c[s->tx[plane]] > c_all - cmax &&
+	    cmax - c[s->tx[plane]] > (c_all >> 4) &&
+	    /*                     ^ T.82 said < here, fixed in Cor.1/25 */
+	    cmax - (c_all - c[s->tx[plane]]) > c_all - cmax &&
+	    cmax - (c_all - c[s->tx[plane]]) > (c_all >> 4) &&
+	    cmax - cmin > (c_all >> 2) &&
+	    (s->tx[plane] || clmax - clmin > (c_all >> 3))) {
+	  /* we have decided to perform an ATMOVE */
+	  new_tx = tmax;
+	  if (!(s->options & JBG_DELAY_AT)) {
+	    new_tx_line = i;
+	    s->tx[plane] = new_tx;
+	  }
+#ifdef DEBUG
+	  fprintf(stderr, "ATMOVE: line=%ld, tx=%d, c_all=%ld\n",
+		  i, new_tx, c_all);
+#endif
+	}
+	at_determined = 1;
+      }
+      assert(s->tx[plane] >= 0); /* i.e., tx can safely be cast to unsigned */
+      
+      /* typical prediction */
+      if (s->options & JBG_TPBON) {
+	ltp = 1;
+	p1 = hp;
+	if (i > 0 || !reset) {
+	  q1 = hp - hbpl;
+	  while (q1 < hp && (ltp = (*p1++ == *q1++)) != 0) ;
+	} else
+	  while (p1 < hp + hbpl && (ltp = (*p1++ == 0)) != 0) ;
+	arith_encode(se, (s->options & JBG_LRLTWO) ? TPB2CX : TPB3CX,
+		     ltp == ltp_old);
+#ifdef DEBUG
+	tp_lines += ltp;
+#endif
+	ltp_old = ltp;
+	if (ltp) {
+	  /* skip next line */
+	  hp += hbpl;
+	  continue;
+	}
+      }
+
+      /*
+       * Layout of the variables line_h1, line_h2, line_h3, which contain
+       * as bits the neighbour pixels of the currently coded pixel X:
+       *
+       *          76543210765432107654321076543210     line_h3
+       *          76543210765432107654321076543210     line_h2
+       *  76543210765432107654321X76543210             line_h1
+       */
+      
+      line_h1 = line_h2 = line_h3 = 0;
+      if (i > 0 || !reset) line_h2 = (long)*(hp - hbpl) << 8;
+      if (i > 1 || !reset) line_h3 = (long)*(hp - hbpl - hbpl) << 8;
+      
+      /* encode line */
+      for (j = 0; j < hx; hp++) {
+	line_h1 |= *hp;
+	if (j < hbpl * 8 - 8 && (i > 0 || !reset)) {
+	  line_h2 |= *(hp - hbpl + 1);
+	  if (i > 1 || !reset)
+	    line_h3 |= *(hp - hbpl - hbpl + 1);
+	}
+	if (s->options & JBG_LRLTWO) {
+	  /* two line template */
+	  do {
+	    line_h1 <<= 1;  line_h2 <<= 1;  line_h3 <<= 1;
+	    if (s->tx[plane]) {
+	      if ((unsigned) s->tx[plane] > j)
+		a = 0;
+	      else {
+		o = (j - s->tx[plane]) - (j & ~7L);
+		a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+		a <<= 4;
+	      }
+	      assert(s->tx[plane] > 23 ||
+		     a == ((line_h1 >> (4 + s->tx[plane])) & 0x010));
+	      arith_encode(se, (((line_h2 >> 10) & 0x3e0) | a |
+				((line_h1 >>  9) & 0x00f)),
+			   (line_h1 >> 8) & 1);
+	    }
+	    else
+	      arith_encode(se, (((line_h2 >> 10) & 0x3f0) |
+				((line_h1 >>  9) & 0x00f)),
+			   (line_h1 >> 8) & 1);
+#ifdef DEBUG
+	    encoded_pixels++;
+#endif
+	    /* statistics for adaptive template changes */
+	    if (!at_determined && j >= s->mx && j < hx-2) {
+	      p = (line_h1 & 0x100) != 0; /* current pixel value */
+	      c[0] += ((line_h2 & 0x4000) != 0) == p; /* default position */
+	      assert(!(((line_h2 >> 6) ^ line_h1) & 0x100) ==
+		     (((line_h2 & 0x4000) != 0) == p));
+	      for (t = 5; t <= s->mx && t <= j; t++) {
+		o = (j - t) - (j & ~7L);
+		a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+		assert(t > 23 ||
+		       (a == p) == !(((line_h1 >> t) ^ line_h1) & 0x100));
+		c[t] += a == p;
+	      }
+	      for (; t <= s->mx; t++) {
+		c[t] += 0 == p;
+	      }
+	      ++c_all;
+	    }
+	  } while (++j & 7 && j < hx);
+	} else {
+	  /* three line template */
+	  do {
+	    line_h1 <<= 1;  line_h2 <<= 1;  line_h3 <<= 1;
+	    if (s->tx[plane]) {
+	      if ((unsigned) s->tx[plane] > j)
+		a = 0;
+	      else {
+		o = (j - s->tx[plane]) - (j & ~7L);
+		a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+		a <<= 2;
+	      }
+	      assert(s->tx[plane] > 23 ||
+		     a == ((line_h1 >> (6 + s->tx[plane])) & 0x004));
+	      arith_encode(se, (((line_h3 >>  8) & 0x380) |
+				((line_h2 >> 12) & 0x078) | a |
+				((line_h1 >>  9) & 0x003)),
+			   (line_h1 >> 8) & 1);
+	    } else
+	      arith_encode(se, (((line_h3 >>  8) & 0x380) |
+				((line_h2 >> 12) & 0x07c) |
+				((line_h1 >>  9) & 0x003)),
+			   (line_h1 >> 8) & 1);
+#ifdef DEBUG
+	    encoded_pixels++;
+#endif
+	    /* statistics for adaptive template changes */
+	    if (!at_determined && j >= s->mx && j < hx-2) {
+	      p = (line_h1 & 0x100) != 0; /* current pixel value */
+	      c[0] += ((line_h2 & 0x4000) != 0) == p; /* default position */
+	      assert(!(((line_h2 >> 6) ^ line_h1) & 0x100) ==
+		     (((line_h2 & 0x4000) != 0) == p));
+	      for (t = 3; t <= s->mx && t <= j; t++) {
+		o = (j - t) - (j & ~7L);
+		a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+		assert(t > 23 ||
+		       (a == p) == !(((line_h1 >> t) ^ line_h1) & 0x100));
+		c[t] += a == p;
+	      }
+	      for (; t <= s->mx; t++) {
+		c[t] += 0 == p;
+	      }
+	      ++c_all;
+	    }
+	  } while (++j & 7 && j < hx);
+	} /* if (s->options & JBG_LRLTWO) */
+      } /* for (j = ...) */
+    } /* for (i = ...) */
+
+  } else {
+
+    /*
+     *  Encode differential layer
+     */
+    
+    for (i = 0; i < hl && y < hy; i++, y++) {
+
+      /* check whether it is worth to perform an ATMOVE */
+      if (!at_determined && c_all > 2048) {
+	cmin = clmin = 0xffffffffL;
+	cmax = clmax = 0;
+	tmax = 0;
+	for (t = 3; t <= s->mx; t++) {
+	  if (c[t] > cmax) cmax = c[t];
+	  if (c[t] < cmin) cmin = c[t];
+	  if (c[t] > c[tmax]) tmax = t;
+	}
+	clmin = (c[0] < cmin) ? c[0] : cmin;
+	clmax = (c[0] > cmax) ? c[0] : cmax;
+	if (c_all - cmax < (c_all >> 3) &&
+	    cmax - c[s->tx[plane]] > c_all - cmax &&
+	    cmax - c[s->tx[plane]] > (c_all >> 4) &&
+	    /*                     ^ T.82 said < here, fixed in Cor.1/25 */
+	    cmax - (c_all - c[s->tx[plane]]) > c_all - cmax &&
+	    cmax - (c_all - c[s->tx[plane]]) > (c_all >> 4) &&
+	    cmax - cmin > (c_all >> 2) &&
+	    (s->tx[plane] || clmax - clmin > (c_all >> 3))) {
+	  /* we have decided to perform an ATMOVE */
+	  new_tx = tmax;
+	  if (!(s->options & JBG_DELAY_AT)) {
+	    new_tx_line = i;
+	    s->tx[plane] = new_tx;
+	  }
+#ifdef DEBUG
+	  fprintf(stderr, "ATMOVE: line=%ld, tx=%d, c_all=%ld\n",
+		  i, new_tx, c_all);
+#endif
+	}
+	at_determined = 1;
+      }
+      
+      if ((i >> 1) >= ll - 1 || (y >> 1) >= ly - 1)
+	lp1 = lp2;
+
+      /* typical prediction */
+      if (s->options & JBG_TPDON && (i & 1) == 0) {
+	q1 = lp1; q2 = lp2;
+	p0 = p1 = hp;
+	if (i < hl - 1 && y < hy - 1)
+	  p0 = hp + hbpl;
+	if (i > 1 || !reset)
+	  line_l3 = (long)*(q2 - lbpl) << 8;
+	else
+	  line_l3 = 0;
+	line_l2 = (long)*q2 << 8;
+	line_l1 = (long)*q1 << 8;
+	ltp = 1;
+	for (j = 0; j < lx && ltp; q1++, q2++) {
+	  if (j < lbpl * 8 - 8) {
+	    if (i > 1 || !reset)
+	      line_l3 |= *(q2 - lbpl + 1);
+	    line_l2 |= *(q2 + 1);
+	    line_l1 |= *(q1 + 1);
+	  }
+	  do {
+	    if ((j >> 2) < hbpl) {
+	      line_h1 = *(p1++);
+	      line_h0 = *(p0++);
+	    }
+	    do {
+	      line_l3 <<= 1;
+	      line_l2 <<= 1;
+	      line_l1 <<= 1;
+	      line_h1 <<= 2;
+	      line_h0 <<= 2;
+	      cx = (((line_l3 >> 15) & 0x007) |
+		    ((line_l2 >> 12) & 0x038) |
+		    ((line_l1 >> 9)  & 0x1c0));
+	      if (cx == 0x000)
+		if ((line_h1 & 0x300) == 0 && (line_h0 & 0x300) == 0)
+		  s->tp[j] = 0;
+		else {
+		  ltp = 0;
+#ifdef DEBUG
+		  tp_exceptions++;
+#endif
+		}
+	      else if (cx == 0x1ff)
+		if ((line_h1 & 0x300) == 0x300 && (line_h0 & 0x300) == 0x300)
+		  s->tp[j] = 1;
+		else {
+		  ltp = 0;
+#ifdef DEBUG
+		  tp_exceptions++;
+#endif
+		}
+	      else
+		s->tp[j] = 2;
+	    } while (++j & 3 && j < lx);
+	  } while (j & 7 && j < lx);
+	} /* for (j = ...) */
+	arith_encode(se, TPDCX, !ltp);
+#ifdef DEBUG
+	tp_lines += ltp;
+#endif
+      }
+
+
+      /*
+       * Layout of the variables line_h1, line_h2, line_h3, which contain
+       * as bits the high resolution neighbour pixels of the currently coded
+       * highres pixel X:
+       *
+       *            76543210 76543210 76543210 76543210     line_h3
+       *            76543210 76543210 76543210 76543210     line_h2
+       *   76543210 76543210 7654321X 76543210              line_h1
+       *
+       * Layout of the variables line_l1, line_l2, line_l3, which contain
+       * the low resolution pixels near the currently coded pixel as bits.
+       * The lowres pixel in which the currently coded highres pixel is
+       * located is marked as Y:
+       *
+       *            76543210 76543210 76543210 76543210     line_l3
+       *            76543210 7654321Y 76543210 76543210     line_l2
+       *            76543210 76543210 76543210 76543210     line_l1
+       */
+      
+
+      line_h1 = line_h2 = line_h3 = line_l1 = line_l2 = line_l3 = 0;
+      if (i > 0 || !reset) line_h2 = (long)*(hp - hbpl) << 8;
+      if (i > 1 || !reset) {
+	line_h3 = (long)*(hp - hbpl - hbpl) << 8;
+	line_l3 = (long)*(lp2 - lbpl) << 8;
+      }
+      line_l2 = (long)*lp2 << 8;
+      line_l1 = (long)*lp1 << 8;
+      
+      /* encode line */
+      for (j = 0; j < hx; lp1++, lp2++) {
+	if ((j >> 1) < lbpl * 8 - 8) {
+	  if (i > 1 || !reset)
+	    line_l3 |= *(lp2 - lbpl + 1);
+	  line_l2 |= *(lp2 + 1);
+	  line_l1 |= *(lp1 + 1);
+	}
+	do { /* ... while (j & 15 && j < hx) */
+
+	  assert(hp - (s->lhp[s->highres[plane]][plane] +
+		       (stripe * hl + i) * hbpl)
+		 == (ptrdiff_t) j >> 3);
+
+	  assert(lp2 - (s->lhp[1-s->highres[plane]][plane] +
+			(stripe * ll + (i>>1)) * lbpl)
+		 == (ptrdiff_t) j >> 4);
+
+	  line_h1 |= *hp;
+	  if (j < hbpl * 8 - 8) {
+	    if (i > 0 || !reset) {
+	      line_h2 |= *(hp - hbpl + 1);
+	      if (i > 1 || !reset)
+		line_h3 |= *(hp - hbpl - hbpl + 1);
+	    }
+	  }
+	  do { /* ... while (j & 7 && j < hx) */
+	    line_l1 <<= 1;  line_l2 <<= 1;  line_l3 <<= 1;
+	    if (ltp && s->tp[j >> 1] < 2) {
+	      /* pixel are typical and have not to be encoded */
+	      line_h1 <<= 2;  line_h2 <<= 2;  line_h3 <<= 2;
+#ifdef DEBUG
+	      do {
+		++tp_pixels;
+	      } while (++j & 1 && j < hx);
+#else
+	      j += 2;
+#endif
+	    } else
+	      do { /* ... while (++j & 1 && j < hx) */
+		line_h1 <<= 1;  line_h2 <<= 1;  line_h3 <<= 1;
+
+		/* deterministic prediction */
+		if (s->options & JBG_DPON) {
+		  if ((y & 1) == 0) {
+		    if ((j & 1) == 0) {
+		      /* phase 0 */
+		      if (s->dppriv[((line_l3 >> 16) & 0x003) |
+				    ((line_l2 >> 14) & 0x00c) |
+				    ((line_h1 >> 5)  & 0x010) |
+				    ((line_h2 >> 10) & 0x0e0)] < 2) {
+#ifdef DEBUG
+			++dp_pixels;
+#endif
+			continue;
+		      }
+		    } else {
+		      /* phase 1 */
+		      if (s->dppriv[(((line_l3 >> 16) & 0x003) |
+				     ((line_l2 >> 14) & 0x00c) |
+				     ((line_h1 >> 5)  & 0x030) |
+				     ((line_h2 >> 10) & 0x1c0)) + 256] < 2) {
+#ifdef DEBUG
+			++dp_pixels;
+#endif
+			continue;
+		      }
+		    }
+		  } else {
+		    if ((j & 1) == 0) {
+		      /* phase 2 */
+		      if (s->dppriv[(((line_l3 >> 16) & 0x003) |
+				     ((line_l2 >> 14) & 0x00c) |
+				     ((line_h1 >> 5)  & 0x010) |
+				     ((line_h2 >> 10) & 0x0e0) |
+				     ((line_h3 >> 7) & 0x700)) + 768] < 2) {
+#ifdef DEBUG
+			++dp_pixels;
+#endif
+			continue;
+		      }
+		    } else {
+		      /* phase 3 */
+		      if (s->dppriv[(((line_l3 >> 16) & 0x003) |
+				     ((line_l2 >> 14) & 0x00c) |
+				     ((line_h1 >> 5)  & 0x030) |
+				     ((line_h2 >> 10) & 0x1c0) |
+				     ((line_h3 >> 7)  & 0xe00)) + 2816] < 2) {
+#ifdef DEBUG
+			++dp_pixels;
+#endif
+			continue;
+		      }
+		    }	
+		  }	
+		}
+
+		/* determine context */
+		if (s->tx[plane]) {
+		  if ((unsigned) s->tx[plane] > j)
+		    a = 0;
+		  else {
+		    o = (j - s->tx[plane]) - (j & ~7L);
+		    a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+		    a <<= 4;
+		  }
+		  assert(s->tx[plane] > 23 ||
+			 a == ((line_h1 >> (4 + s->tx[plane])) & 0x010));
+		  cx = (((line_h1 >> 9)  & 0x003) | a |
+			((line_h2 >> 13) & 0x00c) |
+			((line_h3 >> 11) & 0x020));
+		} else
+		  cx = (((line_h1 >> 9)  & 0x003) |
+			((line_h2 >> 13) & 0x01c) |
+			((line_h3 >> 11) & 0x020));
+		if (j & 1)
+		  cx |= (((line_l2 >> 9)  & 0x0c0) |
+			 ((line_l1 >> 7)  & 0x300)) | (1UL << 10);
+		else
+		  cx |= (((line_l2 >> 10) & 0x0c0) |
+			 ((line_l1 >> 8)  & 0x300));
+		cx |= (y & 1) << 11;
+
+		arith_encode(se, cx, (line_h1 >> 8) & 1);
+#ifdef DEBUG
+		encoded_pixels++;
+#endif
+		
+		/* statistics for adaptive template changes */
+		if (!at_determined && j >= s->mx) {
+		  c[0] += !(((line_h2 >> 6) ^ line_h1) & 0x100);
+		  for (t = 3; t <= s->mx; t++)
+		    c[t] += !(((line_h1 >> t) ^ line_h1) & 0x100);
+		  ++c_all;
+		}
+		
+	      } while (++j & 1 && j < hx);
+	  } while (j & 7 && j < hx);
+	  hp++;
+	} while (j & 15 && j < hx);
+      } /* for (j = ...) */
+
+      /* low resolution pixels are used twice */
+      if ((i & 1) == 0) {
+	lp1 -= lbpl;
+	lp2 -= lbpl;
+      }
+      
+    } /* for (i = ...) */
+  }
+  
+  arith_encode_flush(se);
+  jbg_buf_remove_zeros(s->sde[stripe][layer][plane]);
+  jbg_buf_write(MARKER_ESC, s->sde[stripe][layer][plane]);
+  jbg_buf_write((s->options & JBG_SDRST) ? MARKER_SDRST : MARKER_SDNORM,
+		s->sde[stripe][layer][plane]);
+  if (s->options & JBG_SDRST)
+    s->tx[plane] = 0;
+
+  /* add ATMOVE */
+  if (new_tx != -1) {
+    if (s->options & JBG_DELAY_AT) {
+      /* ATMOVE will become active at the first line of the next stripe */
+      s->tx[plane] = new_tx;
+      jbg_buf_write(MARKER_ESC, s->sde[stripe][layer][plane]);
+      jbg_buf_write(MARKER_ATMOVE, s->sde[stripe][layer][plane]);
+      jbg_buf_write(0, s->sde[stripe][layer][plane]);
+      jbg_buf_write(0, s->sde[stripe][layer][plane]);
+      jbg_buf_write(0, s->sde[stripe][layer][plane]);
+      jbg_buf_write(0, s->sde[stripe][layer][plane]);
+      jbg_buf_write(s->tx[plane], s->sde[stripe][layer][plane]);
+      jbg_buf_write(0, s->sde[stripe][layer][plane]);
+    } else {
+      /* ATMOVE has already become active during this stripe
+       * => we have to prefix the SDE data with an ATMOVE marker */
+      new_jbg_buf = jbg_buf_init(&s->free_list);
+      jbg_buf_write(MARKER_ESC, new_jbg_buf);
+      jbg_buf_write(MARKER_ATMOVE, new_jbg_buf);
+      jbg_buf_write((new_tx_line >> 24) & 0xff, new_jbg_buf);
+      jbg_buf_write((new_tx_line >> 16) & 0xff, new_jbg_buf);
+      jbg_buf_write((new_tx_line >> 8) & 0xff, new_jbg_buf);
+      jbg_buf_write(new_tx_line & 0xff, new_jbg_buf);
+      jbg_buf_write(new_tx, new_jbg_buf);
+      jbg_buf_write(0, new_jbg_buf);
+      jbg_buf_prefix(new_jbg_buf, &s->sde[stripe][layer][plane]);
+    }
+  }
+
+#if 0
+  if (stripe == s->stripes - 1)
+    fprintf(stderr, "tp_lines = %ld, tp_exceptions = %ld, tp_pixels = %ld, "
+	    "dp_pixels = %ld, encoded_pixels = %ld\n",
+	    tp_lines, tp_exceptions, tp_pixels, dp_pixels, encoded_pixels);
+#endif
+
+  return;
+}
+
+
+/*
+ * Create the next lower resolution version of an image
+ */
+static void resolution_reduction(struct jbg_enc_state *s, int plane,
+				 int higher_layer)
+{
+  unsigned long hl, ll, hx, hy, lx, ly, hbpl, lbpl;
+  unsigned char *hp1, *hp2, *hp3, *lp;
+  unsigned long line_h1, line_h2, line_h3, line_l2;
+  unsigned long y;  /* current line number in lowres image */
+  unsigned long i;  /* current line number within lowres stripe */
+  unsigned long j;  /* current column number in lowres image */
+  int pix, k, l;
+
+  /* number of lines per stripe in highres image */
+  hl = s->l0 << higher_layer;
+  /* number of lines per stripe in lowres image */
+  ll = hl >> 1;
+  /* number of pixels in highres image */
+  hx = jbg_ceil_half(s->xd, s->d - higher_layer);
+  hy = jbg_ceil_half(s->yd, s->d - higher_layer);
+  /* number of pixels in lowres image */
+  lx = jbg_ceil_half(hx, 1);
+  ly = jbg_ceil_half(hy, 1);
+  /* bytes per line in highres and lowres image */
+  hbpl = jbg_ceil_half(hx, 3);
+  lbpl = jbg_ceil_half(lx, 3);
+  /* pointers to first image bytes */
+  hp2 = s->lhp[s->highres[plane]][plane];
+  hp1 = hp2 + hbpl;
+  hp3 = hp2 - hbpl;
+  lp = s->lhp[1 - s->highres[plane]][plane];
+  
+#ifdef DEBUG
+  fprintf(stderr, "resolution_reduction: plane = %d, higher_layer = %d\n",
+	  plane, higher_layer);
+#endif
+
+  /*
+   * Layout of the variables line_h1, line_h2, line_h3, which contain
+   * as bits the high resolution neighbour pixels of the currently coded
+   * lowres pixel /\:
+   *              \/
+   *
+   *   76543210 76543210 76543210 76543210     line_h3
+   *   76543210 76543210 765432/\ 76543210     line_h2
+   *   76543210 76543210 765432\/ 76543210     line_h1
+   *
+   * Layout of the variable line_l2, which contains the low resolution
+   * pixels near the currently coded pixel as bits. The lowres pixel
+   * which is currently coded is marked as X:
+   *
+   *   76543210 76543210 76543210 76543210     line_l2
+   *                            X
+   */
+
+  for (y = 0; y < ly;) {
+    for (i = 0; i < ll && y < ly; i++, y++) {
+      if (2*y + 1 >= hy)
+	hp1 = hp2;
+      pix = 0;
+      line_h1 = line_h2 = line_h3 = line_l2 = 0;
+      for (j = 0; j < lbpl * 8; j += 8) {
+	*lp = 0;
+	if (i > 0 || (y > 0 && !(s->options & JBG_SDRST)))
+	  line_l2 |= *(lp-lbpl);
+	for (k = 0; k < 8 && j + k < lx; k += 4) {
+	  if (((j + k) >> 2) < hbpl) {
+	    if (i > 0 || (y > 0 && !(s->options & JBG_SDRST)))
+	      line_h3 |= *hp3;
+	    ++hp3;
+	    line_h2 |= *(hp2++);
+	    line_h1 |= *(hp1++);
+	  }
+	  for (l = 0; l < 4 && j + k + l < lx; l++) {
+	    line_h3 <<= 2;
+	    line_h2 <<= 2;
+	    line_h1 <<= 2;
+	    line_l2 <<= 1;
+	    pix = s->res_tab[((line_h1 >> 8) & 0x007) |
+			     ((line_h2 >> 5) & 0x038) |
+			     ((line_h3 >> 2) & 0x1c0) |
+			     (pix << 9) | ((line_l2 << 2) & 0xc00)];
+	    *lp = (*lp << 1) | pix;
+	  }
+	}
+	++lp;
+      }
+      *(lp - 1) <<= lbpl * 8 - lx;
+      hp1 += hbpl;
+      hp2 += hbpl;
+      hp3 += hbpl;
+    }
+  }
+
+#ifdef DEBUG
+  {
+    FILE *f;
+    char fn[50];
+    
+    sprintf(fn, "dbg_d=%02d.pbm", higher_layer - 1);
+    f = fopen(fn, "wb");
+    fprintf(f, "P4\n%lu %lu\n", lx, ly);
+    fwrite(s->lhp[1 - s->highres[plane]][plane], 1, lbpl * ly, f);
+    fclose(f);
+  }
+#endif
+
+  return;
+}
+
+
+/* 
+ * This function is called inside the three loops of jbg_enc_out() in
+ * order to write the next SDE. It has first to generate the required
+ * SDE and all SDEs which have to be encoded before this SDE can be
+ * created. The problem here is that if we want to output a lower
+ * resolution layer, we have to apply the resolution reduction
+ * algorithm first to get it. As we try to safe as much memory as
+ * possible, the resolution reduction will overwrite previous higher
+ * resolution bitmaps. Consequently, we have to encode and buffer SDEs
+ * which depend on higher resolution layers before we can start the
+ * resolution reduction. All the logic about which SDE has to be
+ * encoded before resolution reduction is allowed is handled
+ * here. This approach may be a bit more complex than alternative ways
+ * of doing it, but it minimizes the amount of temporary memory used.
+ */
+static void output_sde(struct jbg_enc_state *s,
+		       unsigned long stripe, int layer, int plane)
+{
+  int lfcl;     /* lowest fully coded layer */
+  long i;
+  unsigned long u;
+  
+  assert(s->sde[stripe][layer][plane] != SDE_DONE);
+
+  if (s->sde[stripe][layer][plane] != SDE_TODO) {
+#ifdef DEBUG
+    fprintf(stderr, "writing SDE: s/d/p = %2lu/%2d/%2d\n",
+	    stripe, layer, plane);
+#endif
+    jbg_buf_output(&s->sde[stripe][layer][plane], s->data_out, s->file);
+    s->sde[stripe][layer][plane] = SDE_DONE;
+    return;
+  }
+
+  /* Determine the smallest resolution layer in this plane for which
+   * not yet all stripes have been encoded into SDEs. This layer will
+   * have to be completely coded, before we can apply the next
+   * resolution reduction step. */
+  lfcl = 0;
+  for (i = s->d; i >= 0; i--)
+    if (s->sde[s->stripes - 1][i][plane] == SDE_TODO) {
+      lfcl = i + 1;
+      break;
+    }
+  if (lfcl > s->d && s->d > 0 && stripe == 0) {
+    /* perform the first resolution reduction */
+    resolution_reduction(s, plane, s->d);
+  }
+  /* In case HITOLO is not used, we have to encode and store the higher
+   * resolution layers first, although we do not need them right now. */
+  while (lfcl - 1 > layer) {
+    for (u = 0; u < s->stripes; u++)
+      encode_sde(s, u, lfcl - 1, plane);
+    --lfcl;
+    s->highres[plane] ^= 1;
+    if (lfcl > 1)
+      resolution_reduction(s, plane, lfcl - 1);
+  }
+  
+  encode_sde(s, stripe, layer, plane);
+
+#ifdef DEBUG
+  fprintf(stderr, "writing SDE: s/d/p = %2lu/%2d/%2d\n", stripe, layer, plane);
+#endif
+  jbg_buf_output(&s->sde[stripe][layer][plane], s->data_out, s->file);
+  s->sde[stripe][layer][plane] = SDE_DONE;
+  
+  if (stripe == s->stripes - 1 && layer > 0 &&
+      s->sde[0][layer-1][plane] == SDE_TODO) {
+    s->highres[plane] ^= 1;
+    if (layer > 1)
+      resolution_reduction(s, plane, layer - 1);
+  }
+  
+  return;
+}
+
+
+/*
+ * Convert the table which controls the deterministic prediction
+ * process from the internal format into the representation required
+ * for the 1728 byte long DPTABLE element of a BIH.
+ *
+ * The bit order of the DPTABLE format (see also ITU-T T.82 figure 13) is
+ *
+ * high res:   4  5  6     low res:  0  1
+ *             7  8  9               2  3
+ *            10 11 12
+ *
+ * were 4 table entries are packed into one byte, while we here use
+ * internally an unpacked 6912 byte long table indexed by the following
+ * bit order:
+ *
+ * high res:   7  6  5     high res:   8  7  6     low res:  1  0
+ * (phase 0)   4  .  .     (phase 1)   5  4  .               3  2
+ *             .  .  .                 .  .  .
+ *
+ * high res:  10  9  8     high res:  11 10  9
+ * (phase 2)   7  6  5     (phase 3)   8  7  6
+ *             4  .  .                 5  4  .
+ */
+void jbg_int2dppriv(unsigned char *dptable, const char *internal)
+{
+  int i, j, k;
+  int trans0[ 8] = { 1, 0, 3, 2, 7, 6, 5, 4 };
+  int trans1[ 9] = { 1, 0, 3, 2, 8, 7, 6, 5, 4 };
+  int trans2[11] = { 1, 0, 3, 2, 10, 9, 8, 7, 6, 5, 4 };
+  int trans3[12] = { 1, 0, 3, 2, 11, 10, 9, 8, 7, 6, 5, 4 };
+  
+  for (i = 0; i < 1728; dptable[i++] = 0) ;
+
+#define FILL_TABLE1(offset, len, trans) \
+  for (i = 0; i < len; i++) { \
+    k = 0; \
+    for (j = 0; i >> j; j++) \
+      k |= ((i >> j) & 1) << trans[j]; \
+    dptable[(i + offset) >> 2] |= \
+      (internal[k + offset] & 3) << ((3 - (i&3)) << 1); \
+  }
+
+  FILL_TABLE1(   0,  256, trans0);
+  FILL_TABLE1( 256,  512, trans1);
+  FILL_TABLE1( 768, 2048, trans2);
+  FILL_TABLE1(2816, 4096, trans3);
+
+  return;
+}
+
+
+/*
+ * Convert the table which controls the deterministic prediction
+ * process from the 1728 byte long DPTABLE format into the 6912 byte long
+ * internal format.
+ */
+void jbg_dppriv2int(char *internal, const unsigned char *dptable)
+{
+  int i, j, k;
+  int trans0[ 8] = { 1, 0, 3, 2, 7, 6, 5, 4 };
+  int trans1[ 9] = { 1, 0, 3, 2, 8, 7, 6, 5, 4 };
+  int trans2[11] = { 1, 0, 3, 2, 10, 9, 8, 7, 6, 5, 4 };
+  int trans3[12] = { 1, 0, 3, 2, 11, 10, 9, 8, 7, 6, 5, 4 };
+  
+#define FILL_TABLE2(offset, len, trans) \
+  for (i = 0; i < len; i++) { \
+    k = 0; \
+    for (j = 0; i >> j; j++) \
+      k |= ((i >> j) & 1) << trans[j]; \
+    internal[k + offset] = \
+      (dptable[(i + offset) >> 2] >> ((3 - (i & 3)) << 1)) & 3; \
+  }
+
+  FILL_TABLE2(   0,  256, trans0);
+  FILL_TABLE2( 256,  512, trans1);
+  FILL_TABLE2( 768, 2048, trans2);
+  FILL_TABLE2(2816, 4096, trans3);
+
+  return;
+}
+
+
+/*
+ * Encode one full BIE and pass the generated data to the specified
+ * call-back function
+ */
+void jbg_enc_out(struct jbg_enc_state *s)
+{
+  unsigned long bpl;
+  unsigned char buf[20];
+  unsigned long xd, yd, y;
+  long ii[3], is[3], ie[3];    /* generic variables for the 3 nested loops */ 
+  unsigned long stripe;
+  int layer, plane;
+  int order;
+  unsigned char dpbuf[1728];
+
+  /* some sanity checks */
+  s->order &= JBG_HITOLO | JBG_SEQ | JBG_ILEAVE | JBG_SMID;
+  order = s->order & (JBG_SEQ | JBG_ILEAVE | JBG_SMID);
+  if (iindex[order][0] < 0)
+    s->order = order = JBG_SMID | JBG_ILEAVE;
+  if (s->options & JBG_DPON && s->dppriv != jbg_dptable)
+    s->options |= JBG_DPPRIV;
+  if (s->mx > MX_MAX)
+    s->mx = MX_MAX;
+  s->my = 0;
+  if (s->mx && s->mx < ((s->options & JBG_LRLTWO) ? 5U : 3U))
+    s->mx = 0;
+  if (s->d > 255 || s->d < 0 || s->dh > s->d || s->dh < 0 ||
+      s->dl < 0 || s->dl > s->dh || s->planes < 0 || s->planes > 255)
+    return;
+  /* prevent uint32 overflow: s->l0 * 2 ^ s->d < 2 ^ 32 */
+  if (s->d > 31 || (s->d != 0 && s->l0 >= (1UL << (32 - s->d))))
+    return;
+  if (s->yd1 < s->yd)
+    s->yd1 = s->yd;
+  if (s->yd1 > s->yd)
+    s->options |= JBG_VLENGTH;
+
+  /* ensure correct zero padding of bitmap at the final byte of each line */
+  if (s->xd & 7) {
+    bpl = jbg_ceil_half(s->xd, 3);     /* bytes per line */
+    for (plane = 0; plane < s->planes; plane++)
+      for (y = 0; y < s->yd; y++)
+	s->lhp[0][plane][y * bpl + bpl - 1] &= ~((1 << (8 - (s->xd & 7))) - 1);
+  }
+
+  /* prepare BIH */
+  buf[0] = s->dl;
+  buf[1] = s->dh;
+  buf[2] = s->planes;
+  buf[3] = 0;
+  xd = jbg_ceil_half(s->xd, s->d - s->dh);
+  yd = jbg_ceil_half(s->yd1, s->d - s->dh);
+  buf[4] = xd >> 24;
+  buf[5] = (xd >> 16) & 0xff;
+  buf[6] = (xd >> 8) & 0xff;
+  buf[7] = xd & 0xff;
+  buf[8] = yd >> 24;
+  buf[9] = (yd >> 16) & 0xff;
+  buf[10] = (yd >> 8) & 0xff;
+  buf[11] = yd & 0xff;
+  buf[12] = s->l0 >> 24;
+  buf[13] = (s->l0 >> 16) & 0xff;
+  buf[14] = (s->l0 >> 8) & 0xff;
+  buf[15] = s->l0 & 0xff;
+  buf[16] = s->mx;
+  buf[17] = s->my;
+  buf[18] = s->order;
+  buf[19] = s->options & 0x7f;
+
+#if 0
+  /* sanitize L0 (if it was set to 0xffffffff for T.85-style NEWLEN tests) */
+  if (s->l0 > (s->yd >> s->d))
+    s->l0 = s->yd >> s->d;
+#endif
+
+  /* calculate number of stripes that will be required */
+  s->stripes = jbg_stripes(s->l0, s->yd, s->d);
+
+  /* allocate buffers for SDE pointers */
+  if (s->sde == NULL) {
+    s->sde = (struct jbg_buf ****)
+      checked_malloc(s->stripes, sizeof(struct jbg_buf ***));
+    for (stripe = 0; stripe < s->stripes; stripe++) {
+      s->sde[stripe] = (struct jbg_buf ***)
+	checked_malloc(s->d + 1, sizeof(struct jbg_buf **));
+      for (layer = 0; layer < s->d + 1; layer++) {
+	s->sde[stripe][layer] = (struct jbg_buf **)
+	  checked_malloc(s->planes, sizeof(struct jbg_buf *));
+	for (plane = 0; plane < s->planes; plane++)
+	  s->sde[stripe][layer][plane] = SDE_TODO;
+      }
+    }
+  }
+
+  /* output BIH */
+  s->data_out(buf, 20, s->file);
+  if ((s->options & (JBG_DPON | JBG_DPPRIV | JBG_DPLAST)) ==
+      (JBG_DPON | JBG_DPPRIV)) {
+    /* write private table */
+    jbg_int2dppriv(dpbuf, s->dppriv);
+    s->data_out(dpbuf, 1728, s->file);
+  }
+
+#if 0
+  /*
+   * Encode everything first. This is a simple-minded alternative to
+   * all the tricky on-demand encoding logic in output_sde() for
+   * debugging purposes.
+   */
+  for (layer = s->dh; layer >= s->dl; layer--) {
+    for (plane = 0; plane < s->planes; plane++) {
+      if (layer > 0)
+	resolution_reduction(s, plane, layer);
+      for (stripe = 0; stripe < s->stripes; stripe++)
+	encode_sde(s, stripe, layer, plane);
+      s->highres[plane] ^= 1;
+    }
+  }
+#endif
+
+  /*
+   * Generic loops over all SDEs. Which loop represents layer, plane and
+   * stripe depends on the option flags.
+   */
+
+  /* start and end value for each loop */
+  is[iindex[order][STRIPE]] = 0;
+  ie[iindex[order][STRIPE]] = s->stripes - 1;
+  is[iindex[order][LAYER]] = s->dl;
+  ie[iindex[order][LAYER]] = s->dh;
+  is[iindex[order][PLANE]] = 0;
+  ie[iindex[order][PLANE]] = s->planes - 1;
+
+  for (ii[0] = is[0]; ii[0] <= ie[0]; ii[0]++)
+    for (ii[1] = is[1]; ii[1] <= ie[1]; ii[1]++)
+      for (ii[2] = is[2]; ii[2] <= ie[2]; ii[2]++) {
+	
+	stripe = ii[iindex[order][STRIPE]];
+	if (s->order & JBG_HITOLO)
+	  layer = s->dh - (ii[iindex[order][LAYER]] - s->dl);
+	else
+	  layer = ii[iindex[order][LAYER]];
+	plane = ii[iindex[order][PLANE]];
+
+	/* output comment marker segment if there is any pending */
+	if (s->comment) {
+	  buf[0] = MARKER_ESC;
+	  buf[1] = MARKER_COMMENT;
+	  buf[2] = s->comment_len >> 24;
+	  buf[3] = (s->comment_len >> 16) & 0xff;
+	  buf[4] = (s->comment_len >> 8) & 0xff;
+	  buf[5] = s->comment_len & 0xff;
+	  s->data_out(buf, 6, s->file);
+	  s->data_out(s->comment, s->comment_len, s->file);
+	  s->comment = NULL;
+	}
+
+	output_sde(s, stripe, layer, plane);
+
+	/*
+	 * When we generate a NEWLEN test case (s->yd1 > s->yd), output
+	 * NEWLEN after last stripe if we have only a single
+	 * resolution layer or plane (see ITU-T T.85 profile), otherwise
+	 * output NEWLEN before last stripe.
+	 */
+	if (s->yd1 > s->yd &&
+	    (stripe == s->stripes - 1 ||
+	     (stripe == s->stripes - 2 && 
+	      (s->dl != s->dh || s->planes > 1)))) {
+	  s->yd1 = s->yd;
+	  yd = jbg_ceil_half(s->yd, s->d - s->dh);
+	  buf[0] = MARKER_ESC;
+	  buf[1] = MARKER_NEWLEN;
+	  buf[2] = yd >> 24;
+	  buf[3] = (yd >> 16) & 0xff;
+	  buf[4] = (yd >> 8) & 0xff;
+	  buf[5] = yd & 0xff;
+	  s->data_out(buf, 6, s->file);
+#ifdef DEBUG
+	  fprintf(stderr, "NEWLEN: yd=%lu\n", yd);
+#endif
+	  if (stripe == s->stripes - 1) {
+	    buf[1] = MARKER_SDNORM;
+	    s->data_out(buf, 2, s->file);
+	  }
+	}
+
+      }
+
+  return;
+}
+
+
+void jbg_enc_free(struct jbg_enc_state *s)
+{
+  unsigned long stripe;
+  int layer, plane;
+
+#ifdef DEBUG
+  fprintf(stderr, "jbg_enc_free(%p)\n", (void *) s);
+#endif
+
+  /* clear buffers for SDEs */
+  if (s->sde) {
+    for (stripe = 0; stripe < s->stripes; stripe++) {
+      for (layer = 0; layer < s->d + 1; layer++) {
+	for (plane = 0; plane < s->planes; plane++)
+	  if (s->sde[stripe][layer][plane] != SDE_DONE &&
+	      s->sde[stripe][layer][plane] != SDE_TODO)
+	    jbg_buf_free(&s->sde[stripe][layer][plane]);
+	checked_free(s->sde[stripe][layer]);
+      }
+      checked_free(s->sde[stripe]);
+    }
+    checked_free(s->sde);
+  }
+
+  /* clear free_list */
+  jbg_buf_free(&s->free_list);
+
+  /* clear memory for arithmetic encoder states */
+  checked_free(s->s);
+
+  /* clear memory for differential-layer typical prediction buffer */
+  checked_free(s->tp);
+
+  /* clear memory for adaptive template pixel offsets */
+  checked_free(s->tx);
+
+  /* clear lowres image buffers */
+  if (s->lhp[1]) {
+    for (plane = 0; plane < s->planes; plane++)
+      checked_free(s->lhp[1][plane]);
+    checked_free(s->lhp[1]);
+  }
+  
+  /* clear buffer for index of highres image in lhp */
+  checked_free(s->highres);
+  
+  return;
+}
+
+
+/*
+ * Convert the error codes used by jbg_dec_in() into an English ASCII string
+ */
+const char *jbg_strerror(int errnum)
+{
+  errnum >>= 4;
+  if (errnum < 0 || (unsigned) errnum >= sizeof(errmsg)/sizeof(errmsg[0]))
+    return "Unknown error code passed to jbg_strerror()";
+
+  return errmsg[errnum];
+}
+
+
+/*
+ * The constructor for a decoder 
+ */
+void jbg_dec_init(struct jbg_dec_state *s)
+{
+  s->order = 0;
+  s->d = -1;
+  s->bie_len = 0;
+  s->buf_len = 0;
+  s->dppriv = NULL;
+  s->xmax = 4294967295UL;
+  s->ymax = 4294967295UL;
+  s->dmax = 256;
+  s->s = NULL;
+
+  return;
+}
+
+
+/*
+ * Specify a maximum image size for the decoder. If the JBIG file has
+ * the order bit ILEAVE, but not the bit SEQ set, then the decoder
+ * will abort to decode after the image has reached the maximal
+ * resolution layer which is still not wider than xmax or higher than
+ * ymax.
+ */
+void jbg_dec_maxsize(struct jbg_dec_state *s, unsigned long xmax,
+		     unsigned long ymax)
+{
+  if (xmax > 0) s->xmax = xmax;
+  if (ymax > 0) s->ymax = ymax;
+
+  return;
+}
+
+
+/*
+ * Decode the new len PSDC bytes to which data points and add them to
+ * the current stripe. Return the number of bytes which have actually
+ * been read (this will be less than len if a marker segment was 
+ * part of the data or if the final byte was 0xff, in which case
+ * this code cannot determine whether we have a marker segment).
+ */
+static size_t decode_pscd(struct jbg_dec_state *s, unsigned char *data,
+			  size_t len)
+{
+  unsigned long stripe;
+  unsigned int layer, plane;
+  unsigned long hl, ll, y, hx, hy, lx, ly, hbpl, lbpl;
+  unsigned char *hp, *lp1, *lp2, *p1, *q1;
+  register unsigned long line_h1, line_h2, line_h3;
+  register unsigned long line_l1, line_l2, line_l3;
+  struct jbg_ardec_state *se;
+  unsigned long x;
+  long o;
+  unsigned a;
+  int n;
+  int pix, cx = 0, slntp, tx;
+
+  /* SDE loop variables */
+  stripe = s->ii[iindex[s->order & 7][STRIPE]];
+  layer = s->ii[iindex[s->order & 7][LAYER]];
+  plane = s->ii[iindex[s->order & 7][PLANE]];
+
+  /* forward data to arithmetic decoder */
+  se = s->s[plane] + layer - s->dl;
+  se->pscd_ptr = data;
+  se->pscd_end = data + len;
+  
+  /* number of lines per stripe in highres image */
+  hl = s->l0 << layer;
+  /* number of lines per stripe in lowres image */
+  ll = hl >> 1;
+  /* current line number in highres image */
+  y = stripe * hl + s->i;
+  /* number of pixels in highres image */
+  hx = jbg_ceil_half(s->xd, s->d - layer);
+  hy = jbg_ceil_half(s->yd, s->d - layer);
+  /* number of pixels in lowres image */
+  lx = jbg_ceil_half(hx, 1);
+  ly = jbg_ceil_half(hy, 1);
+  /* bytes per line in highres and lowres image */
+  hbpl = jbg_ceil_half(hx, 3);
+  lbpl = jbg_ceil_half(lx, 3);
+  /* pointer to highres and lowres image bytes */
+  hp  = s->lhp[ layer    & 1][plane] + (stripe * hl + s->i) * hbpl +
+    (s->x >> 3);
+  lp2 = s->lhp[(layer-1) & 1][plane] + (stripe * ll + (s->i >> 1)) * lbpl +
+    (s->x >> 4);
+  lp1 = lp2 + lbpl;
+
+  /* restore a few local variables */
+  line_h1 = s->line_h1;
+  line_h2 = s->line_h2;
+  line_h3 = s->line_h3;
+  line_l1 = s->line_l1;
+  line_l2 = s->line_l2;
+  line_l3 = s->line_l3;
+  x = s->x;
+
+#ifdef DEBUG
+  if (s->x == 0 && s->i == 0 && s->pseudo)
+    fprintf(stderr, "decode_pscd(%p, %p, %ld): s/d/p = %2lu/%2u/%2u\n",
+	    (void *) s, (void *) data, (long) len, stripe, layer, plane);
+#endif
+
+  if (s->x == 0 && s->i == 0 &&
+      (stripe == 0 || s->reset[plane][layer - s->dl]) && s->pseudo) {
+    s->tx[plane][layer - s->dl] = s->ty[plane][layer - s->dl] = 0;
+    s->lntp[plane][layer - s->dl] = 1;
+  }
+
+  if (layer == 0) {
+
+    /*
+     *  Decode lowest resolution layer
+     */
+
+    for (; s->i < hl && y < hy; s->i++, y++) {
+
+      /* adaptive template changes */
+      if (x == 0 && s->pseudo)
+	for (n = 0; n < s->at_moves; n++)
+	  if (s->at_line[n] == s->i) {
+	    s->tx[plane][layer - s->dl] = s->at_tx[n];
+	    s->ty[plane][layer - s->dl] = s->at_ty[n];
+#ifdef DEBUG
+	    fprintf(stderr, "ATMOVE: line=%lu, tx=%d, ty=%d.\n", s->i,
+		    s->tx[plane][layer - s->dl], s->ty[plane][layer - s->dl]);
+#endif
+	  }
+      tx = s->tx[plane][layer - s->dl];
+      assert(tx >= 0); /* i.e., tx can safely be cast to unsigned */
+
+      /* typical prediction */
+      if (s->options & JBG_TPBON && s->pseudo) {
+	slntp = arith_decode(se, (s->options & JBG_LRLTWO) ? TPB2CX : TPB3CX);
+	if (slntp < 0)
+	  goto leave;
+	s->lntp[plane][layer - s->dl] =
+	  !(slntp ^ s->lntp[plane][layer - s->dl]);
+	if (!s->lntp[plane][layer - s->dl]) {
+	  /* this line is 'typical' (i.e. identical to the previous one) */
+	  p1 = hp;
+	  if (s->i == 0 && (stripe == 0 || s->reset[plane][layer - s->dl]))
+	    while (p1 < hp + hbpl) *p1++ = 0;
+	  else {
+	    q1 = hp - hbpl;
+	    while (q1 < hp) *p1++ = *q1++;
+	  }
+	  hp += hbpl;
+	  continue;
+	}
+	/* this line is 'not typical' and has to be coded completely */
+      }
+      s->pseudo = 0;
+      
+      /*
+       * Layout of the variables line_h1, line_h2, line_h3, which contain
+       * as bits the neighbour pixels of the currently decoded pixel X:
+       *
+       *                     76543210 76543210 76543210 76543210     line_h3
+       *                     76543210 76543210 76543210 76543210     line_h2
+       *   76543210 76543210 76543210 76543210 X                     line_h1
+       */
+      
+      if (x == 0) {
+	line_h1 = line_h2 = line_h3 = 0;
+	if (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl]))
+	  line_h2 = (long)*(hp - hbpl) << 8;
+	if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl]))
+	  line_h3 = (long)*(hp - hbpl - hbpl) << 8;
+      }
+      
+      /*
+       * Another tiny JBIG standard bug:
+       *
+       * While implementing the line_h3 handling here, I discovered
+       * another problem with the ITU-T T.82(1993 E) specification.
+       * This might be a somewhat pathological case, however. The
+       * standard is unclear about how a decoder should behave in the
+       * following situation:
+       *
+       * Assume we are in layer 0 and all stripes are single lines
+       * (L0=1 allowed by table 9). We are now decoding the first (and
+       * only) line of the third stripe. Assume, the first stripe was
+       * terminated by SDRST and the second stripe was terminated by
+       * SDNORM. While decoding the only line of the third stripe with
+       * the three-line template, we need access to pixels from the
+       * previous two stripes. We know that the previous stripe
+       * terminated with SDNROM, so we access the pixel from the
+       * second stripe. But do we have to replace the pixels from the
+       * first stripe by background pixels, because this stripe ended
+       * with SDRST? The standard, especially clause 6.2.5 does never
+       * mention this case, so the behaviour is undefined here. My
+       * current implementation remembers only the marker used to
+       * terminate the previous stripe. In the above example, the
+       * pixels of the first stripe are accessed despite the fact that
+       * this stripe ended with SDRST. An alternative (only slightly
+       * more complicated) implementation would be to remember the end
+       * marker (SDNORM or SDRST) of the previous two stripes in a
+       * plane/layer and to act accordingly when accessing the two
+       * previous lines. What am I supposed to do here?
+       *
+       * As the standard is unclear about the correct behaviour in the
+       * situation of the above example, I strongly suggest to avoid
+       * the following situation while encoding data with JBIG:
+       *
+       *   LRLTWO = 0, L0=1 and both SDNORM and SDRST appear in layer 0.
+       *
+       * I guess that only a very few if any encoders will switch
+       * between SDNORM and SDRST, so let us hope that this ambiguity
+       * in the standard will never cause any interoperability
+       * problems.
+       *
+       * Markus Kuhn -- 1995-04-30
+       */
+
+      /* decode line */
+      while (x < hx) {
+	if ((x & 7) == 0) {
+	  if (x < hbpl * 8 - 8 &&
+	      (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl]))) {
+	    line_h2 |= *(hp - hbpl + 1);
+	    if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl]))
+	      line_h3 |= *(hp - hbpl - hbpl + 1);
+	  }
+	}
+	if (s->options & JBG_LRLTWO) {
+	  /* two line template */
+	  do {
+	    if (tx) {
+	      if ((unsigned) tx > x)
+		a = 0;
+	      else if (tx < 8)
+		a = ((line_h1 >> (tx - 5)) & 0x010);
+	      else {
+		o = (x - tx) - (x & ~7L);
+		a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+		a <<= 4;
+	      }
+	      assert(tx > 31 ||
+		     a == ((line_h1 >> (tx - 5)) & 0x010));
+	      pix = arith_decode(se, (((line_h2 >> 9) & 0x3e0) | a |
+				      (line_h1 & 0x00f)));
+	    } else
+	      pix = arith_decode(se, (((line_h2 >> 9) & 0x3f0) |
+				      (line_h1 & 0x00f)));
+	    if (pix < 0)
+	      goto leave;
+	    line_h1 = (line_h1 << 1) | pix;
+	    line_h2 <<= 1;
+	  } while ((++x & 7) && x < hx);
+	} else {
+	  /* three line template */
+	  do {
+	    if (tx) {
+	      if ((unsigned) tx > x)
+		a = 0;
+	      else if (tx < 8)
+		a = ((line_h1 >> (tx - 3)) & 0x004);
+	      else {
+		o = (x - tx) - (x & ~7L);
+		a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+		a <<= 2;
+	      }
+	      assert(tx > 31 ||
+		     a == ((line_h1 >> (tx - 3)) & 0x004));
+	      pix = arith_decode(se, (((line_h3 >>  7) & 0x380) |
+				      ((line_h2 >> 11) & 0x078) | a |
+				      (line_h1 & 0x003)));
+	    } else
+	      pix = arith_decode(se, (((line_h3 >>  7) & 0x380) |
+				      ((line_h2 >> 11) & 0x07c) |
+				      (line_h1 & 0x003)));
+	    if (pix < 0)
+	      goto leave;
+	    
+	    line_h1 = (line_h1 << 1) | pix;
+	    line_h2 <<= 1;
+	    line_h3 <<= 1;
+	  } while ((++x & 7) && x < hx);
+	} /* if (s->options & JBG_LRLTWO) */
+	*hp++ = line_h1;
+      } /* while */
+      *(hp - 1) <<= hbpl * 8 - hx;
+      x = 0;
+      s->pseudo = 1;
+    } /* for (i = ...) */
+    
+  } else {
+
+    /*
+     *  Decode differential layer
+     */
+
+    for (; s->i < hl && y < hy; s->i++, y++) {
+
+      /* adaptive template changes */
+      if (x == 0)
+	for (n = 0; n < s->at_moves; n++)
+	  if (s->at_line[n] == s->i) {
+	    s->tx[plane][layer - s->dl] = s->at_tx[n];
+	    s->ty[plane][layer - s->dl] = s->at_ty[n];
+#ifdef DEBUG
+	    fprintf(stderr, "ATMOVE: line=%lu, tx=%d, ty=%d.\n", s->i,
+		    s->tx[plane][layer - s->dl], s->ty[plane][layer - s->dl]);
+#endif
+	  }
+      tx = s->tx[plane][layer - s->dl];
+
+      /* handle lower border of low-resolution image */
+      if ((s->i >> 1) >= ll - 1 || (y >> 1) >= ly - 1)
+	lp1 = lp2;
+
+      /* typical prediction */
+      if ((s->options & JBG_TPDON) && s->pseudo) {
+	if ((s->lntp[plane][layer - s->dl] = arith_decode(se, TPDCX)) < 0)
+	  goto leave;
+      }
+      s->pseudo = 0;
+
+      /*
+       * Layout of the variables line_h1, line_h2, line_h3, which contain
+       * as bits the high resolution neighbour pixels of the currently
+       * decoded highres pixel X:
+       *
+       *                     76543210 76543210 76543210 76543210     line_h3
+       *                     76543210 76543210 76543210 76543210     line_h2
+       *   76543210 76543210 76543210 76543210 X                     line_h1
+       *
+       * Layout of the variables line_l1, line_l2, line_l3, which contain
+       * the low resolution pixels near the currently decoded pixel as bits.
+       * The lowres pixel in which the currently coded highres pixel is
+       * located is marked as Y:
+       *
+       *                     76543210 76543210 76543210 76543210     line_l3
+       *                     76543210 76543210 Y6543210 76543210     line_l2
+       *                     76543210 76543210 76543210 76543210     line_l1
+       */
+      
+
+      if (x == 0) {
+	line_h1 = line_h2 = line_h3 = line_l1 = line_l2 = line_l3 = 0;
+	if (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl])) {
+	  line_h2 = (long)*(hp - hbpl) << 8;
+	  if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl]))
+	    line_h3 = (long)*(hp - hbpl - hbpl) << 8;
+	}
+	if (s->i > 1 || (y > 1 && !s->reset[plane][layer-s->dl]))
+	  line_l3 = (long)*(lp2 - lbpl) << 8;
+	line_l2 = (long)*lp2 << 8;
+	line_l1 = (long)*lp1 << 8;
+      }
+      
+      /* decode line */
+      while (x < hx) {
+	if ((x & 15) == 0)
+	  if ((x >> 1) < lbpl * 8 - 8) {
+	    line_l1 |= *(lp1 + 1);
+	    line_l2 |= *(lp2 + 1);
+	    if (s->i > 1 || 
+		(y > 1 && !s->reset[plane][layer - s->dl]))
+	      line_l3 |= *(lp2 - lbpl + 1);
+	  }
+	do {
+
+	  assert(hp  - (s->lhp[ layer     &1][plane] + (stripe * hl + s->i)
+			* hbpl) == (ptrdiff_t) x >> 3);
+	  assert(lp2 - (s->lhp[(layer-1) &1][plane] + (stripe * ll + (s->i>>1))
+			* lbpl) == (ptrdiff_t) x >> 4);
+
+	  if ((x & 7) == 0)
+	    if (x < hbpl * 8 - 8) {
+	      if (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl])) {
+		line_h2 |= *(hp + 1 - hbpl);
+		if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl]))
+		  line_h3 |= *(hp + 1 - hbpl - hbpl);
+	      }
+	    }
+	  do {
+	    if (!s->lntp[plane][layer - s->dl])
+              cx = (((line_l3 >> 14) & 0x007) |
+                    ((line_l2 >> 11) & 0x038) |
+                    ((line_l1 >> 8)  & 0x1c0));
+	    if (!s->lntp[plane][layer - s->dl] &&
+		(cx == 0x000 || cx == 0x1ff)) {
+	      /* pixels are typical and have not to be decoded */
+	      do {
+		line_h1 = (line_h1 << 1) | (cx & 1);
+	      } while ((++x & 1) && x < hx);
+	      line_h2 <<= 2;  line_h3 <<= 2;
+	    } else 
+	      do {
+		
+		/* deterministic prediction */
+		if (s->options & JBG_DPON)
+		  if ((y & 1) == 0)
+		    if ((x & 1) == 0) 
+		      /* phase 0 */
+		      pix = s->dppriv[((line_l3 >> 15) & 0x003) |
+				      ((line_l2 >> 13) & 0x00c) |
+				      ((line_h1 <<  4) & 0x010) |
+				      ((line_h2 >>  9) & 0x0e0)];
+		    else
+		      /* phase 1 */
+		      pix = s->dppriv[(((line_l3 >> 15) & 0x003) |
+				       ((line_l2 >> 13) & 0x00c) |
+				       ((line_h1 <<  4) & 0x030) |
+				       ((line_h2 >>  9) & 0x1c0)) + 256];
+		  else
+		    if ((x & 1) == 0)
+		      /* phase 2 */
+		      pix = s->dppriv[(((line_l3 >> 15) & 0x003) |
+				       ((line_l2 >> 13) & 0x00c) |
+				       ((line_h1 <<  4) & 0x010) |
+				       ((line_h2 >>  9) & 0x0e0) |
+				       ((line_h3 >>  6) & 0x700)) + 768];
+		    else
+		      /* phase 3 */
+		      pix = s->dppriv[(((line_l3 >> 15) & 0x003) |
+				       ((line_l2 >> 13) & 0x00c) |
+				       ((line_h1 <<  4) & 0x030) |
+				       ((line_h2 >>  9) & 0x1c0) |
+				       ((line_h3 >>  6) & 0xe00)) + 2816];
+		else
+		  pix = 2;
+
+		if (pix & 2) {
+		  if (tx)
+		    cx = ((line_h1         & 0x003) |
+			  (((line_h1 << 2) >> (tx - 3)) & 0x010) |
+			  ((line_h2 >> 12) & 0x00c) |
+			  ((line_h3 >> 10) & 0x020));
+		  else
+		    cx = ((line_h1         & 0x003) |
+			  ((line_h2 >> 12) & 0x01c) |
+			  ((line_h3 >> 10) & 0x020));
+		  if (x & 1)
+		    cx |= (((line_l2 >> 8) & 0x0c0) |
+			   ((line_l1 >> 6) & 0x300)) | (1UL << 10);
+		  else
+		    cx |= (((line_l2 >> 9) & 0x0c0) |
+			   ((line_l1 >> 7) & 0x300));
+		  cx |= (y & 1) << 11;
+
+		  pix = arith_decode(se, cx);
+		  if (pix < 0)
+		    goto leave;
+		}
+
+		line_h1 = (line_h1 << 1) | pix;
+		line_h2 <<= 1;
+		line_h3 <<= 1;
+		
+	      } while ((++x & 1) && x < hx);
+	    line_l1 <<= 1; line_l2 <<= 1;  line_l3 <<= 1;
+	  } while ((x & 7) && x < hx);
+	  *hp++ = line_h1;
+	} while ((x & 15) && x < hx);
+	++lp1;
+	++lp2;
+      } /* while */
+      x = 0;
+      
+      *(hp - 1) <<= hbpl * 8 - hx;
+      if ((s->i & 1) == 0) {
+	/* low resolution pixels are used twice */
+	lp1 -= lbpl;
+	lp2 -= lbpl;
+      } else
+	s->pseudo = 1;
+      
+    } /* for (i = ...) */
+    
+  }
+
+ leave:
+
+  /* save a few local variables */
+  s->line_h1 = line_h1;
+  s->line_h2 = line_h2;
+  s->line_h3 = line_h3;
+  s->line_l1 = line_l1;
+  s->line_l2 = line_l2;
+  s->line_l3 = line_l3;
+  s->x = x;
+
+  return se->pscd_ptr - data;
+}
+
+
+/*
+ * Provide to the decoder a new BIE fragment of len bytes starting at data.
+ *
+ * Unless cnt is NULL, *cnt will contain the number of actually read bytes
+ * on return.
+ *
+ * Normal return values:
+ *
+ *   JBG_EAGAIN      All data bytes provided so far have been processed
+ *                   (*cnt == len) but the end of the data stream has
+ *                   not yet been recognized. Call the function again
+ *                   with additional BIE bytes.
+ *   JBG_EOK         The function has reached the end of a and
+ *                   a full image has been decoded. The function can
+ *                   be called again with data from the next BIE, if
+ *                   there exists one, in order to get to a higher
+ *                   resolution layer. The remaining len - *cnt bytes
+ *                   of the previous data block will then have to passed
+ *                   to this function again if len > *cnt.
+ *   JBG_EOK_INTR    Parsing the BIE has been interrupted as had been
+ *                   requested by a jbg_dec_maxsize() specification.
+ *                   This function can be called again with the
+ *                   rest of the BIE to continue the decoding process.
+ *                   The remaining len - *cnt bytes of the previous
+ *                   data block will then have to be passed to this
+ *                   function again if len > *cnt.
+ *
+ * Any other return value indicates that the decoding process was
+ * aborted by a serious problem and the only function you can then
+ * still call is jbg_dec_free() in order to remove the mess, and
+ * jbg85_strerror() to find out what to tell the user. (Looking at the
+ * least significant bits of the return value will provide additional
+ * information by identifying which test exactly has failed.)
+ */
+int jbg_dec_in(struct jbg_dec_state *s, unsigned char *data, size_t len,
+	       size_t *cnt)
+{
+  int i, j, required_length;
+  unsigned long x, y;
+  unsigned long is[3], ie[3];
+  size_t dummy_cnt;
+  unsigned char *dppriv;
+
+  if (!cnt) cnt = &dummy_cnt;
+  *cnt = 0;
+  if (len < 1) return JBG_EAGAIN;
+
+  /* read in 20-byte BIH */
+  if (s->bie_len < 20) {
+    while (s->bie_len < 20 && *cnt < len)
+      s->buffer[s->bie_len++] = data[(*cnt)++];
+    if (s->bie_len < 20) 
+      return JBG_EAGAIN;
+    /* test whether this looks like a valid JBIG header at all */
+    if (s->buffer[1] < s->buffer[0])
+      return JBG_EINVAL | 1;
+    if (s->buffer[3] != 0)           return JBG_EINVAL | 2; /* padding != 0 */
+    if ((s->buffer[18] & 0xf0) != 0) return JBG_EINVAL | 3; /* padding != 0 */
+    if ((s->buffer[19] & 0x80) != 0) return JBG_EINVAL | 4; /* padding != 0 */
+    if (s->buffer[0] != s->d + 1)
+      return JBG_ENOCONT | 1;
+    s->dl = s->buffer[0];
+    s->d = s->buffer[1];
+    if (s->dl == 0)
+      s->planes = s->buffer[2];
+    else
+      if (s->planes != s->buffer[2])
+	return JBG_ENOCONT | 2;
+    x = (((long) s->buffer[ 4] << 24) | ((long) s->buffer[ 5] << 16) |
+	 ((long) s->buffer[ 6] <<  8) | (long) s->buffer[ 7]);
+    y = (((long) s->buffer[ 8] << 24) | ((long) s->buffer[ 9] << 16) |
+	 ((long) s->buffer[10] <<  8) | (long) s->buffer[11]);
+    if (s->dl != 0 && ((s->xd << (s->d - s->dl + 1)) != x &&
+		       (s->yd << (s->d - s->dl + 1)) != y))
+      return JBG_ENOCONT | 3;
+    s->xd = x;
+    s->yd = y;
+    s->l0 = (((long) s->buffer[12] << 24) | ((long) s->buffer[13] << 16) |
+	     ((long) s->buffer[14] <<  8) | (long) s->buffer[15]);
+    /* ITU-T T.85 trick not directly implemented by decoder; for full
+     * T.85 compatibility with respect to all NEWLEN marker scenarios,
+     * preprocess BIE with jbg_newlen() before passing it to the decoder,
+     * or consider using the decoder found in jbig85.c instead. */
+    if (s->yd == 0xffffffff)
+      return JBG_EIMPL | 1;
+    if (!s->planes) return JBG_EINVAL | 5;
+    if (!s->xd)     return JBG_EINVAL | 6;
+    if (!s->yd)     return JBG_EINVAL | 7;
+    if (!s->l0)     return JBG_EINVAL | 8;
+    /* prevent uint32 overflow: s->l0 * 2 ^ s->d < 2 ^ 32 */
+    if (s->d > 31)
+      return JBG_EIMPL | 2;
+    if ((s->d != 0 && s->l0 >= (1UL << (32 - s->d))))
+      return JBG_EIMPL | 3;
+    s->mx = s->buffer[16];
+    if (s->mx > 127)
+      return JBG_EINVAL | 9;
+    s->my = s->buffer[17];
+#if 0
+    if (s->my > 0)
+      return JBG_EIMPL | 4;
+#endif
+    s->order = s->buffer[18];
+    if (iindex[s->order & 7][0] < 0)
+      return JBG_EINVAL | 10;
+    /* HITOLO and SEQ currently not yet implemented */
+    if (s->dl != s->d && (s->order & JBG_HITOLO || s->order & JBG_SEQ))
+      return JBG_EIMPL | 5;
+    s->options = s->buffer[19];
+
+    /* calculate number of stripes that will be required */
+    s->stripes = jbg_stripes(s->l0, s->yd, s->d);
+    
+    /* some initialization */
+    s->ii[iindex[s->order & 7][STRIPE]] = 0;
+    s->ii[iindex[s->order & 7][LAYER]] = s->dl;
+    s->ii[iindex[s->order & 7][PLANE]] = 0;
+    if (s->dl == 0) {
+      s->s      = (struct jbg_ardec_state **)
+	checked_malloc(s->planes, sizeof(struct jbg_ardec_state *));
+      s->tx     = (int **) checked_malloc(s->planes, sizeof(int *));
+      s->ty     = (int **) checked_malloc(s->planes, sizeof(int *));
+      s->reset  = (int **) checked_malloc(s->planes, sizeof(int *));
+      s->lntp   = (int **) checked_malloc(s->planes, sizeof(int *));
+      s->lhp[0] = (unsigned char **)
+	checked_malloc(s->planes, sizeof(unsigned char *));
+      s->lhp[1] = (unsigned char **)
+	checked_malloc(s->planes, sizeof(unsigned char *));
+      for (i = 0; i < s->planes; i++) {
+	s->s[i]     = (struct jbg_ardec_state *)
+	  checked_malloc(s->d - s->dl + 1, sizeof(struct jbg_ardec_state));
+	s->tx[i]    = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int));
+	s->ty[i]    = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int));
+	s->reset[i] = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int));
+	s->lntp[i]  = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int));
+	s->lhp[ s->d    & 1][i] = (unsigned char *)
+	  checked_malloc(s->yd, jbg_ceil_half(s->xd, 3));
+	s->lhp[(s->d-1) & 1][i] = (unsigned char *)
+	  checked_malloc(jbg_ceil_half(s->yd, 1), jbg_ceil_half(s->xd, 1+3));
+      }
+    } else {
+      for (i = 0; i < s->planes; i++) {
+	s->s[i]     = (struct jbg_ardec_state *)
+	  checked_realloc(s->s[i], s->d - s->dl + 1,
+			  sizeof(struct jbg_ardec_state));
+	s->tx[i]    = (int *) checked_realloc(s->tx[i],
+					      s->d - s->dl + 1, sizeof(int));
+	s->ty[i]    = (int *) checked_realloc(s->ty[i],
+					      s->d - s->dl + 1, sizeof(int));
+	s->reset[i] = (int *) checked_realloc(s->reset[i],
+					      s->d - s->dl + 1, sizeof(int));
+	s->lntp[i]  = (int *) checked_realloc(s->lntp[i],
+					      s->d - s->dl + 1, sizeof(int));
+	s->lhp[ s->d    & 1][i] = (unsigned char *)
+	  checked_realloc(s->lhp[ s->d    & 1][i],
+			  s->yd, jbg_ceil_half(s->xd, 3));
+	s->lhp[(s->d-1) & 1][i] = (unsigned char *)
+	  checked_realloc(s->lhp[(s->d-1) & 1][i],
+			  jbg_ceil_half(s->yd, 1), jbg_ceil_half(s->xd, 1+3));
+      }
+    }
+    for (i = 0; i < s->planes; i++)
+      for (j = 0; j <= s->d - s->dl; j++)
+	arith_decode_init(s->s[i] + j, 0);
+    if (s->dl == 0 || (s->options & JBG_DPON && !(s->options & JBG_DPPRIV)))
+      s->dppriv = jbg_dptable;
+    s->comment_skip = 0;
+    s->buf_len = 0;
+    s->x = 0;
+    s->i = 0;
+    s->pseudo = 1;
+    s->at_moves = 0;
+  }
+
+  /* read in DPTABLE */
+  if (s->bie_len < 20 + 1728 && 
+      (s->options & (JBG_DPON | JBG_DPPRIV | JBG_DPLAST)) ==
+      (JBG_DPON | JBG_DPPRIV)) {
+    assert(s->bie_len >= 20);
+    if (!s->dppriv || s->dppriv == jbg_dptable)
+      s->dppriv = (char *) checked_malloc(1728, sizeof(char));
+    while (s->bie_len < 20 + 1728 && *cnt < len)
+      s->dppriv[s->bie_len++ - 20] = data[(*cnt)++];
+    if (s->bie_len < 20 + 1728) 
+      return JBG_EAGAIN;
+    dppriv = (unsigned char *) s->dppriv;
+    s->dppriv = (char *) checked_malloc(6912, sizeof(char));
+    jbg_dppriv2int(s->dppriv, dppriv);
+    checked_free(dppriv);
+  }
+
+  /*
+   * BID processing loop
+   */
+  
+  while (*cnt < len) {
+
+    /* process floating marker segments */
+
+    /* skip COMMENT contents */
+    if (s->comment_skip) {
+      if (s->comment_skip <= len - *cnt) {
+	*cnt += s->comment_skip;
+	s->comment_skip = 0;
+      } else {
+	s->comment_skip -= len - *cnt;
+	*cnt = len;
+      }
+      continue;
+    }
+
+    /* load complete marker segments into s->buffer for processing */
+    if (s->buf_len > 0) {
+      assert(s->buffer[0] == MARKER_ESC);
+      while (s->buf_len < 2 && *cnt < len)
+	s->buffer[s->buf_len++] = data[(*cnt)++];
+      if (s->buf_len < 2) continue;
+      switch (s->buffer[1]) {
+      case MARKER_COMMENT: required_length = 6; break;
+      case MARKER_ATMOVE:  required_length = 8; break;
+      case MARKER_NEWLEN:  required_length = 6; break;
+      case MARKER_ABORT:
+      case MARKER_SDNORM:
+      case MARKER_SDRST:   required_length = 2; break;
+      case MARKER_STUFF:
+	/* forward stuffed 0xff to arithmetic decoder */
+	s->buf_len = 0;
+	decode_pscd(s, s->buffer, 2);
+	continue;
+      default:
+	return JBG_EMARKER;
+      }
+      while (s->buf_len < required_length && *cnt < len)
+	s->buffer[s->buf_len++] = data[(*cnt)++];
+      if (s->buf_len < required_length) continue;
+      /* now the buffer is filled with exactly one marker segment */
+      switch (s->buffer[1]) {
+      case MARKER_COMMENT:
+	s->comment_skip =
+	  (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) |
+	   ((long) s->buffer[4] <<  8) | (long) s->buffer[5]);
+	break;
+      case MARKER_ATMOVE:
+	if (s->at_moves < JBG_ATMOVES_MAX) {
+	  s->at_line[s->at_moves] =
+	    (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) |
+	     ((long) s->buffer[4] <<  8) | (long) s->buffer[5]);
+	  s->at_tx[s->at_moves] = (signed char) s->buffer[6];
+	  s->at_ty[s->at_moves] = s->buffer[7];
+	  if (s->at_tx[s->at_moves] < - (int) s->mx ||
+	      s->at_tx[s->at_moves] >   (int) s->mx ||
+	      s->at_ty[s->at_moves] >   (int) s->my ||
+	      (s->at_ty[s->at_moves] == 0 && s->at_tx[s->at_moves] < 0))
+	    return JBG_EINVAL | 11;
+	  if (s->at_ty[s->at_moves] != 0)
+	    return JBG_EIMPL | 6;
+	  s->at_moves++;
+	} else
+	  return JBG_EIMPL | 7; /* more than JBG_ATMOVES_MAX ATMOVES */
+	break;
+      case MARKER_NEWLEN:
+	y = (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) |
+	     ((long) s->buffer[4] <<  8) | (long) s->buffer[5]);
+	if (y > s->yd)                   return JBG_EINVAL | 12;
+	if (!(s->options & JBG_VLENGTH)) return JBG_EINVAL | 13;
+	s->yd = y;
+	/* calculate again number of stripes that will be required */
+	s->stripes = jbg_stripes(s->l0, s->yd, s->d);
+	break;
+      case MARKER_ABORT:
+	return JBG_EABORT;
+	
+      case MARKER_SDNORM:
+      case MARKER_SDRST:
+	/* decode final pixels based on trailing zero bytes */
+	decode_pscd(s, s->buffer, 2);
+
+	arith_decode_init(s->s[s->ii[iindex[s->order & 7][PLANE]]] + 
+			  s->ii[iindex[s->order & 7][LAYER]] - s->dl,
+			  s->ii[iindex[s->order & 7][STRIPE]] != s->stripes - 1
+			  && s->buffer[1] != MARKER_SDRST);
+	
+	s->reset[s->ii[iindex[s->order & 7][PLANE]]]
+	  [s->ii[iindex[s->order & 7][LAYER]] - s->dl] =
+	    (s->buffer[1] == MARKER_SDRST);
+	
+	/* prepare for next SDE */
+	s->x = 0;
+	s->i = 0;
+	s->pseudo = 1;
+	s->at_moves = 0;
+	
+	/* increment layer/stripe/plane loop variables */
+	/* start and end value for each loop: */
+	is[iindex[s->order & 7][STRIPE]] = 0;
+	ie[iindex[s->order & 7][STRIPE]] = s->stripes - 1;
+	is[iindex[s->order & 7][LAYER]] = s->dl;
+	ie[iindex[s->order & 7][LAYER]] = s->d;
+	is[iindex[s->order & 7][PLANE]] = 0;
+	ie[iindex[s->order & 7][PLANE]] = s->planes - 1;
+	i = 2;  /* index to innermost loop */
+	do {
+	  j = 0;  /* carry flag */
+	  if (++s->ii[i] > ie[i]) {
+	    /* handling overflow of loop variable */
+	    j = 1;
+	    if (i > 0)
+	      s->ii[i] = is[i];
+	  }
+	} while (--i >= 0 && j);
+
+	s->buf_len = 0;
+	
+	/* check whether this have been all SDEs */
+	if (j) {
+#ifdef DEBUG
+	  fprintf(stderr, "This was the final SDE in this BIE, "
+		  "%ld bytes left.\n", (long) (len - *cnt));
+#endif
+	  s->bie_len = 0;
+	  return JBG_EOK;
+	}
+
+	/* check whether we have to abort because of xmax/ymax */
+	if (iindex[s->order & 7][LAYER] == 0 && i < 0) {
+	  /* LAYER is the outermost loop and we have just gone to next layer */
+	  if (jbg_ceil_half(s->xd, s->d - s->ii[0]) > s->xmax ||
+	      jbg_ceil_half(s->yd, s->d - s->ii[0]) > s->ymax) {
+	    s->xmax = 4294967295UL;
+	    s->ymax = 4294967295UL;
+	    return JBG_EOK_INTR;
+	  }
+	  if (s->ii[0] > (unsigned long) s->dmax) {
+	    s->dmax = 256;
+	    return JBG_EOK_INTR;
+	  }
+	}
+
+	break;
+      }
+      s->buf_len = 0;
+
+    } else if (data[*cnt] == MARKER_ESC)
+      s->buffer[s->buf_len++] = data[(*cnt)++];
+
+    else {
+
+      /* we have found PSCD bytes */
+      *cnt += decode_pscd(s, data + *cnt, len - *cnt);
+      if (*cnt < len && data[*cnt] != 0xff) {
+#ifdef DEBUG
+	fprintf(stderr, "PSCD was longer than expected, unread bytes "
+		"%02x %02x %02x %02x ...\n", data[*cnt], data[*cnt+1],
+		data[*cnt+2], data[*cnt+3]);
+#endif
+	return JBG_EINVAL | 14;
+      }
+      
+    }
+  }  /* of BID processing loop 'while (*cnt < len) ...' */
+
+  return JBG_EAGAIN;
+}
+
+
+/*
+ * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call this
+ * function in order to find out the width of the image. Returns 0 if
+ * there is no image available yet.
+ */
+unsigned long jbg_dec_getwidth(const struct jbg_dec_state *s)
+{
+  if (s->d < 0)
+    return 0;
+  if (iindex[s->order & 7][LAYER] == 0) {
+    if (s->ii[0] < 1)
+      return 0;
+    else
+      return jbg_ceil_half(s->xd, s->d - (s->ii[0] - 1));
+  }
+
+  return s->xd;
+}
+
+
+/*
+ * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call this
+ * function in order to find out the height of the image. Returns 0 if
+ * there is no image available yet.
+ */
+unsigned long jbg_dec_getheight(const struct jbg_dec_state *s)
+{
+  if (s->d < 0)
+    return 0;
+  if (iindex[s->order & 7][LAYER] == 0) {
+    if (s->ii[0] < 1)
+      return 0;
+    else
+      return jbg_ceil_half(s->yd, s->d - (s->ii[0] - 1));
+  }
+  
+  return s->yd;
+}
+
+
+/*
+ * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call this
+ * function in order to get a pointer to the image. Returns NULL if
+ * there is no image available yet.
+ */
+unsigned char *jbg_dec_getimage(const struct jbg_dec_state *s, int plane)
+{
+  if (s->d < 0)
+    return NULL;
+  if (iindex[s->order & 7][LAYER] == 0) {
+    if (s->ii[0] < 1)
+      return NULL;
+    else
+      return s->lhp[(s->ii[0] - 1) & 1][plane];
+  }
+  
+  return s->lhp[s->d & 1][plane];
+}
+
+
+/*
+ * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call
+ * this function in order to find out the size in bytes of one
+ * bitplane of the image.
+ */
+unsigned long jbg_dec_getsize(const struct jbg_dec_state *s)
+{
+  if (s->d < 0)
+    return 0;
+  if (iindex[s->order & 7][LAYER] == 0) {
+    if (s->ii[0] < 1)
+      return 0;
+    else
+      return 
+	jbg_ceil_half(s->xd, s->d - (s->ii[0] - 1) + 3) * /* overflow risk? */
+	jbg_ceil_half(s->yd, s->d - (s->ii[0] - 1));
+  }
+  
+  return jbg_ceil_half(s->xd, 3) * s->yd;
+}
+
+
+/*
+ * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call
+ * this function in order to find out the size of the image that you
+ * can retrieve with jbg_merge_planes().
+ */
+unsigned long jbg_dec_getsize_merged(const struct jbg_dec_state *s)
+{
+  if (s->d < 0)
+    return 0;
+  if (iindex[s->order & 7][LAYER] == 0) {
+    if (s->ii[0] < 1)
+      return 0;
+    else
+      return 
+	jbg_ceil_half(s->xd, s->d - (s->ii[0] - 1)) * /* overflow risk? */
+	jbg_ceil_half(s->yd, s->d - (s->ii[0] - 1)) *
+	((s->planes + 7) / 8);
+  }
+  
+  return s->xd * s->yd * ((s->planes + 7) / 8);
+}
+
+
+/* 
+ * The destructor function which releases any resources obtained by the
+ * other decoder functions.
+ */
+void jbg_dec_free(struct jbg_dec_state *s)
+{
+  int i;
+
+  if (s->d < 0 || s->s == NULL)
+    return;
+  s->d = -2;
+
+  for (i = 0; i < s->planes; i++) {
+    checked_free(s->s[i]);
+    checked_free(s->tx[i]);
+    checked_free(s->ty[i]);
+    checked_free(s->reset[i]);
+    checked_free(s->lntp[i]);
+    checked_free(s->lhp[0][i]);
+    checked_free(s->lhp[1][i]);
+  }
+  
+  checked_free(s->s);
+  checked_free(s->tx);
+  checked_free(s->ty);
+  checked_free(s->reset);
+  checked_free(s->lntp);
+  checked_free(s->lhp[0]);
+  checked_free(s->lhp[1]);
+  if (s->dppriv && s->dppriv != jbg_dptable)
+    checked_free(s->dppriv);
+
+  s->s = NULL;
+
+  return;
+}
+
+
+/*
+ * Split bigendian integer pixel field into separate bit planes. In the
+ * src array, every pixel is represented by a ((has_planes + 7) / 8) byte
+ * long word, most significant byte first. While has_planes describes
+ * the number of used bits per pixel in the source image, encode_plane
+ * is the number of most significant bits among those that we
+ * actually transfer to dest.
+ */
+void jbg_split_planes(unsigned long x, unsigned long y, int has_planes,
+		      int encode_planes,
+		      const unsigned char *src, unsigned char **dest,
+		      int use_graycode)
+{
+  unsigned long bpl = jbg_ceil_half(x, 3);  /* bytes per line in dest plane */
+  unsigned long line, i;
+  unsigned k = 8;
+  int p;
+  unsigned prev;     /* previous *src byte shifted by 8 bit to the left */
+  register int bits, msb = has_planes - 1;
+  int bitno;
+
+  /* sanity checks */
+  if (encode_planes > has_planes)
+    encode_planes = has_planes;
+  use_graycode = use_graycode != 0 && encode_planes > 1;
+  
+  for (p = 0; p < encode_planes; p++)
+    memset(dest[p], 0, bpl * y);
+  
+  for (line = 0; line < y; line++) {                 /* lines loop */
+    for (i = 0; i * 8 < x; i++) {                    /* dest bytes loop */
+      for (k = 0; k < 8 && i * 8 + k < x; k++) {     /* pixel loop */
+	prev = 0;
+	for (p = 0; p < encode_planes; p++) {        /* bit planes loop */
+	  /* calculate which bit in *src do we want */
+	  bitno = (msb - p) & 7;
+	  /* put this bit with its left neighbor right adjusted into bits */
+	  bits = (prev | *src) >> bitno;
+	  /* go to next *src byte, but keep old */
+	  if (bitno == 0)
+	    prev = *src++ << 8;
+	  /* make space for inserting new bit */
+	  dest[p][bpl * line + i] <<= 1;
+	  /* insert bit, if requested apply Gray encoding */
+	  dest[p][bpl * line + i] |= (bits ^ (use_graycode & (bits>>1))) & 1;
+	  /*
+	   * Theorem: Let b(n),...,b(1),b(0) be the digits of a
+	   * binary word and let g(n),...,g(1),g(0) be the digits of the
+	   * corresponding Gray code word, then g(i) = b(i) xor b(i+1).
+	   */
+	}
+	/* skip unused *src bytes */
+	for (;p < has_planes; p++)
+	  if (((msb - p) & 7) == 0)
+	    src++;
+      }
+    }
+    for (p = 0; p < encode_planes; p++)              /* right padding loop */
+      dest[p][bpl * (line + 1) - 1] <<= 8 - k;
+  }
+  
+  return;
+}
+
+/* 
+ * Merge the separate bit planes decoded by the JBIG decoder into an
+ * integer pixel field. This is essentially the counterpart to
+ * jbg_split_planes().
+ */
+void jbg_dec_merge_planes(const struct jbg_dec_state *s, int use_graycode,
+			  void (*data_out)(unsigned char *start, size_t len,
+					   void *file), void *file)
+{
+#define BUFLEN 4096
+  unsigned long bpl, line, i;
+  unsigned k = 8;
+  int p;
+  unsigned char buf[BUFLEN];
+  unsigned char *bp = buf;
+  unsigned char **src;
+  unsigned long x, y;
+  unsigned v;
+
+  /* sanity check */
+  use_graycode = use_graycode != 0;
+  
+  x = jbg_dec_getwidth(s);
+  y = jbg_dec_getheight(s);
+  if (x == 0 || y == 0)
+    return;
+  bpl = jbg_ceil_half(x, 3);   /* bytes per line in src plane */
+
+  if (iindex[s->order & 7][LAYER] == 0)
+    if (s->ii[0] < 1)
+      return;
+    else
+      src = s->lhp[(s->ii[0] - 1) & 1];
+  else
+    src = s->lhp[s->d & 1];
+  
+  for (line = 0; line < y; line++) {                    /* lines loop */
+    for (i = 0; i * 8 < x; i++) {                       /* src bytes loop */
+      for (k = 0; k < 8 && i * 8 + k < x; k++) {        /* pixel loop */
+	v = 0;
+	for (p = 0; p < s->planes;) {                   /* dest bytes loop */
+	  do {
+	    v = (v << 1) |
+	      (((src[p][bpl * line + i] >> (7 - k)) & 1) ^
+	       (use_graycode & v));
+	  } while ((s->planes - ++p) & 7);
+	  *bp++ = v;
+	  if (bp - buf == BUFLEN) {
+	    data_out(buf, BUFLEN, file);
+	    bp = buf;
+	  }
+	}
+      }
+    }
+  }
+  
+  if (bp - buf > 0)
+    data_out(buf, bp - buf, file);
+  
+  return;
+}
+
+
+/*
+ * Given a pointer p to the first byte of either a marker segment or a
+ * PSCD, as well as the length len of the remaining data, return
+ * either the pointer to the first byte of the next marker segment or
+ * PSCD, or p+len if this was the last one, or NULL if some error was
+ * encountered. Possible errors are:
+ *
+ *  - not enough bytes left for complete marker segment
+ *  - no marker segment terminates the PSCD
+ *  - unknown marker code encountered
+ *  
+ */
+static unsigned char *jbg_next_pscdms(unsigned char *p, size_t len)
+{
+  unsigned char *pp;
+  unsigned long l;
+
+  if (len < 2)
+    return NULL; /* not enough bytes left for complete marker segment */
+
+  if (p[0] != MARKER_ESC || p[1] == MARKER_STUFF) {
+    do {
+      while (p[0] == MARKER_ESC && p[1] == MARKER_STUFF) {
+	p += 2;
+	len -= 2;
+	if (len < 2)
+	  return NULL; /* not enough bytes left for complete marker segment */
+      }
+      assert(len >= 2);
+      pp = (unsigned char *) memchr(p, MARKER_ESC, len - 1);
+      if (!pp)
+	return NULL; /* no marker segment terminates the PSCD */
+      l = pp - p;
+      assert(l < len);
+      p += l;
+      len -= l;
+    } while (p[1] == MARKER_STUFF);
+  } else {
+    switch (p[1]) {
+    case MARKER_SDNORM:
+    case MARKER_SDRST:
+    case MARKER_ABORT:
+      return p + 2;
+    case MARKER_NEWLEN:
+      if (len < 6)
+	return NULL; /* not enough bytes left for complete marker segment */
+      return p + 6;
+    case MARKER_ATMOVE:
+      if (len < 8)
+	return NULL; /* not enough bytes left for complete marker segment */
+      return p + 8;
+    case MARKER_COMMENT:
+      if (len < 6)
+	return NULL; /* not enough bytes left for complete marker segment */
+      l = (((long) p[2] << 24) | ((long) p[3] << 16) |
+	   ((long) p[4] <<  8) |  (long) p[5]);
+      if (len - 6 < l)
+	return NULL; /* not enough bytes left for complete marker segment */
+      return p + 6 + l;
+    default:
+      /* unknown marker sequence encountered */
+      return NULL;
+    }
+  }
+
+  return p;
+}
+
+
+/*
+ * Scan a complete BIE for a NEWLEN marker segment, then read the new
+ * YD value found in it and use it to overwrite the one in the BIE
+ * header. Use this procedure if a BIE initially declares an
+ * unreasonably high provisional YD value (e.g., 0xffffffff) or
+ * depends on the fact that section 6.2.6.2 of ITU-T T.82 says that a
+ * NEWLEN marker segment "could refer to a line in the immediately
+ * preceding stripe due to an unexpected termination of the image or
+ * the use of only such stripe". ITU-T.85 explicitely suggests the
+ * use of this for fax machines that start transmission before having
+ * encountered the end of the page. None of this is necessary for
+ * BIEs produced by JBIG-KIT, which normally does not use NEWLEN.
+ */
+int jbg_newlen(unsigned char *bie, size_t len)
+{
+  unsigned char *p = bie + 20;
+  int i;
+  unsigned long y, yn;
+
+  if (len < 20)
+    return JBG_EAGAIN;
+  if ((bie[19] & (JBG_DPON | JBG_DPPRIV | JBG_DPLAST))
+      == (JBG_DPON | JBG_DPPRIV))
+    p += 1728; /* skip DPTABLE */
+  if (p >= bie + len)
+    return JBG_EAGAIN;
+
+  while ((p = jbg_next_pscdms(p, len - (p - bie)))) {
+    if (p == bie + len)
+      return JBG_EOK;
+    else if (p[0] == MARKER_ESC)
+      switch (p[1]) {
+      case MARKER_NEWLEN:
+	y = (((long) bie[ 8] << 24) | ((long) bie[ 9] << 16) |
+	     ((long) bie[10] <<  8) |  (long) bie[11]);
+	yn = (((long) p[2] << 24) | ((long) p[3] << 16) |
+	      ((long) p[4] <<  8) |  (long) p[5]);
+	if (yn > y) return JBG_EINVAL | 12;
+	/* overwrite YD in BIH with YD from NEWLEN */
+	for (i = 0; i < 4; i++) {
+	  bie[8+i] = p[2+i];
+	}
+	return JBG_EOK;
+      case MARKER_ABORT:
+	return JBG_EABORT;
+      }
+  }
+  return JBG_EINVAL | 0;
+}
diff --git a/converter/other/jbig/libjbig/jbig.txt b/converter/other/jbig/libjbig/jbig.txt
new file mode 100644
index 00000000..bdc14b17
--- /dev/null
+++ b/converter/other/jbig/libjbig/jbig.txt
@@ -0,0 +1,810 @@
+
+Using the JBIG-KIT library
+--------------------------
+
+Markus Kuhn -- 2013-09-10
+
+
+This text explains how to use the functions provided by the JBIG-KIT
+portable image compression library jbig.c in your application
+software. The jbig.c library is a full-featured implementation of the
+JBIG1 standard aimed at applications that can hold the entire
+uncompressed and compressed image in RAM.
+
+[For applications that require only the single-bit-per-pixel "fax
+subset" of the JBIG1 standard defined in ITU-T Recommendation T.85
+<http://www.itu.int/rec/T-REC-T.85/en>, the alternative implementation
+found in jbig85.c may be preferable. It keeps not more than three
+lines of the uncompressed image in RAM, which makes it particularly
+suitable for embedded applications. For information on how to use
+jbig85.c, please refer to the separate documentation file jbig85.txt.]
+
+
+1  Introduction to JBIG
+
+We start with a short introduction to JBIG1. More detailed information
+is provided in the "Introduction and overview" section of the JBIG1
+standard. Information on how to obtain a copy of the standard is
+available from <http://www.itu.int/rec/T-REC-T.82/en> or
+<http://www.iso.ch/>.
+
+Image data encoded with the JBIG algorithm is separated into planes,
+layers, and stripes. Each plane contains one bit per pixel. The number
+of planes stored in a JBIG data stream is the number of bits per
+pixel. Resolution layers are numbered from 0 to D with 0 being the
+layer with the lowest resolution and D the one with the highest. Each
+next higher resolution layer has twice the number of rows and columns.
+Layer 0 is encoded independently of any other data, all other
+resolution layers are encoded as only the difference between the next
+lower and the current layer. For applications that require very quick
+access to parts of an image, it is possible to divide an image into
+several horizontal stripes. All stripes of one resolution layer have
+equal size, except perhaps the final one. The number of stripes of an
+image is equal in all resolution layers and in all bit planes.
+
+The compressed data stream specified by the JBIG standard is called a
+bi-level image entity (BIE). A BIE consists of a 20-byte header,
+followed by an optional 1728-byte table (usually not present, except
+in special applications) followed by a sequence of stripe data
+entities (SDE). Each SDE encodes the content of one single stripe in
+one plane of one resolution layer. Between the SDEs, other information
+blocks (called floating marker segments) can also be present. They are
+used to change certain parameters of the algorithm in the middle of an
+image or contain additional application specific information. A BIE
+looks like this:
+
+
+          +------------------------------------------------+
+          |                                                |
+          |  20-byte header (with image size, #planes,     |
+          |  #layers, stripe size, first layer, options,   |
+          |  SDE ordering, ...)                            |
+          |                                                |
+          +------------------------------------------------+
+          |                                                |
+          |           optional 1728-byte table             |
+          |                                                |
+          +------------------------------------------------+
+          |                                                |
+          |       optional floating marker segments        |
+          |                                                |
+          +------------------------------------------------+
+          |                                                |
+          |              stripe data entity                |
+          |                                                |
+          +------------------------------------------------+
+          |                                                |
+          |       optional floating marker segments        |
+          |                                                |
+          +------------------------------------------------+
+          |                                                |
+          |              stripe data entity                |
+          |                                                |
+          +------------------------------------------------+
+            ...
+          +------------------------------------------------+
+          |                                                |
+          |              stripe data entity                |
+          |                                                |
+          +------------------------------------------------+
+
+
+One BIE can contain all resolution layers of an image, but it is also
+possible to store various resolution layers in several BIEs. The BIE
+header contains the number of the first and the last resolution layer
+stored in this BIE, as well as the size of the highest resolution
+layer stored in this BIE. Progressive coding is deactivated by simply
+storing the image in one single resolution layer.
+
+Different applications might have different requirements for the order
+in which the SDEs for stripes of various planes and layers are stored
+in the BIE, so all possible sensible orderings are allowed by the
+standard and indicated by four bits in the header.
+
+It is possible to use the raw BIE data stream as specified by the JBIG
+standard directly as the format of a file used for storing images.
+This is what the pbmtojbg, jbgtopbm, pbmtojbg85, and jbgtopbm85
+conversion tools do that are provided in this package as demonstration
+applications. However, as the BIE format has been designed for a large
+number of very different applications, and to allow efficient direct
+processing by special JBIG hardware chip implementations, the BIE
+header contains only the minimum amount of information absolutely
+required by the decompression algorithm. Many features expected from a
+good file format are missing in the BIE data stream:
+
+  - no "magic code" in the first few bytes to allow identification
+    of the file format on a typeless file system and to allow
+    automatic distinction from other compression algorithms
+
+  - no standardized way to encode additional information such as a
+    textual description, information about the meaning of various bit
+    planes, the physical size and resolution of the document, etc.
+
+  - a checksum to ensure image integrity
+
+  - encryption and signature mechanisms
+
+  - many things more
+
+Raw BIE data streams alone may therefore not be a suitable format for
+document archiving and exchange. A standard format for this purpose
+would typically combine a BIE representing the image data with an
+additional header providing auxiliary information into one file.
+Existing established multi-purpose file formats with a rich set of
+auxiliary information attributes like TIFF could be extended easily to
+also hold JBIG compressed data.
+
+On the other hand, in e.g. database applications, a BIE might be
+stored directly in a binary variable-length field. Auxiliary
+information would then be stored in other fields of the same record,
+to simplify search operations.
+
+
+2  Compressing an image
+
+2.1  Format of the source image
+
+To be processed by the jbig.c encoder, the image has to be present in
+memory as separate bitmap planes. Each byte of a bitmap contains eight
+pixels, where the most significant bit represents the leftmost of
+these. Each line of a bitmap has to be stored in an integral number of
+bytes. If the image width is not an integral multiple of eight, then
+the final byte has to be padded with zero bits.
+
+For example the 23x5 pixels large single plane image:
+
+   .XXXXX..XXX...X...XXX..
+   .....X..X..X..X..X.....
+   .....X..XXX...X..X.XXX.
+   .X...X..X..X..X..X...X.
+   ..XXX...XXX...X...XXX..
+
+is represented by the 15 bytes
+
+   01111100 11100010 00111000
+   00000100 10010010 01000000
+   00000100 11100010 01011100
+   01000100 10010010 01000100
+   00111000 11100010 00111000
+
+or in hexadecimal notation
+
+   7c e2 38 04 92 40 04 e2 5c 44 92 44 38 e2 38
+
+This is the format used in binary PBM files and it can also be handled
+directly by the Xlib library of the X Window System.
+
+As JBIG can also handle images with multiple bit planes, the jbig.c
+library functions accept and return always arrays of pointers to
+bitmaps with one pointer per plane.
+
+For single-plane images, the standard recommends that a 0 pixel
+represents the background and a 1 pixel represents the foreground
+colour of an image, in other words, 0 is white and 1 is black for
+scanned paper documents. For images with several bits per pixel, the
+JBIG standard makes no recommendations about how various colours should
+be encoded.
+
+For grey-scale images, by using a Gray code instead of a simple binary
+weighted representation of the pixel intensity, some increase in
+coding efficiency can be reached.
+
+A Gray code is also a binary representation of integer numbers, but it
+has the property that the representations of the integer numbers i and
+(i+1) always differ in exactly one bit. For example, the numbers 0 to
+7 can be represented in normal binary code and Gray code as in the
+following table:
+
+                           normal
+              number    binary code     Gray code
+            ---------------------------------------
+                0           000            000
+                1           001            001
+                2           010            011
+                3           011            010
+                4           100            110
+                5           101            111
+                6           110            101
+                7           111            100
+
+The form of Gray code shown above has the property that the second
+half of the code (numbers 4 - 7) is simply the mirrored first half
+(numbers 3 - 0) with the first bit set to one. This way, arbitrarily
+large Gray codes can be generated quickly by mirroring the above
+example and prefixing the first half with zeros and the second half
+with ones as often as required. In grey-scale images, it is common
+practise to use the all-0 code for black and the all-1 code for white.
+
+No matter whether a Gray code or a binary code is used for encoding a
+pixel intensity in several bit planes, it always makes sense to store
+the most significant (leftmost) bit in plane 0, which is transmitted
+first. This way, a decoder could increase the precision of the
+displayed pixel intensities while data is still being received and the
+basic structure of the image will become visible as early as possible
+during the transmission.
+
+
+2.2  A simple compression application
+
+In order to use jbig.c in your application, just link libjbig.a to
+your executable (on Unix systems just add -ljbig and -L. to the
+command line options of your compiler, on other systems you will have
+to write a new Makefile anyway), copy the file jbig.h into your source
+directory and put the line
+
+  #include "jbig.h"
+
+into your source code.
+
+The library interface follows object-oriented programming principles.
+You have to declare a variable (object)
+
+  struct jbg_enc_state s;
+
+which contains the current status of an encoder. Then you initialize
+the encoder by calling the constructor function
+
+  void jbg_enc_init(struct jbg_enc_state *s, unsigned long x, unsigned long y,
+                    int pl, unsigned char **p,
+                    void (*data_out)(unsigned char *start, size_t len,
+                                     void *file),
+                    void *file);
+
+The parameters have the following meaning:
+
+  s             A pointer to the jbg_enc_state structure that you want
+                to initialize.
+
+  x             The width of your image in pixels.
+
+  y             The height of your image in pixels (lines).
+
+  pl            the number of bitmap planes you want to encode.
+
+  p             A pointer to an array of pl pointers, where each is again
+                pointing to the first byte of a bitmap as described in
+                section 2.1.
+
+  data_out      This is a call-back function that the encoder will
+                call during the compression process by in order to
+                deliver the BIE data to your application. The
+                parameters of the function data_out are a pointer
+                start to the new block of data being delivered, as
+                well as the number len of delivered bytes. The pointer
+                file is transparently delivered to data_out, as
+                specified in jbg_enc_init(). Typically, data_out will
+                write the BIE portion to a file, send it to a network
+                connection, or append it to some memory buffer.
+
+  file          A pointer parameter that is passed on to data_out()
+                and can be used, for instance, to allow data_out() to
+                distinguish by which compression task it has been
+                called in multi-threaded applications.
+
+In the simplest case, the compression is then started by calling the
+function
+
+  void jbg_enc_out(struct jbg_enc_state *s);
+
+which will deliver the complete BIE to data_out() in several calls.
+After jbg_enc_out has returned, a call to the destructor function
+
+  void jbg_enc_free(struct jbg_enc_state *s);
+
+will release any heap memory allocated by the previous functions.
+
+
+A minimal example application, which sends the BIE of the above bitmap
+to stdout, looks like this:
+
+---------------------------------------------------------------------------
+/* A sample JBIG encoding application */
+
+#include <stdio.h>
+#include "jbig.h"
+
+void output_bie(unsigned char *start, size_t len, void *file)
+{
+  fwrite(start, 1, len, (FILE *) file);
+  
+  return;
+}
+
+int main()
+{
+  unsigned char bitmap[15] = {
+    /* 23 x 5 pixels, "JBIG" */
+    0x7c, 0xe2, 0x38, 0x04, 0x92, 0x40, 0x04, 0xe2,
+    0x5c, 0x44, 0x92, 0x44, 0x38, 0xe2, 0x38
+  };
+  unsigned char *bitmaps[1] = { bitmap };
+  struct jbg_enc_state se;
+  
+  jbg_enc_init(&se, 23, 5, 1, bitmaps, 
+	       output_bie, stdout);              /* initialize encoder */
+  jbg_enc_out(&se);                                    /* encode image */
+  jbg_enc_free(&se);                    /* release allocated resources */
+  
+  return 0;
+}
+---------------------------------------------------------------------------
+
+This software produces a 42 byte long BIE. (JBIG is not very good at
+compressing extremely small images like in this example, because the
+arithmetic encoder requires some startup data in order to generate
+reasonable statistics which influence the compression process and
+because there is some header overhead.)
+
+
+2.3  More about compression
+
+If jbg_enc_out() is called directly after jbg_enc_init(), the
+following default values are used for various compression parameters:
+
+  - Only one single resolution layer is used, i.e. no progressive
+    mode.
+
+  - The number of lines per stripe is selected so that approximately
+    35 stripes per image are used (as recommended in annex C of the
+    standard together with the suggested adaptive template change
+    algorithm). However, not less than 2 and not more than 128 lines
+    are used in order to stay within the suggested minimum parameter
+    support range specified in annex A of the standard).
+
+  - All optional parts of the JBIG algorithm are activated (TPBON,
+    TPDON and DPON).
+
+  - The default resolution reduction table and the default deterministic
+    prediction table are used
+
+  - The maximal vertical offset of the adaptive template pixel is 0
+    and the maximal horizontal offset is 8 (mx = 8, my = 0).
+
+In order to change any of these default parameters, additional
+functions have to be called between jbg_enc_init() and jbg_enc_out().
+
+In order to activate progressive encoding, it is possible to specify
+with 
+
+  void jbg_enc_layers(struct jbg_enc_state *s, int d);
+
+the number d of differential resolution layers which shall be encoded
+in addition to the lowest resolution layer 0. For example, if a
+document with 60-micrometer pixels has to be stored, and the lowest
+resolution layer shall have 240-micrometer pixels, so that a screen
+previewer can directly decompress only the required resolution, then a
+call
+
+  jbg_enc_layers(&se, 2);
+
+will cause three layers with 240, 120 and 60 micrometers resolution to
+be generated.
+
+If the application does not know what typical resolutions are used and
+simply wants to ensure that the lowest resolution layer will fit into
+a given maximal window size, then as an alternative, a call to
+
+  int jbg_enc_lrlmax(struct jbg_enc_state *s, unsigned long mwidth,
+                     unsigned long mheight);
+
+will cause the library to automatically determine the suitable number
+of resolutions so that the lowest resolution layer 0 will not be
+larger than mwidth x mheight pixels. E.g. if one wants to ensure that
+systems with a 640 x 480 pixel large screen can decode the required
+resolution directly, then call
+
+  jbg_enc_lrlmax(&se, 640, 480);
+
+The return value is the number of differential layers selected.
+
+After the number of resolution layers has been specified by calls to
+jbg_enc_layers() or jbg_enc_lrlmax(), by default, all these layers
+will be written into the BIE. This can be changed with a call to
+
+  int  jbg_enc_lrange(struct jbg_enc_state *s, int dl, int dh);
+
+Parameter dl specifies the lowest resolution layer and dh the highest
+resolution layer that will appear in the BIE. For instance, if layer 0
+shall be written to the first BIE and layer 1 and 2 shall be written
+to a second one, then before writing the first BIE, call
+
+  jbg_enc_lrange(&se, 0, 0);
+
+and before writing the second BIE with jbg_enc_out(), call
+
+  jbg_enc_lrange(&se, 1, 2);
+
+If any of the parameters is negative, it will be ignored. The return
+value is the total number of differential layers that will represent
+the input image. This way, jbg_enc_lrange(&se, -1, -1) can be used to
+query the layer of the full image resolution.
+
+A number of other more exotic options of the JBIG algorithm can be
+modified by calling
+
+  void jbg_enc_options(struct jbg_enc_state *s, int order, int options,
+                       long l0, int mx, int my);
+
+before calling jbg_enc_out().
+
+The order parameter can be a combination of the bits JBG_HITOLO,
+JBG_SEQ, JBG_ILEAVE and JBG_SMID and it determines in which order
+the SDEs are stored in the BIE. The bits have the following meaning:
+
+  JBG_HITOLO   Usually, the lower resolution layers are stored before
+               the higher resolution layers, so that a decoder can
+               already start to display a low resolution version of
+               the full image once a prefix of the BIE has been
+               received. When this bit is set, however, the BIE will
+               contain the higher layers before the lower layers. This
+               avoids additional buffer memory in the encoder and is
+               intended for applications where the encoder is connected
+               to a database which can easily reorder the SDEs before
+               sending them to a decoder. Warning: JBIG decoders are
+               not expected to support the HITOLO option (e.g. the
+               jbig.c decoder currently does not) so you should
+               normally not use it.
+
+  JBG_SEQ      Usually, at first all stripes of one resolution layer
+               are written to the BIE and then all stripes of the next
+               layer, and so on. When the SEQ bit is set however, then
+               all layers of the first stripe will be written,
+               followed by all layers of the second stripe, etc. This
+               option also should normally never be required and is
+               not supported by the current jbig.c decoder.
+
+  JBG_SMID     In case there exist several bit planes, then the order of
+               the stripes is determined by three loops over all stripes,
+               all planes and all layers. When SMID is set, the loop
+               over all stripes is the middle loop.
+
+  JBG_ILEAVE   If this bit is set, then at first all layers of one
+               plane are written before the encoder starts with the next
+               plane.
+
+The above description may be somewhat confusing, but the following
+table (see also Table 11 in ITU-T T.82) clarifies how the three bits
+JBG_SEQ, JBIG_ILEAVE and JBG_SMID influence the ordering of the loops
+over all stripes, planes and layers:
+
+
+                                                 Loops:
+    JBG_SEQ   JBG_ILEAVE   JBG_SMID   |  Outer   Middle    Inner
+  ------------------------------------+---------------------------
+       0           0           0      |    p        d        s
+       0           1           0      |    d        p        s
+       0           1           1      |    d        s        p
+       1           0           0      |    s        p        d
+       1           0           1      |    p        s        d
+       1           1           0      |    s        d        p
+
+                                       p: plane, s: stripe, d: layer
+
+
+By default, the order combination JBG_ILEAVE | JBG_SMID is used.
+
+The options value can contain the following bits, which activate
+some of the optional algorithms defined by JBIG:
+
+  JBG_LRLTWO     Normally, in the lowest resolution layer, pixels
+                 from three lines around the next pixel are used
+                 in order to determine the context in which the next
+                 pixel is encoded. Some people in the JBIG committee
+                 seem to have argued that using only 2 lines will
+                 make software implementations a little bit faster,
+                 however others have argued that using only two lines
+                 will decrease compression efficiency by around 5%.
+                 As you might expect from a committee, now both
+                 alternatives are allowed and if JBG_LRLTWO is set,
+                 the slightly faster but 5% less well compressing two
+                 line alternative is selected. God bless the committees.
+                 Although probably nobody will ever need this option,
+                 it has been implemented in jbig.c and is off by
+                 default.
+
+  JBG_TPDON      This activates the "typical prediction" algorithm
+                 for differential layers which avoids that large
+                 areas of equal colour have to be encoded at all.
+                 This is on by default and there is no good reason to
+                 switch it off except for debugging or preparing data
+                 for cheap JBIG hardware that might not support this
+                 option.
+
+  JBG_TPBON      Like JBG_TPDON this activates the "typical prediction"
+                 algorithm in the lowest resolution layer. Also activated
+                 by default.
+
+  JBG_DPON       This bit activates for the differential resolution
+                 layers the "deterministic prediction" algorithm,
+                 which avoids that higher resolution layer pixels are
+                 encoded when their value can already be determined
+                 with the knowledge of the neighbour pixels, the
+                 corresponding lower resolution pixels and the
+                 resolution reduction algorithm. This is also
+                 activated by default and one reason for deactivating
+                 it would be if the default resolution reduction
+                 algorithm were replaced by another one.
+
+  JBG_DELAY_AT   Use a slightly less efficient algorithm to determine
+                 when an adaptive template change is necessary. With
+                 this bit set, the encoder output is compatible to the
+                 conformance test examples in cause 7.2 of ITU-T T.82.
+                 Then all adaptive template changes are delayed until
+                 the first line of the next stripe. This option is by
+                 default deactivated and is only required for passing a
+                 special compatibility test suite.
+
+In addition, parameter l0 in jbg_enc_options() allows you to specify
+the number of lines per stripe in resolution layer 0. The parameters
+mx and my change the maximal offset allowed for the adaptive template
+pixel. JBIG-KIT now supports the full range of possible mx values up
+to 127 in the encoder and decoder, but my is at the moment ignored and
+always set to 0. As the standard requires of all decoder
+implementations only to support maximum values mx = 16 and my = 0,
+higher values should normally be avoided in order to guarantee
+interoperability. The ITU-T T.85 profile for JBIG in fax machines
+requires support for mx = 127 and my = 0. Default is mx = 8 and my =
+0. If any of the parameters order, options, mx or my is negative, or
+l0 is zero, then the corresponding current value remains unmodified.
+
+The resolution reduction and deterministic prediction tables can also
+be replaced. However as these options are anyway only for experts,
+please have a look at the source code of jbg_enc_out() and the struct
+members dppriv and res_tab of struct jbg_enc_state for the details of
+how to do this, in case you really need it. The functions
+jbg_int2dppriv and jbg_dppriv2int are provided in order to convert the
+DPTABLE data from the format used in the standard into the more
+efficient format used internally by JBIG-KIT.
+
+If you want to encode a grey-scale image, you can use the library
+function
+
+  void jbg_split_planes(unsigned long x, unsigned long y, int has_planes,
+                        int encode_planes,
+                        const unsigned char *src, unsigned char **dest,
+                        int use_graycode);
+
+It separates an image in which each pixel is represented by one or
+more bytes into separate bit planes. The dest array of pointers to
+these bit planes can then be handed over to jbg_enc_init(). The
+variables x and y specify the width and height of the image in pixels,
+and has_planes specifies how many bits per pixel are used. As each
+pixel is represented by an integral number of consecutive bytes, of
+which each contains up to eight bits, the total length of the input
+image array src[] will therefore be x * y * ((has_planes + 7) / 8)
+bytes. The pixels are stored as usually in English reading order, and
+for each pixel the integer value is stored with the most significant
+byte coming first (Bigendian). This is exactly the format used in raw
+PGM files. In encode_planes, the number of bit planes that shall be
+extracted can be specified. This allows for instance to extract only
+the most significant 8 bits of a 12-bit image, where each pixel is
+represented by two bytes, by specifying has_planes = 12 and
+encode_planes = 8. If use_graycode is zero, then the binary code of
+the pixel integer values will be used instead of the Gray code. Plane
+0 contains always the most significant bit.
+
+
+3  Decompressing an image
+
+Like with the compression functions, if you want to use the jbig.c
+library, you have to put the line
+
+  #include "jbig.h"
+
+into your source code and link your executable with libjbig.a.
+
+The state of a JBIG decoder is stored completely in a struct and you
+will have to define a variable like
+
+  struct jbg_dec_state sd;
+
+which is initialized by a call to
+
+  void jbg_dec_init(struct jbg_dec_state *s);
+
+After this, you can directly start to pass data from the BIE to the decoder
+by calling the function
+
+  int jbg_dec_in(struct jbg_dec_state *s, unsigned char *data, size_t len,
+                 size_t *cnt);
+
+The pointer data points to the first byte of a data block with length
+len, which contains bytes from a BIE. It is not necessary to pass a
+whole BIE at once to jbg_dec_in(), it can arrive fragmented in any way
+by calling jbg_dec_in() several times. It is also possible to send
+several BIEs concatenated to jbg_dec_in(), however these then have to
+fit together. If you send several BIEs to the decoder, the lowest
+resolution layer in each following BIE has to be the highest
+resolution layer in the previous BIE plus one and the image sizes and
+number of planes also have to fit together, otherwise jbg_dec_in()
+will return the error JBG_ENOCONT after the header of the new BIE has
+been received completely.
+
+If pointer cnt is not NULL, then the number of bytes actually read
+from the data block will be stored there. In case the data block did
+not contain the end of the BIE, then the value JBG_EAGAIN will be
+returned and *cnt equals len.
+
+Once the end of a BIE has been reached, the return value of
+jbg_dec_in() will be JBG_EOK. After this has happened, the functions
+and macros
+
+  unsigned long jbg_dec_getwidth(struct jbg_dec_state *s);
+  unsigned long jbg_dec_getheight(struct jbg_dec_state *s);
+  int jbg_dec_getplanes(struct jbg_dec_state *s);
+  unsigned char *jbg_dec_getimage(struct jbg_dec_state *s, int plane);
+  unsigned long jbg_dec_getsize(struct jbg_dec_state *s);
+
+can be used to query the dimensions of the now completely decoded
+image and to get a pointer to all bitmap planes. The bitmaps are
+stored as described in section 2.1. The function jbg_dec_getsize()
+calculates the number of bytes which one bitmap requires.
+
+The function
+
+  void jbg_dec_merge_planes(const struct jbg_dec_state *s, int use_graycode,
+                            void (*data_out)(unsigned char *start, size_t len,
+                                             void *file), void *file);
+
+allows you to merge the bit planes that can be accessed individually
+with jbg_dec_getimage() into an array with one or more bytes per pixel
+(i.e., the format provided to jbg_split_planes()). If use_graycode is
+zero, then a binary encoding will be used. The output array will be
+delivered via the callback function data_out, exactly in the same way
+in which the encoder provides the BIE. The function
+
+  unsigned long jbg_dec_getsize_merged(const struct jbg_dec_state *s);
+
+determines how long the data array delivered by jbg_dec_merge_planes()
+is going to be.
+
+Before calling jbg_dec_in() the first time, it is possible to specify with
+a call to
+
+  void jbg_dec_maxsize(struct jbg_dec_state *s, unsigned long xmax,
+                       unsigned long ymax);
+
+an abort criterion for progressively encoded images. For instance if an
+application will display a whole document on a screen which is 1024 x
+768 pixels large, then this application should call
+
+  jbg_dec_maxsize(&sd, 1024, 768);
+
+before the decoding process starts. If the image has been encoded in
+progressive mode (i.e. with several resolution layers), then the
+decoder will stop with a return value JBG_EOK_INTR after the largest
+resolution layer that is still smaller than 1024 x 768. However this
+is no guarantee that the image which can then be read out using
+jbg_dec_getimage(), etc. is really not larger than the specified
+maximal size. The application will have to check the size of the
+image, because the decoder does not automatically apply a resolution
+reduction if no suitable resolution layer is available in the BIE.
+
+If jbg_dec_in() returned JBG_EOK_INTR or JBG_EOK, then it is possible
+to continue calling jbg_dec_in() with the remaining data in order to
+either decode the remaining resolution layers of the current BIE or in
+order to add another BIE with additional resolution layers. In both
+cases, after jbg_dec_in() returned JBG_EOK_INTR or JBG_EOK, *cnt is
+probably not equal to len and the remainder of the data block which
+has not yet been processed by the decoder has to be delivered to
+jbg_dec_in() again.
+
+If any other return value than JBG_EOK, JBG_EOK_INTR or JBG_EAGAIN
+has been returned by jbg_dec_in(), then an error has occurred and
+
+  void jbg_dec_free(struct jbg_dec_state *s);
+
+should be called in order to release any allocated memory. The
+destructor jbg_dec_free() should of course also be called, once the
+decoded bitmap returned by jbg_dec_getimage() is no longer required
+and the memory can be released.
+
+The function
+
+  const char *jbg_strerror(int errnum);
+
+returns a pointer to a short single line test message that explains
+the return value of jbg_dec_in(). This message can be used in order to
+provide the user a brief informative message about what when wrong
+while decompressing a JBIG image. The po/ subdirectory contains *.po
+files that translate the English ASCII strings returned by
+jbg_strerror() into other languages (e.g., for use with GNU gettext).
+The four least-significant bits of the return value of jbg_dec_in()
+may contain additional detailed technical information about the exact
+test that spotted the error condition (see source code for details),
+i.e. more than the text message returned by jbg_strerror() reveals.
+Therefore it may be useful to display the return value itself as a
+hexadecimal number, in addition to the string returned by
+jbg_strerror().
+
+The current implementation of the jbig.c decoder has the following
+limitations:
+
+  - The maximal vertical offset MY of the adaptive template pixel
+    must be zero.
+
+  - HITOLO and SEQ bits must not be set in the order value.
+
+  - Not more than JBG_ATMOVES_MAX (currently set to 64) ATMOVE
+    marker segments can be handled per stripe.
+
+  - the number D of differential layers must be less than 32
+
+None of the above limitations can be exceeded by a JBIG data stream
+that conforms to the ITU-T T.85 application profile for the use of
+JBIG1 in fax machines.
+
+The current implementation of the jbig.c decoder does not impose any
+limits on the image size that it will process, as long as malloc() is
+able to allocate enough heap space for the resulting bitmaps. The only
+exception is that jbg_dec_in() will return "Input data stream uses
+unimplemented JBIG features" (JBG_EIMPL | 1) if Y_D equals 0xffffffff,
+which is an extreme value commonly used to encode images according to
+ITU-T T.85 where the height was unknown when the BIH was emitted.
+After jbg_dec_in() received the 20-byte long BIH at the start of the
+BIE, it will malloc() to allocate enough memory to hold the requested
+image planes and layers. If you want to defend your application
+against excessive image-size parameters in a received BIH, then do
+make sure that you check X_D, Y_D, and P against appropriate safety
+limits before handing over the BIH to jbg_dec_in().
+
+There are two more limitations of the current implementation of the
+jbig.c decoder that might cause problems with processing JBIG data
+stream that conform to ITU-T T.85:
+
+  - The jbig.c decoder was designed to operate incrementally.
+    Each received byte is processed immediately as soon as it arrives.
+    As a result, it does not look beyond the SDRST/SDNORM at the end
+    of all stripes for any immediately following NEWLEN marker that
+    might reduce the number of lines encoded by the current stripe.
+    However section 6.2.6.2 of ITU-T T.82 says that a NEWLEN marker
+    segment "could refer to a line in the immediately preceding stripe
+    due to an unexpected termination of the image or the use of only
+    such stripe", and ITU-T.85 explicitly suggests the use of this
+    for fax machines that start transmission before having encountered
+    the end of the page.
+
+  - The image size initially indicated in the BIE header is used to
+    allocate memory for a bitmap of this size. This means that BIEs
+    that set initially Y_D = 0xffffffff (as suggested in ITU-T T.85
+    for fax machines that do not know the height of the page at the
+    start of the transmission) cannot be decoded directly by this
+    version.
+
+For both issues, there is a workaround available:
+
+If you encounter a BIE that has in the header the VLENGTH=1 option bit
+set, then first wait until you have received the entire BIE and stored
+it in memory. Then call the function
+
+  int jbg_newlen(unsigned char *bie, size_t len);
+
+where bie is a pointer to the first byte of the BIE and len its length
+in bytes. This function will scan the entire BIE for the first NEWLEN
+marker segment. It will then take the updated image-height value YD
+from it and use it to overwrite the YD value in the BIE header. The
+jbg_newlen() can return some of the same error codes as jbg_dec_in(),
+namely JBG_EOK if everything went fine, JBG_EAGAIN is the data
+provided is too short to be a valid BIE, JBG_EINVAL if a format error
+was encountered, and JBG_EABORT if an ABORT marker segment was found.
+After having patched the image-height value in the BIE using
+jbg_newlen(), simply hand over the BIE as usual to jbg_dec_in().
+
+In general, for applications where NEWLEN markers can appear, in
+particular fax reception, you should consider using the jbig85.c
+decoder instead, as it can process BIEs with NEWLEN markers in a
+single pass.
+
+A more detailed description of the JBIG-KIT implementation is
+
+  Markus Kuhn: Effiziente Kompression von bi-level Bilddaten durch
+  kontextsensitive arithmetische Codierung. Studienarbeit, Lehrstuhl
+  für Betriebssysteme, IMMD IV, Universität Erlangen-Nürnberg,
+  Erlangen, July 1995. (German, 62 pages)
+  <http://www.cl.cam.ac.uk/~mgk25/kuhn-sta.pdf>
+
+Please quote the above if you use JBIG-KIT in your research project.
+
+*** Happy compressing ***
+
+[end]
diff --git a/converter/other/jbig/libjbig/jbig_ar.c b/converter/other/jbig/libjbig/jbig_ar.c
new file mode 100644
index 00000000..d23a317d
--- /dev/null
+++ b/converter/other/jbig/libjbig/jbig_ar.c
@@ -0,0 +1,417 @@
+/*
+ *  Arithmetic encoder and decoder of the portable JBIG
+ *  compression library
+ *
+ *  Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+ *
+ *  This module implements a portable standard C arithmetic encoder
+ *  and decoder used by the JBIG lossless bi-level image compression
+ *  algorithm as specified in International Standard ISO 11544:1993
+ *  and ITU-T Recommendation T.82.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 
+ *  If you want to use this program under different license conditions,
+ *  then contact the author for an arrangement.
+ */
+
+#include <assert.h>
+#include "jbig_ar.h"
+
+/*
+ *  Probability estimation tables for the arithmetic encoder/decoder
+ *  given by ITU T.82 Table 24.
+ */
+
+static short lsztab[113] = {
+  0x5a1d, 0x2586, 0x1114, 0x080b, 0x03d8, 0x01da, 0x00e5, 0x006f,
+  0x0036, 0x001a, 0x000d, 0x0006, 0x0003, 0x0001, 0x5a7f, 0x3f25,
+  0x2cf2, 0x207c, 0x17b9, 0x1182, 0x0cef, 0x09a1, 0x072f, 0x055c,
+  0x0406, 0x0303, 0x0240, 0x01b1, 0x0144, 0x00f5, 0x00b7, 0x008a,
+  0x0068, 0x004e, 0x003b, 0x002c, 0x5ae1, 0x484c, 0x3a0d, 0x2ef1,
+  0x261f, 0x1f33, 0x19a8, 0x1518, 0x1177, 0x0e74, 0x0bfb, 0x09f8,
+  0x0861, 0x0706, 0x05cd, 0x04de, 0x040f, 0x0363, 0x02d4, 0x025c,
+  0x01f8, 0x01a4, 0x0160, 0x0125, 0x00f6, 0x00cb, 0x00ab, 0x008f,
+  0x5b12, 0x4d04, 0x412c, 0x37d8, 0x2fe8, 0x293c, 0x2379, 0x1edf,
+  0x1aa9, 0x174e, 0x1424, 0x119c, 0x0f6b, 0x0d51, 0x0bb6, 0x0a40,
+  0x5832, 0x4d1c, 0x438e, 0x3bdd, 0x34ee, 0x2eae, 0x299a, 0x2516,
+  0x5570, 0x4ca9, 0x44d9, 0x3e22, 0x3824, 0x32b4, 0x2e17, 0x56a8,
+  0x4f46, 0x47e5, 0x41cf, 0x3c3d, 0x375e, 0x5231, 0x4c0f, 0x4639,
+  0x415e, 0x5627, 0x50e7, 0x4b85, 0x5597, 0x504f, 0x5a10, 0x5522,
+  0x59eb
+};
+
+static unsigned char nmpstab[113] = {
+    1,   2,   3,   4,   5,   6,   7,   8,
+    9,  10,  11,  12,  13,  13,  15,  16,
+   17,  18,  19,  20,  21,  22,  23,  24,
+   25,  26,  27,  28,  29,  30,  31,  32,
+   33,  34,  35,   9,  37,  38,  39,  40,
+   41,  42,  43,  44,  45,  46,  47,  48,
+   49,  50,  51,  52,  53,  54,  55,  56,
+   57,  58,  59,  60,  61,  62,  63,  32,
+   65,  66,  67,  68,  69,  70,  71,  72,
+   73,  74,  75,  76,  77,  78,  79,  48,
+   81,  82,  83,  84,  85,  86,  87,  71,
+   89,  90,  91,  92,  93,  94,  86,  96,
+   97,  98,  99, 100,  93, 102, 103, 104,
+   99, 106, 107, 103, 109, 107, 111, 109,
+  111
+};
+
+/*
+ * least significant 7 bits (mask 0x7f) of nlpstab[] contain NLPS value,
+ * most significant bit (mask 0x80) contains SWTCH bit
+ */
+static unsigned char nlpstab[113] = {
+  129,  14,  16,  18,  20,  23,  25,  28,
+   30,  33,  35,   9,  10,  12, 143,  36,
+   38,  39,  40,  42,  43,  45,  46,  48,
+   49,  51,  52,  54,  56,  57,  59,  60,
+   62,  63,  32,  33, 165,  64,  65,  67,
+   68,  69,  70,  72,  73,  74,  75,  77,
+   78,  79,  48,  50,  50,  51,  52,  53,
+   54,  55,  56,  57,  58,  59,  61,  61,
+  193,  80,  81,  82,  83,  84,  86,  87,
+   87,  72,  72,  74,  74,  75,  77,  77,
+  208,  88,  89,  90,  91,  92,  93,  86,
+  216,  95,  96,  97,  99,  99,  93, 223,
+  101, 102, 103, 104,  99, 105, 106, 107,
+  103, 233, 108, 109, 110, 111, 238, 112,
+  240
+};
+
+/*
+ * The next functions implement the arithmedic encoder and decoder
+ * required for JBIG. The same algorithm is also used in the arithmetic
+ * variant of JPEG.
+ */
+
+/* marker codes */
+#define MARKER_STUFF    0x00
+#define MARKER_ESC      0xff
+
+void arith_encode_init(struct jbg_arenc_state *s, int reuse_st)
+{
+  int i;
+  
+  if (!reuse_st)
+    for (i = 0; i < 4096; s->st[i++] = 0) ;
+  s->c = 0;
+  s->a = 0x10000L;
+  s->sc = 0;
+  s->ct = 11;
+  s->buffer = -1;    /* empty */
+  
+  return;
+}
+
+
+void arith_encode_flush(struct jbg_arenc_state *s)
+{
+  unsigned long temp;
+
+  /* find the s->c in the coding interval with the largest
+   * number of trailing zero bits */
+  if ((temp = (s->a - 1 + s->c) & 0xffff0000L) < s->c)
+    s->c = temp + 0x8000;
+  else
+    s->c = temp;
+  /* send remaining bytes to output */
+  s->c <<= s->ct;
+  if (s->c & 0xf8000000L) {
+    /* one final overflow has to be handled */
+    if (s->buffer >= 0) {
+      s->byte_out(s->buffer + 1, s->file);
+      if (s->buffer + 1 == MARKER_ESC)
+	s->byte_out(MARKER_STUFF, s->file);
+    }
+    /* output 0x00 bytes only when more non-0x00 will follow */
+    if (s->c & 0x7fff800L)
+      for (; s->sc; --s->sc)
+	s->byte_out(0x00, s->file);
+  } else {
+    if (s->buffer >= 0)
+      s->byte_out(s->buffer, s->file); 
+    /* T.82 figure 30 says buffer+1 for the above line! Typo? */
+    for (; s->sc; --s->sc) {
+      s->byte_out(0xff, s->file);
+      s->byte_out(MARKER_STUFF, s->file);
+    }
+  }
+  /* output final bytes only if they are not 0x00 */
+  if (s->c & 0x7fff800L) {
+    s->byte_out((s->c >> 19) & 0xff, s->file);
+    if (((s->c >> 19) & 0xff) == MARKER_ESC)
+      s->byte_out(MARKER_STUFF, s->file);
+    if (s->c & 0x7f800L) {
+      s->byte_out((s->c >> 11) & 0xff, s->file);
+      if (((s->c >> 11) & 0xff) == MARKER_ESC)
+	s->byte_out(MARKER_STUFF, s->file);
+    }
+  }
+
+  return;
+}
+
+
+void arith_encode(struct jbg_arenc_state *s, int cx, int pix) 
+{
+  register unsigned lsz, ss;
+  register unsigned char *st;
+  long temp;
+
+  assert(cx >= 0 && cx < 4096);
+  st = s->st + cx;
+  ss = *st & 0x7f;
+  assert(ss < 113);
+  lsz = lsztab[ss];
+
+#if 0
+  fprintf(stderr, "pix = %d, cx = %d, mps = %d, st = %3d, lsz = 0x%04x, "
+	  "a = 0x%05lx, c = 0x%08lx, ct = %2d, buf = 0x%02x\n",
+	  pix, cx, !!(s->st[cx] & 0x80), ss, lsz, s->a, s->c, s->ct,
+	  s->buffer);
+#endif
+
+  if (((pix << 7) ^ s->st[cx]) & 0x80) {
+    /* encode the less probable symbol */
+    if ((s->a -= lsz) >= lsz) {
+      /* If the interval size (lsz) for the less probable symbol (LPS)
+       * is larger than the interval size for the MPS, then exchange
+       * the two symbols for coding efficiency, otherwise code the LPS
+       * as usual: */
+      s->c += s->a;
+      s->a = lsz;
+    }
+    /* Check whether MPS/LPS exchange is necessary
+     * and chose next probability estimator status */
+    *st &= 0x80;
+    *st ^= nlpstab[ss];
+  } else {
+    /* encode the more probable symbol */
+    if ((s->a -= lsz) & 0xffff8000L)
+      return;   /* A >= 0x8000 -> ready, no renormalization required */
+    if (s->a < lsz) {
+      /* If the interval size (lsz) for the less probable symbol (LPS)
+       * is larger than the interval size for the MPS, then exchange
+       * the two symbols for coding efficiency: */
+      s->c += s->a;
+      s->a = lsz;
+    }
+    /* chose next probability estimator status */
+    *st &= 0x80;
+    *st |= nmpstab[ss];
+  }
+
+  /* renormalization of coding interval */
+  do {
+    s->a <<= 1;
+    s->c <<= 1;
+    --s->ct;
+    if (s->ct == 0) {
+      /* another byte is ready for output */
+      temp = s->c >> 19;
+      if (temp & 0xffffff00L) {
+	/* handle overflow over all buffered 0xff bytes */
+	if (s->buffer >= 0) {
+	  ++s->buffer;
+	  s->byte_out(s->buffer, s->file);
+	  if (s->buffer == MARKER_ESC)
+	    s->byte_out(MARKER_STUFF, s->file);
+	}
+	for (; s->sc; --s->sc)
+	  s->byte_out(0x00, s->file);
+	s->buffer = temp & 0xff;  /* new output byte, might overflow later */
+	assert(s->buffer != 0xff);
+	/* can s->buffer really never become 0xff here? */
+      } else if (temp == 0xff) {
+	/* buffer 0xff byte (which might overflow later) */
+	++s->sc;
+      } else {
+	/* output all buffered 0xff bytes, they will not overflow any more */
+	if (s->buffer >= 0)
+	  s->byte_out(s->buffer, s->file);
+	for (; s->sc; --s->sc) {
+	  s->byte_out(0xff, s->file);
+	  s->byte_out(MARKER_STUFF, s->file);
+	}
+	s->buffer = temp;   /* buffer new output byte (can still overflow) */
+      }
+      s->c &= 0x7ffffL;
+      s->ct = 8;
+    }
+  } while (s->a < 0x8000);
+ 
+  return;
+}
+
+
+void arith_decode_init(struct jbg_ardec_state *s, int reuse_st)
+{
+  int i;
+  
+  if (!reuse_st)
+    for (i = 0; i < 4096; s->st[i++] = 0) ;
+  s->c = 0;
+  s->a = 1;
+  s->ct = 0;
+  s->startup = 1;
+  s->nopadding = 0;
+  return;
+}
+
+/*
+ * Decode and return one symbol from the provided PSCD byte stream
+ * that starts in s->pscd_ptr and ends in the byte before s->pscd_end.
+ * The context cx is a 12-bit integer in the range 0..4095. This
+ * function will advance s->pscd_ptr each time it has consumed all
+ * information from that PSCD byte.
+ *
+ * If a symbol has been decoded successfully, the return value will be
+ * 0 or 1 (depending on the symbol).
+ *
+ * If the decoder was not able to decode a symbol from the provided
+ * PSCD, then the return value will be -1, and two cases can be
+ * distinguished:
+ *
+ * s->pscd_ptr == s->pscd_end:
+ *
+ *   The decoder has used up all information in the provided PSCD
+ *   bytes. Further PSCD bytes have to be provided (via new values of
+ *   s->pscd_ptr and/or s->pscd_end) before another symbol can be
+ *   decoded.
+ *
+ * s->pscd_ptr == s->pscd_end - 1:
+ * 
+ *   The decoder has used up all provided PSCD bytes except for the
+ *   very last byte, because that has the value 0xff. The decoder can
+ *   at this point not yet tell whether this 0xff belongs to a
+ *   MARKER_STUFF sequence or marks the end of the PSCD. Further PSCD
+ *   bytes have to be provided (via new values of s->pscd_ptr and/or
+ *   s->pscd_end), including the not yet processed 0xff byte, before
+ *   another symbol can be decoded successfully.
+ *
+ * If s->nopadding != 0, the decoder will return -2 when it reaches
+ * the first two bytes of the marker segment that follows (and
+ * terminates) the PSCD, but before decoding the first symbol that
+ * depends on a bit in the input data that could have been the result
+ * of zero padding, and might, therefore, never have been encoded.
+ * This gives the caller the opportunity to lookahead early enough
+ * beyond a terminating SDNORM/SDRST for a trailing NEWLEN (as
+ * required by T.85) before decoding remaining symbols. Call the
+ * decoder again afterwards as often as necessary (leaving s->pscd_ptr
+ * pointing to the start of the marker segment) to retrieve any
+ * required remaining symbols that might depend on padding.
+ *
+ * [Note that each PSCD can be decoded into an infinitely long
+ * sequence of symbols, because the encoder might have truncated away
+ * an arbitrarily long sequence of trailing 0x00 bytes, which the
+ * decoder will append automatically as needed when it reaches the end
+ * of the PSCD. Therefore, the decoder cannot report any end of the
+ * symbol sequence and other means (external to the PSCD and
+ * arithmetic decoding process) are needed to determine that.]
+ */
+
+int arith_decode(struct jbg_ardec_state *s, int cx)
+{
+  register unsigned lsz, ss;
+  register unsigned char *st;
+  int pix;
+
+  /* renormalization */
+  while (s->a < 0x8000 || s->startup) {
+    while (s->ct <= 8 && s->ct >= 0) {
+      /* first we can move a new byte into s->c */
+      if (s->pscd_ptr >= s->pscd_end) {
+	return -1;  /* more bytes needed */
+      }
+      if (*s->pscd_ptr == 0xff) 
+	if (s->pscd_ptr + 1 >= s->pscd_end) {
+	  return -1; /* final 0xff byte not processed */
+	} else {
+	  if (*(s->pscd_ptr + 1) == MARKER_STUFF) {
+	    s->c |= 0xffL << (8 - s->ct);
+	    s->ct += 8;
+	    s->pscd_ptr += 2;
+	  } else {
+	    s->ct = -1; /* start padding with zero bytes */
+	    if (s->nopadding) {
+	      s->nopadding = 0;
+	      return -2; /* subsequent symbols might depend on zero padding */
+	    }
+	  }
+	}
+      else {
+	s->c |= (long)*(s->pscd_ptr++) << (8 - s->ct);
+	s->ct += 8;
+      }
+    }
+    s->c <<= 1;
+    s->a <<= 1;
+    if (s->ct >= 0) s->ct--;
+    if (s->a == 0x10000L)
+      s->startup = 0;
+  }
+
+  st = s->st + cx;
+  ss = *st & 0x7f;
+  assert(ss < 113);
+  lsz = lsztab[ss];
+
+#if 0
+  fprintf(stderr, "cx = %d, mps = %d, st = %3d, lsz = 0x%04x, a = 0x%05lx, "
+	  "c = 0x%08lx, ct = %2d\n",
+	  cx, !!(s->st[cx] & 0x80), ss, lsz, s->a, s->c, s->ct);
+#endif
+
+  if ((s->c >> 16) < (s->a -= lsz))
+    if (s->a & 0xffff8000L)
+      return *st >> 7;
+    else {
+      /* MPS_EXCHANGE */
+      if (s->a < lsz) {
+	pix = 1 - (*st >> 7);
+	/* Check whether MPS/LPS exchange is necessary
+	 * and chose next probability estimator status */
+	*st &= 0x80;
+	*st ^= nlpstab[ss];
+      } else {
+	pix = *st >> 7;
+	*st &= 0x80;
+	*st |= nmpstab[ss];
+      }
+    }
+  else {
+    /* LPS_EXCHANGE */
+    if (s->a < lsz) {
+      s->c -= s->a << 16;
+      s->a = lsz;
+      pix = *st >> 7;
+      *st &= 0x80;
+      *st |= nmpstab[ss];
+    } else {
+      s->c -= s->a << 16;
+      s->a = lsz;
+      pix = 1 - (*st >> 7);
+      /* Check whether MPS/LPS exchange is necessary
+       * and chose next probability estimator status */
+      *st &= 0x80;
+      *st ^= nlpstab[ss];
+    }
+  }
+
+  return pix;
+}