diff options
Diffstat (limited to 'converter/other/jbig/libjbig/jbig.doc')
-rw-r--r-- | converter/other/jbig/libjbig/jbig.doc | 721 |
1 files changed, 721 insertions, 0 deletions
diff --git a/converter/other/jbig/libjbig/jbig.doc b/converter/other/jbig/libjbig/jbig.doc new file mode 100644 index 00000000..10eeda80 --- /dev/null +++ b/converter/other/jbig/libjbig/jbig.doc @@ -0,0 +1,721 @@ + +Using the JBIG-KIT library +-------------------------- + +Markus Kuhn -- 1998-04-10 + + +This text explains how to include the functions provided by the +JBIG-KIT portable image compression library into your application +software. + + +1 Introduction to JBIG + +Below follows a short introduction into some technical aspects of the +JBIG standard. More detailed information is provided in the +"Introduction and overview" section of the JBIG standard. Information +about how to obtain a copy of the standard is available on the +Internet from <http://www.itu.ch/> 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 layer with the highest one. +Each next higher resolution layer has exactly twice the number of rows +and columns than the previous one. 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). SDEs are the data blocks of which each encodes the +content of one single stripe in one plane and resolution layer. +Between the SDEs, other information blocks (called floating marker +segments) can also be present, which 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 | + | | + +------------------------------------------------+ + | | + | 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 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 JBIG<->PBM conversion tools that are provided in this +package as demonstration applications do. However as the BIE format +has been designed for a large number of very different applications +and also in order 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. A large number of 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 on a typeless file system as JBIG encoded and to allow + automatic distinction from other compression algorithms + + - no standardized way to encode additional information like a textual + description, information about the meaning of various bit planes, + the physical size and resolution of the document, etc. + + - a checksum that ensures image integrity + + - encryption and signature mechanisms + + - many things more + +Raw BIE data streams alone are consequently no suitable format for +document archiving and exchange. A standard format for this purpose +would typically combine a BIE representing the image data together +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 +so that they can also contain JBIG compressed data. + +On the other hand, in database applications for instance, a BIE might +be directly stored in a variable length field. Auxiliary information +on which efficient search operations are required would then be stored +in other fields of the same record. + + +2 Compressing an image + +2.1 Format of the source image + +For processing by the library, the image has to be present in memory +as separate bitmap planes. Each byte of a bitmap contains eight +pixels, the most significant bit represents the leftmost of these +pixels. 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 be +handled directly by the Xlib library of the X Window System. + +As JBIG can also handle images with several 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, i.e. 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 +has the property that the representations of the integer numbers i and +(i+1) differ always in exactly one single 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 the concepts of object-oriented +programming. 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(). Usually, 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 which is transparently passed to + data_out() and allows 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(). After this, a call +to the destructor function + + void jbg_enc_free(struct jbg_enc_state *s); + +will release any memory allocated by the previous functions. + + +A minimal example application which sends the BIE of the above example +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 tables 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 300 +dpi document has to be stored and the lowest resolution layer shall +have 75 dpi so that a screen previewer can directly decompress only +the required resolution, then a call + + jbg_enc_layers(&se, 2); + +will cause three resolution layers with 75, 150 and 300 dots per inch. + +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. If e.g. only 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, one calls + + jbg_enc_lrange(&se, 0, 0); + +and before writing the second BIE with jbg_enc_out(), one calls + + 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 which will represent +the input image. This way, jbg_enc_lrange(&se, -1, -1) can be used to +query the layer of the full image. + +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 does currently 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 3 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 might be somewhat confusing, but the following +table (see also Table 11 in ITU-T T.82) makes clear 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 which does 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 only might perhaps want + to deactivate it if the default resolution reduction + algorithm is replaced by a new 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 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. The JBIG-KIT implementation allows currently a maximal mx value +of 23 in the encoder and 32 in the decoder. Parameter my is at the +moment ignored and always set to 0. As the standard requires of all +decoder implementations only a maximum supported mx = 16 and my = 0, +higher values should normally be avoided in order to guarantee +interoperability. Default is mx = 8 and my = 0. If any of the +parameters order, options, l0, mx or my is negative, then this value +is ignored and the current value stays 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 bitplanes. The dest array of pointers to +these bitplanes 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 bitplanes 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 bitplanes 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 horizontal offset mx of the adaptive template pixel + must not be larger than 32 and the maximal vertical offset must + be zero. + + - HITOLO and SEQ bits must not be set in the order value. + +A more detailed description of the JBIG-KIT implementation is + + Markus Kuhn: Effiziente Kompression von bi-level Bilddaten durch + kontextsensitive arithmetische Codierung. Studienarbeit, Lehrstuhl + für Betriebssysteme, IMMD IV, Universität Erlangen-Nürnberg, + Erlangen, July 1995. (German, 62 pages) + <http://www.cl.cam.ac.uk/~mgk25/kuhn-sta.pdf> + +Please quote the above if you use JBIG-KIT in your research project. + +*** Happy compressing *** + +[end] |