/*====================================================================*
 -  Copyright (C) 2001 Leptonica.  All rights reserved.
 -  This software is distributed in the hope that it will be
 -  useful, but with NO WARRANTY OF ANY KIND.
 -  No author or distributor accepts responsibility to anyone for the
 -  consequences of using this software, or for whether it serves any
 -  particular purpose or works at all, unless he or she says so in
 -  writing.  Everyone is granted permission to copy, modify and
 -  redistribute this source code, for commercial or non-commercial
 -  purposes, with the following restrictions: (1) the origin of this
 -  source code must not be misrepresented; (2) modified versions must
 -  be plainly marked as such; and (3) this notice may not be removed
 -  or altered from any source or modified source distribution.
 *====================================================================*/

README  (31 Oct 03)
-------------------

gunzip leptonlib-1.13.tar.gz
tar -xvf leptonlib-1.13.tar


1.  This tar includes source, function prototypes,
    compiled test programs, and sample images for
    Linux on x86.  Compilation was done with gcc 2.95.3.

    Prototypes, libraries and executables are easily made,
    as described in 2, 3 and 4.

2.  To make prototype files, using cextract (supplied):

         make allprotos

3.  When you compile, object code is put into a tree with root
    at the place where you un-tar'd.  If you want to change the
    location of the generated object code, change the ROOT_DIR
    variable in the Makefile.

4.  To compile and link, just use 'make' in src and prog directories.
    It is also possible to make a debug version, as well as one that
    builds and uses shared libraries.  If you want to use shared
    libraries, you need to add the location of the shared
    libraries to the LD_LIBRARY_PATH.  See the Makefile for other
    details.

