summaryrefslogtreecommitdiffstats
path: root/kernel/kls_jbig
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kls_jbig')
-rw-r--r--kernel/kls_jbig/Makefile.am11
-rw-r--r--kernel/kls_jbig/fmt_codec_jbig.cpp148
-rw-r--r--kernel/kls_jbig/fmt_codec_jbig_defs.h27
-rw-r--r--kernel/kls_jbig/jbig2mem.cpp270
-rw-r--r--kernel/kls_jbig/jbig2mem.h6
-rw-r--r--kernel/kls_jbig/libjbig/ANNOUNCE147
-rw-r--r--kernel/kls_jbig/libjbig/COPYING339
-rw-r--r--kernel/kls_jbig/libjbig/Makefile.am5
-rw-r--r--kernel/kls_jbig/libjbig/jbig.c3190
-rw-r--r--kernel/kls_jbig/libjbig/jbig.h270
-rw-r--r--kernel/kls_jbig/libjbig/jbig_tab.c428
11 files changed, 4841 insertions, 0 deletions
diff --git a/kernel/kls_jbig/Makefile.am b/kernel/kls_jbig/Makefile.am
new file mode 100644
index 0000000..a74686f
--- /dev/null
+++ b/kernel/kls_jbig/Makefile.am
@@ -0,0 +1,11 @@
+SUBDIRS = libjbig
+
+INCLUDES = -I../include -Ilibjbig
+
+pkglib_LTLIBRARIES = libkls_jbig.la
+
+libkls_jbig_la_SOURCES = fmt_codec_jbig.cpp fmt_codec_jbig_defs.h jbig2mem.cpp jbig2mem.h
+
+libkls_jbig_la_LDFLAGS = ${SQ_RELEASE}
+
+libkls_jbig_la_LIBADD = ${SQ_LOCAL_RPATH} -Llibjbig -ljbig \ No newline at end of file
diff --git a/kernel/kls_jbig/fmt_codec_jbig.cpp b/kernel/kls_jbig/fmt_codec_jbig.cpp
new file mode 100644
index 0000000..d1cfa81
--- /dev/null
+++ b/kernel/kls_jbig/fmt_codec_jbig.cpp
@@ -0,0 +1,148 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+
+#include "ksquirrel-libs/fmt_types.h"
+#include "ksquirrel-libs/fmt_utils.h"
+#include "ksquirrel-libs/fileio.h"
+#include "ksquirrel-libs/error.h"
+
+#include "fmt_codec_jbig_defs.h"
+#include "fmt_codec_jbig.h"
+
+#include "../xpm/codec_jbig.xpm"
+
+#include "jbig2mem.h"
+
+fmt_codec::fmt_codec() : fmt_codec_base()
+{}
+
+fmt_codec::~fmt_codec()
+{}
+
+void fmt_codec::options(codec_options *o)
+{
+ o->version = "0.1.1";
+ o->name = "JBIG";
+ o->filter = "*.jbg *.jbig ";
+ o->config = "";
+ o->mime = "";
+ o->mimetype = "image/x-jbig";
+ o->pixmap = codec_jbig;
+ o->readable = true;
+ o->canbemultiple = false;
+ o->writestatic = false;
+ o->writeanimated = false;
+ o->needtempfile = true;
+}
+
+s32 fmt_codec::read_init(const std::string &file)
+{
+ frs.open(file.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ frs.close();
+
+ const char *argv[2] =
+ {
+ file.c_str(),
+ tmp.c_str()
+ };
+
+ if(jbig2mem((char **)argv))
+ return SQE_R_NOMEMORY;
+
+ frs.open(tmp.c_str(), ios::binary | ios::in);
+
+ if(!frs.good())
+ return SQE_R_NOFILE;
+
+ currentImage = -1;
+ read_error = false;
+
+ finfo.animated = false;
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next()
+{
+ currentImage++;
+
+ if(currentImage)
+ return SQE_NOTOK;
+
+ fmt_image image;
+
+ u32 w, h, bpp;
+ frs.readK(&w, sizeof(u32));
+ frs.readK(&h, sizeof(u32));
+ frs.readK(&bpp, sizeof(u32));
+
+ if(bpp != 24)
+ return SQE_R_BADFILE;
+
+ image.w = w;
+ image.h = h;
+ image.bpp = bpp;
+
+ image.compression = "?";
+ image.colorspace = fmt_utils::colorSpaceByBpp(1);
+
+ finfo.image.push_back(image);
+
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_next_pass()
+{
+ return SQE_OK;
+}
+
+s32 fmt_codec::read_scanline(RGBA *scan)
+{
+ RGB rgb;
+ fmt_image *im = image(currentImage);
+ fmt_utils::fillAlpha(scan, im->w);
+
+ for(s32 i = 0;i < im->w;i++)
+ {
+ frs.readK(&rgb, sizeof(RGB));
+ memcpy(scan+i, &rgb, sizeof(RGB));
+ }
+
+ return SQE_OK;
+}
+
+void fmt_codec::read_close()
+{
+ frs.close();
+
+ finfo.meta.clear();
+ finfo.image.clear();
+}
+
+#include "fmt_codec_cd_func.h"
diff --git a/kernel/kls_jbig/fmt_codec_jbig_defs.h b/kernel/kls_jbig/fmt_codec_jbig_defs.h
new file mode 100644
index 0000000..9f9a5bc
--- /dev/null
+++ b/kernel/kls_jbig/fmt_codec_jbig_defs.h
@@ -0,0 +1,27 @@
+/* This file is part of ksquirrel-libs (http://ksquirrel.sf.net)
+
+ Copyright (c) 2005 Dmitry Baryshev <[email protected]>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation;
+ either version 2 of the License, or (at your option) any later
+ version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KSQUIRREL_CODEC_DEFS_jbig
+#define KSQUIRREL_CODEC_DEFS_jbig
+
+// define constants here
+
+#endif
diff --git a/kernel/kls_jbig/jbig2mem.cpp b/kernel/kls_jbig/jbig2mem.cpp
new file mode 100644
index 0000000..9ae1abf
--- /dev/null
+++ b/kernel/kls_jbig/jbig2mem.cpp
@@ -0,0 +1,270 @@
+/*
+ * jbgtopbm - JBIG to Portable Bitmap converter
+ *
+ * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+ *
+ * $Id: jbgtopbm.c,v 1.11 2004-06-11 15:17:49+01 mgk25 Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "jbig.h"
+
+double koeff = 1.0;
+
+void write_it(unsigned char *data, size_t len, void *file)
+{
+ int bb;
+ unsigned char cc;
+
+ FILE *ff = (FILE *)file;
+
+ for(size_t i = 0;i < len;i++)
+ {
+ bb = int(koeff * (*(data+i)));
+
+ if(bb > 255) cc = 255;
+ else cc = bb;
+
+ fwrite(&cc, 1, 1, ff);
+ fwrite(&cc, 1, 1, ff);
+ fwrite(&cc, 1, 1, ff);
+ }
+}
+
+int read_file(unsigned char **buf, size_t *buflen, size_t *len, FILE *f)
+{
+ if (*buflen == 0) {
+ *buflen = 4000;
+ *len = 0;
+ *buf = (unsigned char *) malloc(*buflen);
+ if (!*buf) {
+ fprintf(stderr, "Sorry, not enough memory available!\n");
+ return 0;
+ }
+ }
+ do {
+ *len += fread(*buf + *len, 1, *buflen - *len, f);
+ if (*len == *buflen) {
+ *buflen *= 2;
+ *buf = (unsigned char *) realloc(*buf, *buflen);
+ if (!*buf) {
+ fprintf(stderr, "Sorry, not enough memory available!\n");
+ return 0;
+ }
+ }
+ if (ferror(f)) {
+ perror("Problem while reading input file");
+ return 0;
+ }
+ } while (!feof(f));
+ *buflen = *len;
+ *buf = (unsigned char *) realloc(*buf, *buflen);
+ if (!*buf) {
+ fprintf(stderr, "Oops, realloc failed when shrinking buffer!\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+int jbig2mem (char *argv[])
+{
+ FILE *fin = stdin, *fout = stdout;
+ const char *fnin = NULL, *fnout = NULL;
+ int i, result;
+ struct jbg_dec_state s;
+ unsigned char *buffer, *p;
+ size_t buflen, len, cnt;
+ unsigned long xmax = 4294967295UL, ymax = 4294967295UL, max;
+ int plane = -1, use_graycode = 1, multi = 0;
+
+printf("+JBIG %s, %s\n", argv[0], argv[1]);
+
+ buflen = 8000;
+ buffer = (unsigned char *) malloc(buflen);
+ if (!buffer) {
+ return 1;
+ }
+
+fnin = argv[0];
+fnout = argv[1];
+
+ fin = fopen(fnin, "rb");
+ if (!fin) {
+ free(buffer);
+ return 1;
+ }
+
+ fout = fopen(fnout, "wb");
+ if (!fout) {
+ fclose(fin);
+ free(buffer);
+ return 1;
+ }
+
+ /* send input file to decoder */
+ jbg_dec_init(&s);
+ jbg_dec_maxsize(&s, xmax, ymax);
+ /* read BIH first to check VLENGTH */
+ len = fread(buffer, 1, 20, fin);
+
+ if(len < 20)
+ {
+ fclose(fin);
+ fclose(fout);
+ remove(fnout);
+ return 1;
+ }
+
+ if (buffer[19] & JBG_VLENGTH) {
+ /* VLENGTH = 1 => we might encounter a NEWLEN, therefore read entire
+ * input file into memory and run two passes over it */
+ if(!read_file(&buffer, &buflen, &len, fin))
+ {
+ fclose(fin);
+ fclose(fout);
+ remove(fnout);
+ return 1;
+ }
+ /* scan for NEWLEN marker segments and update BIE header accordingly */
+ result = jbg_newlen(buffer, len);
+ /* feed data to decoder */
+ if (result == JBG_EOK) {
+ p = (unsigned char *) buffer;
+ result = JBG_EAGAIN;
+ while (len > 0 &&
+ (result == JBG_EAGAIN || (result == JBG_EOK && multi))) {
+ result = jbg_dec_in(&s, p, len, &cnt);
+ p += cnt;
+ len -= cnt;
+ }
+ }
+ } else {
+ /* VLENGTH = 0 => we can simply pass the input file directly to decoder */
+ result = JBG_EAGAIN;
+ do {
+ cnt = 0;
+ p = (unsigned char *) buffer;
+ while (len > 0 &&
+ (result == JBG_EAGAIN || (result == JBG_EOK && multi))) {
+ result = jbg_dec_in(&s, p, len, &cnt);
+ p += cnt;
+ len -= cnt;
+ }
+ if (!(result == JBG_EAGAIN || (result == JBG_EOK && multi)))
+ break;
+ len = fread(buffer, 1, buflen, fin);
+ } while (len > 0);
+
+ if (ferror(fin)) {
+ fclose(fin);
+ fclose(fout);
+ remove(fnout);
+ return 1;
+ }
+ }
+ if (result != JBG_EOK && result != JBG_EOK_INTR) {
+ fprintf(stderr, "Problem with input file '%s': %s\n",
+ fnin, jbg_strerror(result, JBG_EN));
+
+ fclose(fout);
+ remove(fnout);
+ return 1;
+ }
+ if (plane >= 0 && jbg_dec_getplanes(&s) <= plane) {
+ fprintf(stderr, "Image has only %d planes!\n", jbg_dec_getplanes(&s));
+ fclose(fout);
+ remove(fnout);
+ return 1;
+ }
+
+ if (jbg_dec_getplanes(&s) == 1 || plane >= 0)
+ {
+ int w, h, bpp = 24;
+
+ w = jbg_dec_getwidth(&s);
+ h = jbg_dec_getheight(&s);
+
+ fwrite(&w, sizeof(int), 1, fout);
+ fwrite(&h, sizeof(int), 1, fout);
+ fwrite(&bpp, sizeof(int), 1, fout);
+
+ unsigned char *d = jbg_dec_getimage(&s, plane < 0 ? 0 : plane), bt;
+
+ int G = 0, index;
+ bool brk = false;
+ unsigned char S1;
+
+ for(int f = 0;f < h;f++)
+ {
+ for(int i = 0, g = 0;;g++)
+ {
+ bt = *(d + G);
+ G++;
+
+ for(int F = 256;F >= 2;F /= 2)
+ {
+ S1 = (unsigned char)(F / 2);
+ index = (bt&S1) ? 0 : 255;
+
+ fwrite(&index, 1, 1, fout);
+ fwrite(&index, 1, 1, fout);
+ fwrite(&index, 1, 1, fout);
+
+ if(++i >= w)
+ {
+ brk = true;
+ break;
+ }
+ }
+
+ if(brk)
+ {
+ brk = false;
+ break;
+ }
+ }
+ }
+ } else {
+ /* write PGM output file */
+ if ((size_t) jbg_dec_getplanes(&s) > sizeof(unsigned long) * 8)
+ {
+ fprintf(stderr, "Image has too many planes (%d)!\n", jbg_dec_getplanes(&s));
+ fclose(fout);
+ jbg_dec_free(&s);
+ return 1;
+ }
+ max = 0;
+ for (i = jbg_dec_getplanes(&s); i > 0; i--)
+ max = (max << 1) | 1;
+
+ int w, h, bpp = 24;
+
+ w = jbg_dec_getwidth(&s);
+ h = jbg_dec_getheight(&s);
+
+ fwrite(&w, sizeof(int), 1, fout);
+ fwrite(&h, sizeof(int), 1, fout);
+ fwrite(&bpp, sizeof(int), 1, fout);
+
+ koeff = 255.0 / max;
+
+ jbg_dec_merge_planes(&s, use_graycode, write_it, fout);
+ }
+
+ /* check for file errors and close fout */
+ if (ferror(fout) || fclose(fout)) {
+ fprintf(stderr, "Problem while writing output file '%s", fnout);
+ perror("'");
+ jbg_dec_free(&s);
+ return 1;
+ }
+
+ jbg_dec_free(&s);
+
+ return 0;
+}
diff --git a/kernel/kls_jbig/jbig2mem.h b/kernel/kls_jbig/jbig2mem.h
new file mode 100644
index 0000000..36ae619
--- /dev/null
+++ b/kernel/kls_jbig/jbig2mem.h
@@ -0,0 +1,6 @@
+#ifndef JBIG2MEM_H
+#define JBIG2MEM_H
+
+int jbig2mem(char *argv[]);
+
+#endif
diff --git a/kernel/kls_jbig/libjbig/ANNOUNCE b/kernel/kls_jbig/libjbig/ANNOUNCE
new file mode 100644
index 0000000..35baa23
--- /dev/null
+++ b/kernel/kls_jbig/libjbig/ANNOUNCE
@@ -0,0 +1,147 @@
+
+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 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/recommendation.asp?type=folders&parent=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.jbig.org/jbighomepage.html
+ 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 is free software under the GNU General Public License. Other
+license arrangements suitable for commercial applications are
+available as well, please contact the author for details. JBIG-KIT
+provides a portable library implemented in ANSI/ISO C for encoding and
+decoding JBIG data streams, along with documentation. The library is
+not intended for 8-bit or 16-bit machine architectures (e.g., old
+MS-DOS C compilers) on which a number of very efficient optimization
+techniques used in this software are not possible. For maximum
+performance, a 32-bit processor is required (64-bit systems work too,
+of course). On architectures with 16-bit pointer arithmetic, only very
+small images can be processed.
+
+Special features of the JBIG-KIT implementation are:
+
+ - 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.
+
+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/kernel/kls_jbig/libjbig/COPYING b/kernel/kls_jbig/libjbig/COPYING
new file mode 100644
index 0000000..a43ea21
--- /dev/null
+++ b/kernel/kls_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/kernel/kls_jbig/libjbig/Makefile.am b/kernel/kls_jbig/libjbig/Makefile.am
new file mode 100644
index 0000000..4fd99b2
--- /dev/null
+++ b/kernel/kls_jbig/libjbig/Makefile.am
@@ -0,0 +1,5 @@
+noinst_LTLIBRARIES = libjbig.la
+
+libjbig_la_SOURCES = jbig.c jbig.h jbig_tab.c
+
+EXTRA_DIST = COPYING ANNOUNCE \ No newline at end of file
diff --git a/kernel/kls_jbig/libjbig/jbig.c b/kernel/kls_jbig/libjbig/jbig.c
new file mode 100644
index 0000000..6d8afa3
--- /dev/null
+++ b/kernel/kls_jbig/libjbig/jbig.c
@@ -0,0 +1,3190 @@
+/*
+ * Portable Free JBIG image compression library
+ *
+ * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/
+ *
+ * $Id: jbig.c,v 1.22 2004-06-11 15:17:06+01 mgk25 Exp $
+ *
+ * This module implements a portable standard C encoder and decoder
+ * using the JBIG lossless bi-level image compression algorithm as
+ * specified in International Standard ISO 11544:1993 or equivalently
+ * as specified in ITU-T Recommendation T.82. See the file jbig.doc
+ * 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.
+ *
+ * It is possible that certain products which can be built using this
+ * software module might form inventions protected by patent rights in
+ * some countries (e.g., by patents about arithmetic coding algorithms
+ * owned by IBM and AT&T in the USA). Provision of this software by the
+ * author does NOT include any licences for any patents. In those
+ * countries where a patent licence is required for certain applications
+ * of this software module, you will have to obtain such a licence
+ * yourself.
+ */
+
+#ifdef DEBUG
+#include <stdio.h>
+#else
+#define NDEBUG
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "jbig.h"
+
+
+/* optional export of arithmetic coder functions for test purposes */
+#define ARITH static
+#ifdef __GNUC__
+#define ARITH_INL static __inline__
+#else
+#define ARITH_INL static
+#endif
+
+#define MX_MAX 127 /* maximal supported 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 " -- Markus Kuhn -- "
+"$Id: jbig.c,v 1.22 2004-06-11 15:17:06+01 mgk25 Exp $ ";
+
+/*
+ * 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 */
+};
+
+unsigned char *jbg_next_pscdms(unsigned char *p, size_t len);
+
+
+/*
+ * Array [language][message] with text string error messages that correspond
+ * to return values from public functions in this library.
+ */
+#define NEMSG 9 /* number of error codes */
+#define NEMSG_LANG 3 /* number of supported languages */
+static const char *errmsg[NEMSG_LANG][NEMSG] = {
+ /* English (JBG_EN) */
+ {
+ "Everything is ok", /* JBG_EOK */
+ "Reached specified maximum size", /* JBG_EOK_INTR */
+ "Unexpected end of data", /* JBG_EAGAIN */
+ "Not enough memory available", /* JBG_ENOMEM */
+ "ABORT marker found", /* JBG_EABORT */
+ "Unknown marker segment encountered", /* JBG_EMARKER */
+ "Incremental BIE does not fit to previous one", /* JBG_ENOCONT */
+ "Invalid data encountered", /* JBG_EINVAL */
+ "Unimplemented features used" /* JBG_EIMPL */
+ },
+ /* German (JBG_DE_8859_1) */
+ {
+ "Kein Problem aufgetreten", /* JBG_EOK */
+ "Angegebene maximale Bildgr\366\337e erreicht", /* JBG_EOK_INTR */
+ "Unerwartetes Ende der Daten", /* JBG_EAGAIN */
+ "Nicht gen\374gend Speicher vorhanden", /* JBG_ENOMEM */
+ "Es wurde eine Abbruch-Sequenz gefunden", /* JBG_EABORT */
+ "Eine unbekannte Markierungssequenz wurde gefunden", /* JBG_EMARKER */
+ "Neue Daten passen nicht zu vorangegangenen Daten", /* JBG_ENOCONT */
+ "Es wurden ung\374ltige Daten gefunden", /* JBG_EINVAL */
+ "Noch nicht implementierte Optionen wurden benutzt" /* JBG_EIMPL */
+ },
+ /* German (JBG_DE_UTF_8) */
+ {
+ "Kein Problem aufgetreten", /* JBG_EOK */
+ "Angegebene maximale Bildgr\303\266\303\237e erreicht", /* JBG_EOK_INTR */
+ "Unerwartetes Ende der Daten", /* JBG_EAGAIN */
+ "Nicht gen\303\274gend Speicher vorhanden", /* JBG_ENOMEM */
+ "Es wurde eine Abbruch-Sequenz gefunden", /* JBG_EABORT */
+ "Eine unbekannte Markierungssequenz wurde gefunden", /* JBG_EMARKER */
+ "Neue Daten passen nicht zu vorangegangenen Daten", /* JBG_ENOCONT */
+ "Es wurden ung\303\274ltige Daten gefunden", /* JBG_EINVAL */
+ "Noch nicht implementierte Optionen wurden benutzt" /* JBG_EIMPL */
+ }
+};
+
+
+
+/*
+ * 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
+
+}
+
+
+
+/*
+ * The next functions implement the arithmedic encoder and decoder
+ * required for JBIG. The same algorithm is also used in the arithmetic
+ * variant of JPEG.
+ */
+
+#ifdef DEBUG
+static long encoded_pixels = 0;
+#endif
+
+ARITH 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;
+}
+
+
+ARITH void arith_encode_flush(struct jbg_arenc_state *s)
+{
+ unsigned long temp;
+
+#ifdef DEBUG
+ fprintf(stderr, " encoded pixels = %ld, a = %05lx, c = %08lx\n",
+ encoded_pixels, s->a, s->c);
+#endif
+
+ /* 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;
+}
+
+
+ARITH_INL void arith_encode(struct jbg_arenc_state *s, int cx, int pix)
+{
+ extern short jbg_lsz[];
+ extern unsigned char jbg_nmps[], jbg_nlps[];
+ register unsigned lsz, ss;
+ register unsigned char *st;
+ long temp;
+
+#ifdef DEBUG
+ ++encoded_pixels;
+#endif
+
+ assert(cx >= 0 && cx < 4096);
+ st = s->st + cx;
+ ss = *st & 0x7f;
+ assert(ss < 113);
+ lsz = jbg_lsz[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 ^= jbg_nlps[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 |= jbg_nmps[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;
+}
+
+
+ARITH 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->result = JBG_OK;
+ s->startup = 1;
+ return;
+}
+
+
+ARITH_INL int arith_decode(struct jbg_ardec_state *s, int cx)
+{
+ extern short jbg_lsz[];
+ extern unsigned char jbg_nmps[], jbg_nlps[];
+ register unsigned lsz, ss;
+ register unsigned char *st;
+ int pix;
+
+ /* renormalization */
+ while (s->a < 0x8000 || s->startup) {
+ if (s->ct < 1 && s->result != JBG_READY) {
+ /* first we have to move a new byte into s->c */
+ if (s->pscd_ptr >= s->pscd_end) {
+ s->result = JBG_MORE;
+ return -1;
+ }
+ if (*s->pscd_ptr == 0xff)
+ if (s->pscd_ptr + 1 >= s->pscd_end) {
+ s->result = JBG_MARKER;
+ return -1;
+ } else {
+ if (*(s->pscd_ptr + 1) == MARKER_STUFF) {
+ s->c |= 0xffL << (8 - s->ct);
+ s->ct += 8;
+ s->pscd_ptr += 2;
+ s->result = JBG_OK;
+ } else
+ s->result = JBG_READY;
+ }
+ else {
+ s->c |= (long)*(s->pscd_ptr++) << (8 - s->ct);
+ s->ct += 8;
+ s->result = JBG_OK;
+ }
+ }
+ s->c <<= 1;
+ s->a <<= 1;
+ --s->ct;
+ if (s->a == 0x10000L)
+ s->startup = 0;
+ }
+
+ st = s->st + cx;
+ ss = *st & 0x7f;
+ assert(ss < 113);
+ lsz = jbg_lsz[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 ^= jbg_nlps[ss];
+ } else {
+ pix = *st >> 7;
+ *st &= 0x80;
+ *st |= jbg_nmps[ss];
+ }
+ }
+ else {
+ /* LPS_EXCHANGE */
+ if (s->a < lsz) {
+ s->c -= s->a << 16;
+ s->a = lsz;
+ pix = *st >> 7;
+ *st &= 0x80;
+ *st |= jbg_nmps[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 ^= jbg_nlps[ss];
+ }
+ }
+
+ return pix;
+}
+
+
+
+/*
+ * 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);
+}
+
+
+/*
+ * 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;
+
+ extern char jbg_resred[], jbg_dptable[];
+
+ 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->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 && my < 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 i, j, y;
+ 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;
+ 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;
+
+ /* initialize arithmetic encoder */
+ se = s->s + plane;
+ arith_encode_init(se, stripe != 0);
+ 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)
+ 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 (stripe == 0)
+ 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 (y > 0) {
+ 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 (y > 0) line_h2 = (long)*(hp - hbpl) << 8;
+ if (y > 1) line_h3 = (long)*(hp - hbpl - hbpl) << 8;
+
+ /* encode line */
+ for (j = 0; j < hx; hp++) {
+ line_h1 |= *hp;
+ if (j < hbpl * 8 - 8 && y > 0) {
+ line_h2 |= *(hp - hbpl + 1);
+ if (y > 1)
+ 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 (y > 1)
+ 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 (y > 1)
+ 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 (y > 0) line_h2 = (long)*(hp - hbpl) << 8;
+ if (y > 1) {
+ 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 (y > 1)
+ 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 (y > 0) {
+ line_h2 |= *(hp - hbpl + 1);
+ if (y > 1)
+ 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(MARKER_SDNORM, s->sde[stripe][layer][plane]);
+
+ /* 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 hx, hy, lx, ly, hbpl, lbpl;
+ unsigned char *hp1, *hp2, *hp3, *lp;
+ unsigned long line_h1, line_h2, line_h3, line_l2;
+ unsigned long i, j;
+ int pix, k, l;
+
+ /* 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 (i = 0; i < ly; i++) {
+ if (2*i + 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;
+ line_l2 |= i ? *(lp-lbpl) : 0;
+ for (k = 0; k < 8 && j + k < lx; k += 4) {
+ if (((j + k) >> 2) < hbpl) {
+ line_h3 |= i ? *hp3 : 0;
+ ++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 allpy the resolution reduction
+ * algorithm in order 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 this logic about which SDE has to be
+ * encoded before resolution reduction is allowed is handled here.
+ * This approach might be a little bit more complex than alternative
+ * ways to do it, but it allows us to do the encoding with the minimal
+ * possible amount of temporary memory.
+ */
+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; j < 8; 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; j < 8; 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];
+ extern char jbg_dptable[];
+
+ /* 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 vor 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_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 a string
+ * written in the selected language and character set.
+ */
+const char *jbg_strerror(int errnum, int language)
+{
+ if (errnum < 0 || errnum >= NEMSG)
+ return "Unknown error code passed to jbg_strerror()";
+ if (language < 0 || language >= NEMSG_LANG)
+ return "Unknown language code passed to jbg_strerror()";
+
+ return errmsg[language][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 were this code
+ * can not 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;
+
+ if (s->x == 0 && s->i == 0 &&
+ (stripe == 0 || s->reset[plane][layer - s->dl])) {
+ s->tx[plane][layer - s->dl] = s->ty[plane][layer - s->dl] = 0;
+ if (s->pseudo)
+ s->lntp[plane][layer - s->dl] = 1;
+ }
+
+#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 (layer == 0) {
+
+ /*
+ * Decode lowest resolution 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];
+ 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 (se->result == JBG_MORE || se->result == JBG_MARKER)
+ 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 'not typical' and has to be coded completely */
+ s->pseudo = 0;
+ } else {
+ /* 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;
+ }
+ }
+
+ /*
+ * 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 (se->result == JBG_MORE || se->result == JBG_MARKER)
+ 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 (se->result == JBG_MORE || se->result == JBG_MARKER)
+ 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) {
+ s->lntp[plane][layer - s->dl] = arith_decode(se, TPDCX);
+ if (se->result == JBG_MORE || se->result == JBG_MARKER)
+ 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 (se->result == JBG_MORE || se->result == JBG_MARKER)
+ 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 a new BIE fragment to the decoder.
+ *
+ * If cnt is not NULL, then *cnt will contain after the call the
+ * number of actually read bytes. If the data was not complete, then
+ * the return value will be JBG_EAGAIN and *cnt == len. In case this
+ * function has returned with JBG_EOK, then it has reached the end of
+ * a BIE but it can be called again with data from the next BIE if
+ * there exists one in order to get to a higher resolution layer. In
+ * case the return value was JBG_EOK_INTR then this function can be
+ * called again with the rest of the BIE, because parsing the BIE has
+ * been interrupted by a jbg_dec_maxsize() specification. In both
+ * cases the remaining len - *cnt bytes of the previous block will
+ * have to passed to this function again (if len > *cnt). In case of
+ * any other return value than JBG_EOK, JBG_EOK_INTR or JBG_EAGAIN, a
+ * serious problem has occured and the only function you should call
+ * is jbg_dec_free() in order to remove the mess (and probably
+ * jbg_strerror() in order to find out what to tell the user).
+ */
+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];
+ extern char jbg_dptable[];
+ size_t dummy_cnt;
+
+ 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;
+ if (s->buffer[1] < s->buffer[0])
+ return JBG_EINVAL;
+ /* test whether this looks like a valid JBIG header at all */
+ if (s->buffer[3] != 0 || (s->buffer[18] & 0xf0) != 0 ||
+ (s->buffer[19] & 0x80) != 0)
+ return JBG_EINVAL;
+ if (s->buffer[0] != s->d + 1)
+ return JBG_ENOCONT;
+ 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;
+ 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;
+ 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 supported 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. */
+ if (s->yd == 0xffffffff)
+ return JBG_EIMPL;
+ if (!s->planes || !s->xd || !s->yd || !s->l0)
+ return JBG_EINVAL;
+ /* prevent uint32 overflow: s->l0 * 2 ^ s->d < 2 ^ 32 */
+ if (s->d > 31 || (s->d != 0 && s->l0 >= (1UL << (32 - s->d))))
+ return JBG_EIMPL;
+ s->mx = s->buffer[16];
+ if (s->mx > 127)
+ return JBG_EINVAL;
+ s->my = s->buffer[17];
+#if 0
+ if (s->my > 0)
+ return JBG_EIMPL;
+#endif
+ s->order = s->buffer[18];
+ if (iindex[s->order & 7][0] < 0)
+ return JBG_EINVAL;
+ /* HITOLO and SEQ currently not yet implemented */
+ if (s->dl != s->d && (s->order & JBG_HITOLO || s->order & JBG_SEQ))
+ return JBG_EIMPL;
+ 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);
+ while (s->bie_len < 20 + 1728 && *cnt < len)
+ s->buffer[s->bie_len++ - 20] = data[(*cnt)++];
+ if (s->bie_len < 20 + 1728)
+ return JBG_EAGAIN;
+ if (!s->dppriv || s->dppriv == jbg_dptable)
+ s->dppriv = (char *) checked_malloc(1728, sizeof(char));
+ jbg_dppriv2int(s->dppriv, s->buffer);
+ }
+
+ /*
+ * 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;
+ if (s->at_ty[s->at_moves] != 0)
+ return JBG_EIMPL;
+ s->at_moves++;
+ } else
+ return JBG_EIMPL;
+ 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 || !(s->options & JBG_VLENGTH))
+ return JBG_EINVAL;
+ 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, "
+ "%d bytes left.\n", 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;
+ }
+
+ }
+ } /* 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.
+ */
+long jbg_dec_getwidth(const struct jbg_dec_state *s)
+{
+ if (s->d < 0)
+ return -1;
+ if (iindex[s->order & 7][LAYER] == 0) {
+ if (s->ii[0] < 1)
+ return -1;
+ 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.
+ */
+long jbg_dec_getheight(const struct jbg_dec_state *s)
+{
+ if (s->d < 0)
+ return -1;
+ if (iindex[s->order & 7][LAYER] == 0) {
+ if (s->ii[0] < 1)
+ return -1;
+ 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.
+ */
+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.
+ */
+long jbg_dec_getsize(const struct jbg_dec_state *s)
+{
+ if (s->d < 0)
+ return -1;
+ if (iindex[s->order & 7][LAYER] == 0) {
+ if (s->ii[0] < 1)
+ return -1;
+ else
+ return
+ jbg_ceil_half(s->xd, s->d - (s->ii[0] - 1) + 3) *
+ 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().
+ */
+long jbg_dec_getsize_merged(const struct jbg_dec_state *s)
+{
+ if (s->d < 0)
+ return -1;
+ if (iindex[s->order & 7][LAYER] == 0) {
+ if (s->ii[0] < 1)
+ return -1;
+ else
+ return
+ jbg_ceil_half(s->xd, s->d - (s->ii[0] - 1)) *
+ 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;
+ extern char jbg_dptable[];
+
+ 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
+ int bpp;
+ 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;
+ bpp = (s->planes + 7) / 8; /* bytes per pixel in dest image */
+ 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.
+ */
+unsigned char *jbg_next_pscdms(unsigned char *p, size_t len)
+{
+ unsigned char *pp;
+ unsigned long l;
+
+ if (len < 2)
+ return NULL;
+
+ 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;
+ }
+ pp = (unsigned char *) memchr(p, MARKER_ESC, len - 1);
+ if (!pp) return NULL;
+ 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;
+ return p + 6;
+ case MARKER_ATMOVE:
+ if (len < 8) return NULL;
+ return p + 8;
+ case MARKER_COMMENT:
+ if (len < 6) return NULL;
+ l = (((long) p[2] << 24) | ((long) p[3] << 16) |
+ ((long) p[4] << 8) | (long) p[5]);
+ if (len - 6 < l) return NULL;
+ return p + 6 + l;
+ default:
+ 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;
+
+ 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:
+ /* 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;
+}
diff --git a/kernel/kls_jbig/libjbig/jbig.h b/kernel/kls_jbig/libjbig/jbig.h
new file mode 100644
index 0000000..1129ac0
--- /dev/null
+++ b/kernel/kls_jbig/libjbig/jbig.h
@@ -0,0 +1,270 @@
+/*
+ * Header file for the portable free JBIG compression library
+ *
+ * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/
+ *
+ * $Id: jbig.h,v 1.17 2004-06-11 15:18:21+01 mgk25 Exp $
+ */
+
+#ifndef JBG_H
+#define JBG_H
+
+#include <stddef.h>
+
+/*
+ * JBIG-KIT version number
+ */
+
+#define JBG_VERSION "1.6"
+
+/*
+ * 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
+
+#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.*/
+
+
+/*
+ * Possible error code return values
+ */
+
+#define JBG_EOK 0
+#define JBG_EOK_INTR 1
+#define JBG_EAGAIN 2
+#define JBG_ENOMEM 3
+#define JBG_EABORT 4
+#define JBG_EMARKER 5
+#define JBG_ENOCONT 6
+#define JBG_EINVAL 7
+#define JBG_EIMPL 8
+
+/*
+ * Language code for error message strings (based on ISO 639 2-letter
+ * standard language name abbreviations).
+ */
+
+#define JBG_EN 0 /* English */
+#define JBG_DE_8859_1 1 /* German in ISO Latin 1 character set */
+#define JBG_DE_UTF_8 2 /* German in Unicode UTF-8 encoding */
+
+/*
+ * Status description of an arithmetic encoder
+ */
+
+struct jbg_arenc_state {
+ unsigned char st[4096]; /* probability status for contexts, MSB = MPS */
+ unsigned long c; /* C register, base of coding intervall, *
+ * layout as in Table 23 */
+ unsigned long a; /* A register, normalized size of coding intervall */
+ long sc; /* counter for buffered 0xff values which might 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 which receives all PSCD bytes */
+ void *file; /* parameter passed to byte_out */
+};
+
+
+/*
+ * Status description of an arithmetic decoder
+ */
+
+enum jbg_ardec_result {
+ JBG_OK, /* symbol has been successfully decoded */
+ JBG_READY, /* no more bytes of this PSCD required, marker *
+ * encountered, probably more symbols available */
+ JBG_MORE, /* more PSCD data bytes required to decode a symbol */
+ JBG_MARKER /* more PSCD data bytes required, ignored final 0xff byte */
+};
+
+struct jbg_ardec_state {
+ unsigned char st[4096]; /* probability status for contexts, MSB = MPS */
+ unsigned long c; /* C register, base of coding intervall, *
+ * layout as in Table 25 */
+ unsigned long a; /* A register, normalized size of coding intervall */
+ int ct; /* bit shift counter, determines when next byte will be read */
+ unsigned char *pscd_ptr; /* pointer to next PSCD data byte */
+ unsigned char *pscd_end; /* pointer to byte after PSCD */
+ enum jbg_ardec_result result; /* result of previous decode call */
+ int startup; /* controls initial fill of s->c */
+};
+
+/*
+ * 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 */
+};
+
+
+/*
+ * 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)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 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);
+long jbg_dec_getwidth(const struct jbg_dec_state *s);
+long jbg_dec_getheight(const struct jbg_dec_state *s);
+unsigned char *jbg_dec_getimage(const struct jbg_dec_state *s, int plane);
+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);
+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, int language);
+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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* JBG_H */
diff --git a/kernel/kls_jbig/libjbig/jbig_tab.c b/kernel/kls_jbig/libjbig/jbig_tab.c
new file mode 100644
index 0000000..5518350
--- /dev/null
+++ b/kernel/kls_jbig/libjbig/jbig_tab.c
@@ -0,0 +1,428 @@
+/*
+ * Probability estimation tables for the arithmetic encoder/decoder
+ * given by ITU T.82 Table 24.
+ *
+ * $Id: jbig_tab.c,v 1.6 1998-04-05 18:36:19+01 mgk25 Rel $
+ */
+
+short jbg_lsz[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
+};
+
+unsigned char jbg_nmps[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 jbg_nlps[] contain NLPS value,
+ * most significant bit (mask 0x80) contains SWTCH bit
+ */
+unsigned char jbg_nlps[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
+};
+
+/*
+ * Resolution reduction table given by ITU-T T.82 Table 17
+ */
+
+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.
+ */
+
+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,
+};