779 lines
34 KiB
Plaintext
779 lines
34 KiB
Plaintext
|
||
Using the JBIG-KIT library
|
||
--------------------------
|
||
|
||
Markus Kuhn -- 2004-06-10
|
||
|
||
|
||
This text explains how to use the functions provided by the JBIG-KIT
|
||
portable image compression library in your application software.
|
||
|
||
|
||
1 Introduction to JBIG
|
||
|
||
We start with a short introduction to JBIG1. More detailed information
|
||
is provided in the "Introduction and overview" section of the JBIG1
|
||
standard. Information on how to obtain a copy of the standard is
|
||
available from <http://www.itu.int/> or <http://www.iso.ch/>.
|
||
|
||
Image data encoded with the JBIG algorithm is separated into planes,
|
||
layers, and stripes. Each plane contains one bit per pixel. The number
|
||
of planes stored in a JBIG data stream is the number of bits per
|
||
pixel. Resolution layers are numbered from 0 to D with 0 being the
|
||
layer with the lowest resolution and D the one with the highest. Each
|
||
next higher resolution layer has twice the number of rows and columns.
|
||
Layer 0 is encoded independently of any other data, all other
|
||
resolution layers are encoded as only the difference between the next
|
||
lower and the current layer. For applications that require very quick
|
||
access to parts of an image, it is possible to divide an image into
|
||
several horizontal stripes. All stripes of one resolution layer have
|
||
equal size, except perhaps the final one. The number of stripes of an
|
||
image is equal in all resolution layers and in all bit planes.
|
||
|
||
The compressed data stream specified by the JBIG standard is called a
|
||
bi-level image entity (BIE). A BIE consists of a 20-byte header,
|
||
followed by an optional 1728-byte table (usually not present, except
|
||
in special applications) followed by a sequence of stripe data
|
||
entities (SDE). Each SDE encodes the content of one single stripe in
|
||
one plane of one resolution layer. Between the SDEs, other information
|
||
blocks (called floating marker segments) can also be present. They are
|
||
used to change certain parameters of the algorithm in the middle of an
|
||
image or contain additional application specific information. A BIE
|
||
looks like this:
|
||
|
||
|
||
+------------------------------------------------+
|
||
| |
|
||
| 20-byte header (with image size, #planes, |
|
||
| #layers, stripe size, first layer, options, |
|
||
| SDE ordering, ...) |
|
||
| |
|
||
+------------------------------------------------+
|
||
| |
|
||
| optional 1728-byte table |
|
||
| |
|
||
+------------------------------------------------+
|
||
| |
|
||
| optional floating marker segments |
|
||
| |
|
||
+------------------------------------------------+
|
||
| |
|
||
| stripe data entity |
|
||
| |
|
||
+------------------------------------------------+
|
||
| |
|
||
| optional floating marker segments |
|
||
| |
|
||
+------------------------------------------------+
|
||
| |
|
||
| stripe data entity |
|
||
| |
|
||
+------------------------------------------------+
|
||
...
|
||
+------------------------------------------------+
|
||
| |
|
||
| stripe data entity |
|
||
| |
|
||
+------------------------------------------------+
|
||
|
||
|
||
One BIE can contain all resolution layers of an image, but it is also
|
||
possible to store various resolution layers in several BIEs. The BIE
|
||
header contains the number of the first and the last resolution layer
|
||
stored in this BIE, as well as the size of the highest resolution
|
||
layer stored in this BIE. Progressive coding is deactivated by simply
|
||
storing the image in one single resolution layer.
|
||
|
||
Different applications might have different requirements for the order
|
||
in which the SDEs for stripes of various planes and layers are stored
|
||
in the BIE, so all possible sensible orderings are allowed by the
|
||
standard and indicated by four bits in the header.
|
||
|
||
It is possible to use the raw BIE data stream as specified by the JBIG
|
||
standard directly as the format of a file used for storing images.
|
||
This is what the pbmtojbg and jbgtopbm conversion tools do that are
|
||
provided in this package as demonstration applications. However, as
|
||
the BIE format has been designed for a large number of very different
|
||
applications, and to allow efficient direct processing by special JBIG
|
||
hardware chip implementations, the BIE header contains only the
|
||
minimum amount of information absolutely required by the decompression
|
||
algorithm. Many features expected from a good file format are missing
|
||
in the BIE data stream:
|
||
|
||
- no "magic code" in the first few bytes to allow identification
|
||
of the file format on a typeless file system and to allow
|
||
automatic distinction from other compression algorithms
|
||
|
||
- no standardized way to encode additional information such as a
|
||
textual description, information about the meaning of various bit
|
||
planes, the physical size and resolution of the document, etc.
|
||
|
||
- a checksum to ensure image integrity
|
||
|
||
- encryption and signature mechanisms
|
||
|
||
- many things more
|
||
|
||
Raw BIE data streams alone may therefore not be a suitable format for
|
||
document archiving and exchange. A standard format for this purpose
|
||
would typically combine a BIE representing the image data with an
|
||
additional header providing auxiliary information into one file.
|
||
Existing established multi-purpose file formats with a rich set of
|
||
auxiliary information attributes like TIFF could be extended easily to
|
||
also hold JBIG compressed data.
|
||
|
||
On the other hand, in database applications for instance, a BIE might
|
||
be stored directly in a variable length field. Auxiliary information
|
||
would then be stored in other fields of the same record, to simply
|
||
search operations.
|
||
|
||
|
||
2 Compressing an image
|
||
|
||
2.1 Format of the source image
|
||
|
||
To be processed by the JBIG-KIT encoder, the image has to be present
|
||
in memory as separate bitmap planes. Each byte of a bitmap contains
|
||
eight pixels, where the most significant bit represents the leftmost
|
||
of these. Each line of a bitmap has to be stored in an integral number
|
||
of bytes. If the image width is not an integral multiple of eight,
|
||
then the final byte has to be padded with zero bits.
|
||
|
||
For example the 23x5 pixels large single plane image:
|
||
|
||
.XXXXX..XXX...X...XXX..
|
||
.....X..X..X..X..X.....
|
||
.....X..XXX...X..X.XXX.
|
||
.X...X..X..X..X..X...X.
|
||
..XXX...XXX...X...XXX..
|
||
|
||
is represented by the 15 bytes
|
||
|
||
01111100 11100010 00111000
|
||
00000100 10010010 01000000
|
||
00000100 11100010 01011100
|
||
01000100 10010010 01000100
|
||
00111000 11100010 00111000
|
||
|
||
or in hexadecimal notation
|
||
|
||
7c e2 38 04 92 40 04 e2 5c 44 92 44 38 e2 38
|
||
|
||
This is the format used in binary PBM files and it can also be handled
|
||
directly by the Xlib library of the X Window System.
|
||
|
||
As JBIG can also handle images with multiple bit planes, the JBIG-KIT
|
||
library functions accept and return always arrays of pointers to
|
||
bitmaps with one pointer per plane.
|
||
|
||
For single-plane images, the standard recommends that a 0 pixel
|
||
represents the background and a 1 pixel represents the foreground
|
||
color of an image, in other words, 0 is white and 1 is black for
|
||
scanned paper documents. For images with several bits per pixel, the
|
||
JBIG standard makes no recommendations about how various colors should
|
||
be encoded.
|
||
|
||
For greyscale images, by using a Gray code instead of a simple binary
|
||
weighted representation of the pixel intensity, some increase in
|
||
coding efficiency can be reached.
|
||
|
||
A Gray code is also a binary representation of integer numbers, but it
|
||
has the property that the representations of the integer numbers i and
|
||
(i+1) always differ in exactly one bit. For example, the numbers 0 to
|
||
7 can be represented in normal binary code and Gray code as in the
|
||
following table:
|
||
|
||
normal
|
||
number binary code Gray code
|
||
---------------------------------------
|
||
0 000 000
|
||
1 001 001
|
||
2 010 011
|
||
3 011 010
|
||
4 100 110
|
||
5 101 111
|
||
6 110 101
|
||
7 111 100
|
||
|
||
The form of Gray code shown above has the property that the second
|
||
half of the code (numbers 4 - 7) is simply the mirrored first half
|
||
(numbers 3 - 0) with the first bit set to one. This way, arbitrarily
|
||
large Gray codes can be generated quickly by mirroring the above
|
||
example and prefixing the first half with zeros and the second half
|
||
with ones as often as required. In greyscale images, it is common
|
||
practise to use the all-0 code for black and the all-1 code for white.
|
||
|
||
No matter whether a Gray code or a binary code is used for encoding a
|
||
pixel intensity in several bit planes, it always makes sense to store
|
||
the most significant (leftmost) bit in plane 0, which is transmitted
|
||
first. This way, a decoder could increase the precision of the
|
||
displayed pixel intensities while data is still being received and the
|
||
basic structure of the image will become visible as early as possible
|
||
during the transmission.
|
||
|
||
|
||
2.2 A simple compression application
|
||
|
||
In order to use JBIG-KIT in your application, just link libjbig.a to
|
||
your executable (on Unix systems just add -ljbig and -L. to the
|
||
command line options of your compiler, on other systems you will have
|
||
to write a new Makefile anyway), copy the file jbig.h into your source
|
||
directory and put the line
|
||
|
||
#include "jbig.h"
|
||
|
||
into your source code.
|
||
|
||
The library interface follows object-oriented programming principles.
|
||
You have to declare a variable (object)
|
||
|
||
struct jbg_enc_state se;
|
||
|
||
which contains the current status of an encoder. Then you initialize
|
||
the encoder by calling the constructor function
|
||
|
||
void jbg_enc_init(struct jbg_enc_state *s, unsigned long x, unsigned long y,
|
||
int pl, unsigned char **p,
|
||
void (*data_out)(unsigned char *start, size_t len,
|
||
void *file),
|
||
void *file);
|
||
|
||
The parameters have the following meaning:
|
||
|
||
s A pointer to the jbg_enc_state structure which you want
|
||
to initialize.
|
||
|
||
x The width of your image.
|
||
|
||
y The height of your image.
|
||
|
||
pl the number of bitmap planes you want to encode.
|
||
|
||
p A pointer to an array of pl pointers, where each is again
|
||
pointing to the first byte of a bitmap as described in
|
||
section 2.1.
|
||
|
||
data_out This is a call-back function which will be called during
|
||
the compression process by libjbig in order to deliver
|
||
the BIE data to the application. The parameters of the
|
||
function data_out are a pointer start to the new block
|
||
of data to be delivered, as well as the number len of
|
||
delivered bytes. The pointer file is transparently
|
||
delivered to data_out, as specified in jbg_enc_init().
|
||
Typically, data_out will write the BIE portion to a
|
||
file, send it to a network connection, or append it to
|
||
some memory buffer.
|
||
|
||
file A pointer parameter that is passed on to data_out()
|
||
and can be used, for instance, to allow data_out() to
|
||
distinguish by which compression task it has been
|
||
called in multi-threaded applications.
|
||
|
||
In the simplest case, the compression is then started by calling the
|
||
function
|
||
|
||
void jbg_enc_out(struct jbg_enc_state *s);
|
||
|
||
which will deliver the complete BIE to data_out() in several calls.
|
||
After jbg_enc_out has returned, a call to the destructor function
|
||
|
||
void jbg_enc_free(struct jbg_enc_state *s);
|
||
|
||
will release any heap memory allocated by the previous functions.
|
||
|
||
|
||
A minimal example application which sends the BIE of the above
|
||
bitmap to stdout looks like this:
|
||
|
||
---------------------------------------------------------------------------
|
||
/* A sample JBIG encoding application */
|
||
|
||
#include <stdio.h>
|
||
#include "jbig.h"
|
||
|
||
void output_bie(unsigned char *start, size_t len, void *file)
|
||
{
|
||
fwrite(start, 1, len, (FILE *) file);
|
||
|
||
return;
|
||
}
|
||
|
||
int main()
|
||
{
|
||
unsigned char bitmap[15] = {
|
||
/* 23 x 5 pixels, "JBIG" */
|
||
0x7c, 0xe2, 0x38, 0x04, 0x92, 0x40, 0x04, 0xe2,
|
||
0x5c, 0x44, 0x92, 0x44, 0x38, 0xe2, 0x38
|
||
};
|
||
unsigned char *bitmaps[1] = { bitmap };
|
||
struct jbg_enc_state se;
|
||
|
||
jbg_enc_init(&se, 23, 5, 1, bitmaps,
|
||
output_bie, stdout); /* initialize encoder */
|
||
jbg_enc_out(&se); /* encode image */
|
||
jbg_enc_free(&se); /* release allocated resources */
|
||
|
||
return 0;
|
||
}
|
||
---------------------------------------------------------------------------
|
||
|
||
This software produces a 42 byte long BIE. (JBIG is not very good at
|
||
compressing extremely small images like in this example, because the
|
||
arithmetic encoder requires some startup data in order to generate
|
||
reasonable statistics which influence the compression process and
|
||
because there is some header overhead.)
|
||
|
||
|
||
2.3 More about compression
|
||
|
||
If jbg_enc_out() is called directly after jbg_enc_init(), the
|
||
following default values are used for various compression parameters:
|
||
|
||
- Only one single resolution layer is used, i.e. no progressive
|
||
mode.
|
||
|
||
- The number of lines per stripe is selected so that approximately
|
||
35 stripes per image are used (as recommended in annex C of the
|
||
standard together with the suggested adaptive template change
|
||
algorithm). However, not less than 2 and not more than 128 lines
|
||
are used in order to stay within the suggested minimum parameter
|
||
support range specified in annex A of the standard).
|
||
|
||
- All optional parts of the JBIG algorithm are activated (TPBON,
|
||
TPDON and DPON).
|
||
|
||
- The default resolution reduction table and the default deterministic
|
||
prediction table are used
|
||
|
||
- The maximal vertical offset of the adaptive template pixel is 0
|
||
and the maximal horizontal offset is 8 (mx = 8, my = 0).
|
||
|
||
In order to change any of these default parameters, additional
|
||
functions have to be called between jbg_enc_init() and jbg_enc_out().
|
||
|
||
In order to activate progressive encoding, it is possible to specify
|
||
with
|
||
|
||
void jbg_enc_layers(struct jbg_enc_state *s, int d);
|
||
|
||
the number d of differential resolution layers which shall be encoded
|
||
in addition to the lowest resolution layer 0. For example, if a
|
||
document with 60-micrometer pixels has to be stored, and the lowest
|
||
resolution layer shall have 240-micrometer pixels, so that a screen
|
||
previewer can directly decompress only the required resolution, then a
|
||
call
|
||
|
||
jbg_enc_layers(&se, 2);
|
||
|
||
will cause three layers with 240, 120 and 60 micrometers resolution to
|
||
be generated.
|
||
|
||
If the application does not know what typical resolutions are used and
|
||
simply wants to ensure that the lowest resolution layer will fit into
|
||
a given maximal window size, then as an alternative, a call to
|
||
|
||
int jbg_enc_lrlmax(struct jbg_enc_state *s, unsigned long mwidth,
|
||
unsigned long mheight);
|
||
|
||
will cause the library to automatically determine the suitable number
|
||
of resolutions so that the lowest resolution layer 0 will not be
|
||
larger than mwidth x mheight pixels. E.g. if one wants to ensure that
|
||
systems with a 640 x 480 pixel large screen can decode the required
|
||
resolution directly, then call
|
||
|
||
jbg_enc_lrlmax(&se, 640, 480);
|
||
|
||
The return value is the number of differential layers selected.
|
||
|
||
After the number of resolution layers has been specified by calls to
|
||
jbg_enc_layers() or jbg_enc_lrlmax(), by default, all these layers
|
||
will be written into the BIE. This can be changed with a call to
|
||
|
||
int jbg_enc_lrange(struct jbg_enc_state *s, int dl, int dh);
|
||
|
||
Parameter dl specifies the lowest resolution layer and dh the highest
|
||
resolution layer that will appear in the BIE. For instance, if layer 0
|
||
shall be written to the first BIE and layer 1 and 2 shall be written
|
||
to a second one, then before writing the first BIE, call
|
||
|
||
jbg_enc_lrange(&se, 0, 0);
|
||
|
||
and before writing the second BIE with jbg_enc_out(), call
|
||
|
||
jbg_enc_lrange(&se, 1, 2);
|
||
|
||
If any of the parameters is negative, it will be ignored. The return
|
||
value is the total number of differential layers that will represent
|
||
the input image. This way, jbg_enc_lrange(&se, -1, -1) can be used to
|
||
query the layer of the full image resolution.
|
||
|
||
A number of other more exotic options of the JBIG algorithm can be
|
||
modified by calling
|
||
|
||
void jbg_enc_options(struct jbg_enc_state *s, int order, int options,
|
||
long l0, int mx, int my);
|
||
|
||
before calling jbg_enc_out().
|
||
|
||
The order parameter can be a combination of the bits JBG_HITOLO,
|
||
JBG_SEQ, JBG_ILEAVE and JBG_SMID and it determines in which order
|
||
the SDEs are stored in the BIE. The bits have the following meaning:
|
||
|
||
JBG_HITOLO Usually, the lower resolution layers are stored before
|
||
the higher resolution layers, so that a decoder can
|
||
already start to display a low resolution version of
|
||
the full image once a prefix of the BIE has been
|
||
received. When this bit is set, however, the BIE will
|
||
contain the higher layers before the lower layers. This
|
||
avoids additional buffer memory in the encoder and is
|
||
intended for applications where the encoder is connected
|
||
to a database which can easily reorder the SDEs before
|
||
sending them to a decoder. Warning: JBIG decoders are
|
||
not expected to support the HITOLO option (e.g. the
|
||
JBIG-KIT decoder currently does not) so you should
|
||
normally not use it.
|
||
|
||
JBG_SEQ Usually, at first all stripes of one resolution layer
|
||
are written to the BIE and then all stripes of the next
|
||
layer, and so on. When the SEQ bit is set however, then
|
||
all layers of the first stripe will be written,
|
||
followed by all layers of the second stripe, etc. This
|
||
option also should normally never be required and is
|
||
not supported by the current JBIG-KIT decoder.
|
||
|
||
JBG_SMID In case there exist several bit planes, then the order of
|
||
the stripes is determined by three loops over all stripes,
|
||
all planes and all layers. When SMID is set, the loop
|
||
over all stripes is the middle loop.
|
||
|
||
JBG_ILEAVE If this bit is set, then at first all layers of one
|
||
plane are written before the encoder starts with the next
|
||
plane.
|
||
|
||
The above description may be somewhat confusing, but the following
|
||
table (see also Table 11 in ITU-T T.82) clarifies how the three bits
|
||
JBG_SEQ, JBIG_ILEAVE and JBG_SMID influence the ordering of the loops
|
||
over all stripes, planes and layers:
|
||
|
||
|
||
Loops:
|
||
JBG_SEQ JBG_ILEAVE JBG_SMID | Outer Middle Inner
|
||
------------------------------------+---------------------------
|
||
0 0 0 | p d s
|
||
0 1 0 | d p s
|
||
0 1 1 | d s p
|
||
1 0 0 | s p d
|
||
1 0 1 | p s d
|
||
1 1 0 | s d p
|
||
|
||
p: plane, s: stripe, d: layer
|
||
|
||
|
||
By default, the order combination JBG_ILEAVE | JBG_SMID is used.
|
||
|
||
The options value can contain the following bits, which activate
|
||
some of the optional algorithms defined by JBIG:
|
||
|
||
JBG_LRLTWO Normally, in the lowest resolution layer, pixels
|
||
from three lines around the next pixel are used
|
||
in order to determine the context in which the next
|
||
pixel is encoded. Some people in the JBIG committee
|
||
seem to have argued that using only 2 lines will
|
||
make software implementations a little bit faster,
|
||
however others have argued that using only two lines
|
||
will decrease compression efficiency by around 5%.
|
||
As you might expect from a committee, now both
|
||
alternatives are allowed and if JBG_LRLTWO is set,
|
||
the slightly faster but 5% less well compressing two
|
||
line alternative is selected. God bless the committees.
|
||
Although probably nobody will ever need this option,
|
||
it has been implemented in JBIG-KIT and is off by
|
||
default.
|
||
|
||
JBG_TPDON This activates the "typical prediction" algorithm
|
||
for differential layers which avoids that large
|
||
areas of equal color have to be encoded at all.
|
||
This is on by default and there is no good reason to
|
||
switch it off except for debugging or preparing data
|
||
for cheap JBIG hardware that might not support this
|
||
option.
|
||
|
||
JBG_TPBON Like JBG_TPDON this activates the "typical prediction"
|
||
algorithm in the lowest resolution layer. Also activated
|
||
by default.
|
||
|
||
JBG_DPON This bit activates for the differential resolution
|
||
layers the "deterministic prediction" algorithm,
|
||
which avoids that higher resolution layer pixels are
|
||
encoded when their value can already be determined
|
||
with the knowledge of the neighbor pixels, the
|
||
corresponding lower resolution pixels and the
|
||
resolution reduction algorithm. This is also
|
||
activated by default and one reason for deactivating
|
||
it would be if the default resolution reduction
|
||
algorithm were replaced by another one.
|
||
|
||
JBG_DELAY_AT Use a slightly less efficient algorithm to determine
|
||
when an adaptive template change is necessary. With
|
||
this bit set, the encoder output is compatible to the
|
||
conformance test examples in cause 7.2 of ITU-T T.82.
|
||
Then all adaptive template changes are delayed until
|
||
the first line of the next stripe. This option is by
|
||
default deactivated and is only required for passing a
|
||
special compatibility test suite.
|
||
|
||
In addition, parameter l0 in jbg_enc_options() allows you to specify
|
||
the number of lines per stripe in resolution layer 0. The parameters
|
||
mx and my change the maximal offset allowed for the adaptive template
|
||
pixel. JBIG-KIT now supports the full range of possible mx values up
|
||
to 127 in the encoder and decoder, but my is at the moment ignored and
|
||
always set to 0. As the standard requires of all decoder
|
||
implementations only to support maximum values mx = 16 and my = 0,
|
||
higher values should normally be avoided in order to guarantee
|
||
interoperability. The ITU-T T.85 profile for JBIG in fax machines
|
||
requires support for mx = 127 and my = 0. Default is mx = 8 and my =
|
||
0. If any of the parameters order, options, mx or my is negative, or
|
||
l0 is zero, then the corresponding current value remains unmodified.
|
||
|
||
The resolution reduction and deterministic prediction tables can also
|
||
be replaced. However as these options are anyway only for experts,
|
||
please have a look at the source code of jbg_enc_out() and the struct
|
||
members dppriv and res_tab of struct jbg_enc_state for the details of
|
||
how to do this, in case you really need it. The functions
|
||
jbg_int2dppriv and jbg_dppriv2int are provided in order to convert the
|
||
DPTABLE data from the format used in the standard into the more
|
||
efficient format used internally by JBIG-KIT.
|
||
|
||
If you want to encode a greyscale image, you can use the library
|
||
function
|
||
|
||
void jbg_split_planes(unsigned long x, unsigned long y, int has_planes,
|
||
int encode_planes,
|
||
const unsigned char *src, unsigned char **dest,
|
||
int use_graycode);
|
||
|
||
It separates an image in which each pixel is represented by one or
|
||
more bytes into separate bit planes. The dest array of pointers to
|
||
these bit planes can then be handed over to jbg_enc_init(). The
|
||
variables x and y specify the width and height of the image in pixels,
|
||
and has_planes specifies how many bits per pixel are used. As each
|
||
pixel is represented by an integral number of consecutive bytes, of
|
||
which each contains up to eight bits, the total length of the input
|
||
image array src[] will therefore be x * y * ((has_planes + 7) / 8)
|
||
bytes. The pixels are stored as usually in English reading order, and
|
||
for each pixel the integer value is stored with the most significant
|
||
byte coming first (Bigendian). This is exactly the format used in raw
|
||
PGM files. In encode_planes, the number of bit planes that shall be
|
||
extracted can be specified. This allows for instance to extract only
|
||
the most significant 8 bits of a 12-bit image, where each pixel is
|
||
represented by two bytes, by specifying has_planes = 12 and
|
||
encode_planes = 8. If use_graycode is zero, then the binary code of
|
||
the pixel integer values will be used instead of the Gray code. Plane
|
||
0 contains always the most significant bit.
|
||
|
||
|
||
3 Decompressing an image
|
||
|
||
Like with the compression functions, if you want to use the JBIG-KIT
|
||
library, you have to put the line
|
||
|
||
#include "jbig.h"
|
||
|
||
into your source code and link your executable with libjbig.a.
|
||
|
||
The state of a JBIG decoder is stored completely in a struct and you
|
||
will have to define a variable like
|
||
|
||
struct jbg_dec_state sd;
|
||
|
||
which is initialized by a call to
|
||
|
||
void jbg_dec_init(struct jbg_dec_state *s);
|
||
|
||
After this, you can directly start to pass data from the BIE to the decoder
|
||
by calling the function
|
||
|
||
int jbg_dec_in(struct jbg_dec_state *s, unsigned char *data, size_t len,
|
||
size_t *cnt);
|
||
|
||
The pointer data points to the first byte of a data block with length
|
||
len, which contains bytes from a BIE. It is not necessary to pass a
|
||
whole BIE at once to jbg_dec_in(), it can arrive fragmented in any way
|
||
by calling jbg_dec_in() several times. It is also possible to send
|
||
several BIEs concatenated to jbg_dec_in(), however these then have to
|
||
fit together. If you send several BIEs to the decoder, the lowest
|
||
resolution layer in each following BIE has to be the highest
|
||
resolution layer in the previous BIE plus one and the image sizes and
|
||
number of planes also have to fit together, otherwise jbg_dec_in()
|
||
will return the error JBG_ENOCONT after the header of the new BIE has
|
||
been received completely.
|
||
|
||
If pointer cnt is not NULL, then the number of bytes actually read
|
||
from the data block is stored there. In case the data block did not
|
||
contain the end of the BIE, then the value JBG_EAGAIN will be returned
|
||
and *cnt equals len.
|
||
|
||
Once the end of a BIE has been reached, the return value of
|
||
jbg_dec_in() will be JBG_EOK. After this has happened, the functions
|
||
and macros
|
||
|
||
long jbg_dec_getwidth(struct jbg_dec_state *s);
|
||
long jbg_dec_getheight(struct jbg_dec_state *s);
|
||
int jbg_dec_getplanes(struct jbg_dec_state *s);
|
||
unsigned char *jbg_dec_getimage(struct jbg_dec_state *s, int plane);
|
||
long jbg_dec_getsize(struct jbg_dec_state *s);
|
||
|
||
can be used to query the dimensions of the now completely decoded
|
||
image and to get a pointer to all bitmap planes. The bitmaps are
|
||
stored as described in section 2.1. The function jbg_dec_getsize()
|
||
calculates the number of bytes which one bitmap requires.
|
||
|
||
The function
|
||
|
||
void jbg_dec_merge_planes(const struct jbg_dec_state *s, int use_graycode,
|
||
void (*data_out)(unsigned char *start, size_t len,
|
||
void *file), void *file);
|
||
|
||
allows you to merge the bit planes that can be accessed individually
|
||
with jbg_dec_getimage() into an array with one or more bytes per pixel
|
||
(i.e., the format provided to jbg_split_planes()). If use_graycode is
|
||
zero, then a binary encoding will be used. The output array will be
|
||
delivered via the callback function data_out, exactly in the same way
|
||
in which the encoder provides the BIE. The function
|
||
|
||
long jbg_dec_getsize_merged(const struct jbg_dec_state *s);
|
||
|
||
determines how long the data array delivered by jbg_dec_merge_planes()
|
||
is going to be.
|
||
|
||
Before calling jbg_dec_in() the first time, it is possible to specify with
|
||
a call to
|
||
|
||
void jbg_dec_maxsize(struct jbg_dec_state *s, unsigned long xmax,
|
||
unsigned long ymax);
|
||
|
||
an abort criterion for progressively encoded images. For instance if an
|
||
application will display a whole document on a screen which is 1024 x
|
||
768 pixels large, then this application should call
|
||
|
||
jbg_dec_maxsize(&sd, 1024, 768);
|
||
|
||
before the decoding process starts. If the image has been encoded in
|
||
progressive mode (i.e. with several resolution layers), then the
|
||
decoder will stop with a return value JBG_EOK_INTR after the largest
|
||
resolution layer that is still smaller than 1024 x 768. However this
|
||
is no guarantee that the image which can then be read out using
|
||
jbg_dec_getimage(), etc. is really not larger than the specified
|
||
maximal size. The application will have to check the size of the
|
||
image, because the decoder does not automatically apply a resolution
|
||
reduction if no suitable resolution layer is available in the BIE.
|
||
|
||
If jbg_dec_in() returned JBG_EOK_INTR or JBG_EOK, then it is possible
|
||
to continue calling jbg_dec_in() with the remaining data in order to
|
||
either decode the remaining resolution layers of the current BIE or in
|
||
order to add another BIE with additional resolution layers. In both
|
||
cases, after jbg_dec_in() returned JBG_EOK_INTR or JBG_EOK, *cnt is
|
||
probably not equal to len and the remainder of the data block which
|
||
has not yet been processed by the decoder has to be delivered to
|
||
jbg_dec_in() again.
|
||
|
||
If any other return value than JBG_EOK, JBG_EOK_INTR or JBG_EAGAIN
|
||
has been returned by jbg_dec_in(), then an error has occurred and
|
||
|
||
void jbg_dec_free(struct jbg_dec_state *s);
|
||
|
||
should be called in order to release any allocated memory. The
|
||
destructor jbg_dec_free() should of course also be called, once the
|
||
decoded bitmap returned by jbg_dec_getimage() is no longer required
|
||
and the memory can be released.
|
||
|
||
The function
|
||
|
||
const char *jbg_strerror(int errnum, int language);
|
||
|
||
returns a pointer to a short single line test message which explains
|
||
the return value of jbg_dec_in(). This message can be used in order to
|
||
provide the user a brief informative message about what when wrong
|
||
while decompressing the JBIG image. The error messages are available
|
||
in several languages and in several character sets. Currently
|
||
supported are the following values for the language parameter:
|
||
|
||
JBG_EN English messages in ASCII
|
||
JBG_DE_8859_1 German messages in ISO 8859-1 Latin 1 character set
|
||
JBG_DE_UTF_8 German messages in ISO 10646/Unicode UTF-8 encoding
|
||
|
||
|
||
The current implementation of the JBIG-KIT decoder has the following
|
||
limitations:
|
||
|
||
- The maximal vertical offset MY of the adaptive template pixel
|
||
must be zero.
|
||
|
||
- HITOLO and SEQ bits must not be set in the order value.
|
||
|
||
- Not more than JBG_ATMOVES_MAX (currently set to 64) ATMOVE
|
||
marker segments can be handled per stripe.
|
||
|
||
- the number D of differential layers must be less than 32
|
||
|
||
None of the above limitations can be exceeded by a JBIG data stream
|
||
that conforms to the ITU-T T.85 application profile for the use of
|
||
JBIG1 in fax machines.
|
||
|
||
There are two more limitations of the current implementation of the
|
||
JBIG-KIT decoder that might cause problems with processing JBIG data
|
||
stream that conform to ITU-T T.85:
|
||
|
||
- The JBIG-KIT decoder was designed to operate incrementally.
|
||
Each received byte is processed immediately as soon as it arrives.
|
||
As a result, it does not look beyond the SDRST/SDNORM at the end
|
||
of all stripes for any immediately following NEWLEN marker that
|
||
might reduce the number of lines encoded by the current stripe.
|
||
However section 6.2.6.2 of ITU-T T.82 says that a NEWLEN marker
|
||
segment "could refer to a line in the immediately preceding stripe
|
||
due to an unexpected termination of the image or the use of only
|
||
such stripe", and ITU-T.85 explicitly suggests the use of this
|
||
for fax machines that start transmission before having encountered
|
||
the end of the page.
|
||
|
||
- The image size initially indicated in the BIE header is used to
|
||
allocate memory for a bitmap of this size. This means that BIEs
|
||
that set initially Y_D = 0xffffffff (as suggested in ITU-T T.85
|
||
for fax machines that do not know the height of the page at the
|
||
start of the transmission) cannot be decoded directly by this
|
||
version.
|
||
|
||
For both issues, there is a very simple workaround:
|
||
|
||
If you encounter a BIE that has in the header the VLENGTH=1 option bit
|
||
set, then first wait until you have received the entire BIE and stored
|
||
it in memory. Then call the function
|
||
|
||
int jbg_newlen(unsigned char *bie, size_t len);
|
||
|
||
where bie is a pointer to the first byte of the BIE and len its length
|
||
in bytes. This function will scan the entire BIE for the first NEWLEN
|
||
marker segment. It will then take the updated image-height value YD
|
||
from it and use it to overwrite the YD value in the BIE header. The
|
||
jbg_newlen() can return some of the same error codes as jbg_dec_in(),
|
||
namely JBG_EOK if everything went fine, JBG_EAGAIN is the data
|
||
provided is too short to be a valid BIE, JBG_EINVAL if a format error
|
||
was encountered, and JBG_EABORT if an ABORT marker segment was found.
|
||
After having patched the image-height value in the BIE using
|
||
jbg_newlen(), simply hand over the BIE as usual to jbg_dec_in().
|
||
|
||
|
||
A more detailed description of the JBIG-KIT implementation is
|
||
|
||
Markus Kuhn: Effiziente Kompression von bi-level Bilddaten durch
|
||
kontextsensitive arithmetische Codierung. Studienarbeit, Lehrstuhl
|
||
f<>r Betriebssysteme, IMMD IV, Universit<69>t Erlangen-N<>rnberg,
|
||
Erlangen, July 1995. (German, 62 pages)
|
||
<http://www.cl.cam.ac.uk/~mgk25/kuhn-sta.pdf>
|
||
|
||
Please quote the above if you use JBIG-KIT in your research project.
|
||
|
||
*** Happy compressing ***
|
||
|
||
[end]
|