5.  Pre-requisites for compilation and linking.
    The only dependencies required for using leptonlib are three
    libraries that are standard with all linux installations:
        libjpeg.a  (standard jfif jpeg library, version 6.2 preferred)
        libpng.a   (standard png library, suggest version 1.2.5)
	libz.a     (standard gzip library, version 1.1.3 or later)
    These libraries (and their shared versions) should be in /usr/lib.
    (If they're not, you can change the LDFLAGS variable in the Makefile.)
    Additionally, for compilation, the following header files are
    assumed to be in /usr/include:
        jpeg:  jconfig.h
	png:   png.h, pngconf.h
    What about jpeglib.h?  See item 15 below.

    There are also two special interfaces to gnuplot, one that is
    programmatic and one that uses a simple file format.  To use them,
    you need the gnuplot executable (suggest version 3.7.2).

6.  If you want to make programs on other platforms:
    (a) Windows
        A full download of cygwin provides enough libraries and
	programs (e.g., gnu make, gcc, libjpeg, libpng, libz)
	to compile the leptonlib libraries in src and make the .exe
	execuables in the prog directory.  Make the following changes
	to the (linux) src/Makefile:
	   (1) remove viewfiles.c from the src list
	   (2) change $CEXTRACT to run cextract.exe
	   (3) choose $CC to remove the -fPIC flag to avoid warnings
        The cextract.exe program is a version of cextract that runs
	on Windows.  I will provide the tar for building it on request.
    (b) Sun Solaris
        Using Makefile.sun, which is only slightly altered from the
	linux Makefile, you can compile the leptonlib libraries 
	in src and make the Solaris executables in prog.
	I do not provide a version of cextract that runs on Solaris.

7.  This is a source for a clean, fast implementation of rasterops.
    You can find details starting at the leptonica home page,
    and also by looking directly at the source code.
    The low-level code is in roplow.c and ropiplow.c.
    An interface is given in rop.c to a simple PIX image data
    structure that is defined in pix.h.

8.  This is a source for implementations of binary morphology.
    You can find details starting at the leptonica home page,
    and also by looking directly at the source code.

    Binary morphology is implemented two ways:

       (a) Successive full image rasterops for arbitrary 
           structuring elements (sels)

       (b) Destination word accumulation (dwa) for specific
           sels.  This has been implemented two ways:
	      (1) By hand.  See the low-level code in fmorphlow.c
		  From the examples given, you can easily
		  see how to implement others, and why you'd rather
		  not do this at all.
	      (2) Automatically generated.  See, for example, the
	          code in fmorphgen.1.c and fmorphgenlow.1.c.
		  These files were generated by running the
		  program prog/fmorphautogen.c.
	   All results can be checked by comparing with
	   those from full image rasterops.  For the
	   checking of automatically generated code, see
	   prog/fmorptest2.c.

    Method (b) is considerably faster than (a), which is the
    reason we've gone to the effort of supporting the use
    of this method for all sels.

    Similarly, dwa code for the general hit-miss transform
    can be auto-generated from an array of hit-miss sels.
    When prog/fhmtautogen.c is compiled and run, it generates
    the dwa C code in fhmtgen.1.c and fhmtgenlow.1.c.  These
    files can then be compiled into the libraries.  To check
    the correctness of the automatically generated dwa code
    with the rasterop version, see prog/fhmttest.c.

    The structuring element is represented by a simple SEL data structure
    defined in morph.h.

    We also provide a fast implementation of grayscale morphology for
    brick structuring elements (i.e., sels that are decomposable
    into linear elements).  This uses the van Herk/Gil-Werman algorithm
    that performs the calculations in a time independent of the
    size of the sels.  The low-level code is in graymorphlow.c.
    
9.  This is also a source for simple and relatively efficient
    implementations of image scaling, shear and rotation.

    Grayscale and color image scaling are done by both sampling
    and linear interpolation.  Scaling operations with linear
    interpolation are limited to 8 bpp gray, 24 bpp full RGB color,
    and 2, 4 and 8 bpp colormapped (bpp == bits/pixel).  Scaling
    operations with sampling can be done at 1, 2, 4, 8, 16 and
    24 bpp.  Linear interpolation is slower but gives better results,
    especially for upsampling.  The smoothing done by the
    linear interpolation is sometimes called "anti-aliasing."

    For binary scaling, the dest pixel can be selected from the
    closest corresponding source pixel.  For the special case of 
    power-of-2 binary reduction, low-pass rank-order filtering can be
    done in advance.  Power-of-2 binary expansion is done by
    pixel replication.

    We also provide 3x and 4x scale-to-gray reduction on binary images
    to produce high quality reduced grayscale images.

    Conversely, we have special 2x and 4x scale-to-binary expansion
    on grayscale images, using linear interpolation on grayscale
    raster line buffers followed by either thresholding or dithering.  

    Image shear has no bpp constraints.  We provide shearing
    about an arbitrary point (really, a line), both in-place and
    from source to dest.

    There are two different types of general image rotators:

	a.  Grayscale rotation using area mapping
	    - pixRotateAM() for 8 bit gray and 24 bit color, about center
	    - pixRotateAMCorner() for 8 bit gray, about image UL corner

	b.  Rotation of an image of arbitrary bit depth, using
	    either 2 or 3 shears.  These rotations can be done
	    about an arbitrary point, and they can be either 
	    from source to dest or in-place; e.g.
	    - pixRotateShear()
	    - pixRotateShearIP()

	The area mapping rotations are slow and more accurate,
	because each new pixel is composed using an average of four
	neighboring pixels in the original image; this is sometimes
	called "anti-aliasing".  The low-level code is in rotateamlow.c.

	The shear rotations are much faster, and work on images
	of arbitrary pixel depth, but they just move pixels
	around without doing any averaging.  The pixRotateShearIP()
	operates on the image in-place.

    We also provide orthogonal rotators (90, 180, 270 degree)
    for arbitrary image depth.  The low-level code is in
    rotateorthlow.c

10. We provide a number of sequential algorithms, including 
    binary and grayscale seedfill, and the distance function for
    a binary image.  The most efficient binary seedfill is
    pixSeedfill(), which uses Vincent's algorithm to iterate
    raster- and antiraster-ordered propagation, and can be used
    for either 4- or 8-connected fills.  Similar raster/antiraster
    sequential algorithms are used to generate a distance map from
    a binary image, and for grayscale seedfill.  We also use Heckbert's 
    stack-based filling algorithm for identifying 4- and 8-connected
    components in an image.

11. A few simple image enhancement routines for grayscale and
    color images have been provided.  These include intensity mapping
    with gamma correction and contrast enhancement, as well as edge
    sharpening and smoothing.

12. Some facilities have been provided for image input and output.
    This is of course required to build executables that handle images,
    and a number of small executables have been built in the prog
    directory, mostly for testing purposes.  Functions have been
    provided to allow reading and writing of files in BMP, JPEG and
    PNG formats.  These particular formats were chosen for the
    following reasons:

        - BMP has (until recently) had no compression, and hence it is
	  s an exceedingly simple format.  It is commonly used because
	  it is a microsoft standard.

	- JFIF JPEG is the standard method for lossy compression
	  of grayscale and color images.  It is supported natively
	  in all browsers, and uses a good open source compression
	  library.

	- PNG is the standard method for lossless compression
	  of binary, grayscale and color images.  It is supported
	  natively in all browsers, and uses a good open source
	  compression library.  It is superior in almost every
	  respect to GIF (which, in any event, contains proprietary
	  LZW compression).

    All three formats support 8 bpp grayscale, 8 bpp palette
    color and 24 bpp rgb color.  BMP and PNG also support 
    binary images, and PNG supports 2 and 4 bpp images with
    and without palette.

    We also provide binary, 8 bpp gray and 24 bpp full color PS output,
    with a variety of options for scaling the image and printing
    at different resolutions.

    We provide colormap removal for conversion to 8 bpp gray or
    for conversion to 24 bpp full color, as well as conversion
    from RGB to 8 bpp grayscale.  We also provide the inverse
    function to colormap removal; namely, color quantization
    from 24 bpp full color to 8 bpp palette with some number
    of palette colors.  This uses a fast octree vector quantizer.

    A function can be called to display an image immediately on
    the screen using xv.  We provide the reduction, if necessary,
    including scale-to-gray for readability.

13. Simple data structures are provided for safe and
    efficient handling of arrays of numbers, strings, pointers,
    and bytes.  The pointer array is implemented as a stack.
    The byte array is implemented as a queue.  The string arrays
    are particularly useful for both parsing and composing text.
    Generic lists with doubly-linked cons cells are also provided.

14. Examples of programs that are easily built using the library:

        - for plotting x-y data, both programmatic and file
          interfaces to the gnuplot program (e.g., plotprog
	  and plotfile) and with output to X11, png, ps or eps

	- a simple jbig2 classifier, using various distance
	  metrics between image components (e.g., jbig2haus,
	  jbig2correl, jbig2rankhaus, jbig2errors, etc.)

15. The jmorecfg.h file of the jpeg library (re)defines our
    typedefs for the basic data types (e.g., UINT8, INT8, ...),
    which in some cases have slightly different meanings.
    For example, we use 
        typedef long int INT32;
    whereas jmorecfg.h uses
        typedef long INT32;
    To avoid warning messages about redefining variables, we
    place jpeglib.h (version 6b, with the 'extern "C"' macro added
    for C++ compatibility) and a slightly altered version
    of jmorecfg.h in the src directory.  The -I./ flag includes
    both local files, rather than the ones in /usr/include; 
    the jpeglib.h file because of the order on the compile line 
    and the jmorecfg.h file because fortunately jpeglib.h
    included "jmorecfg.h" instead of .
    These local files prevent compiler warnings; without them,
    everything will still compile properly.

16. If you use this library with other systems, you have three
    choices with respect to the PIX data structure.  It is
    easiest if you can use the PIX directly.  Next easiest is to
    make a pix from the local image data structure; see the
    file pix.h for the constraints on the image data that will
    permit you to avoid data replication.  The most work is to
    provide new high-level shims from the local image data 
    structure to the low-level functions in the library, which
    take only built-in C data types.

17. Leptonlib library version numbers are provided for reference,
    so that you know if a more recent version than the one you are
    using exists.  A version chronology is maintained in
    version-notes.txt.