GID - the Generic Image Decoder
-------------------------------

The Generic Image Decoder (GID) is an Ada package for decoding a
broad variety of image formats, from any data stream, to any kind
of medium, be it an in-memory bitmap, a GUI object,
some other stream, arrays of floating-point initial data
for scientific calculations, a browser element, a device,...

Animations are supported.

Some features:

- Standalone (no dependency on other libraires, bindings,...)
- Unconditionally portable code: OS-, CPU-, compiler- independent code.
- Multi-platform, but native code
- Task safe
- Endian-neutral
- Free, open-source
- pure Ada 95 (compiled by Ada 95, Ada 2005, and later compilers)

Some possible applications:

- image processing (interactive or not)
- image analysis, text recognition
- a drawing program
- a web browser
- use of images as data for simulations
- thumbnail generation for a file manager

Through the genericity and the use of the Inline pragma at multiple
nesting levels (see it like macros inside macros), the package is
able to deliver a decent decoding performance, keep a reasonably
compact and readable source code, and avoid tediously copied
pieces of code with almost the same contents corresponding to
different subformats.

Licensing, warranty, copyright, supported formats, authors, credits, history
----------------------------------------------------------------------------
Please read the top comments in gid.ads, and further details in gid_work.xls.

Files
-----
    gid.ads   GID package specification
    gid.adb   GID package body
    gid-*.ad* private packages for decoding specific
                formats, reading headers,...

To summarize, the gid*.ad* files are the whole GID source files. 
For example, you can have a copy of those in a gid/ subdirectory
in your project.

    gid.gpr             GNAT/GCC project file - to be opened with GPS or used
                          with the command: gnatmake -P gid
    gid_objectada.prj   ObjectAda (7.2.2+) project file
    
    gid_work.xls        this workbook contains GID's history, a list of open
                          bugs, technical informations about formats, etc.
    
    test/to_bmp.adb     middle-size command-line demo which converts all image
                          files given as arguments (also works from a GUI file
                          explorer with drag & drop) into BMP image files with
                          the .dib extension. Typically, you put plenty of
                          images into the test folder and launch "to_bmp *" to
                          convert them all.
    test/mini.adb       small-size version of to_bmp; writes PPM files.
    test/steg.adb       steganography tool (hide an image into a data)
    test/recurve.adb    image processing demo: recover curves from a chart
    
    test/tb*.ad*        wrappers for to_bmp, for obtaining trace-back
    
How to use GID in your programs
-------------------------------
Hopefully the package specification (in the file gid.ads) is self
explanatory enough. There are three steps needed:

1) Load the image header from a data stream
2) If needed, use dimensions to prepare the retrieval of the image
3) Load and decode the image itself. If the image is animated,
     call Load_image_contents until next_frame is 0.0

The subprograms corresponding to these steps are
1) Load_image_header
2) Pixel_width and Pixel_height 
3) Load_image_contents

Load_image_contents is generic. You provide the following:
  * Primary_color_range: the type of primary colors.
    Usually it is a byte (E.g. Unsigned_8)
  * procedure Set_X_Y: setting a "cursor" (an array index, for instance)
  * procedure Put_Pixel: set a color (and transparency) on
      the "cursor" place; the cursor is meant to move one pixel
      to te right, then
  * procedure Feedback: display progress (if you want or need it;
      otherwise, you can always provide an empty procedure)
  * mode: Display_mode: here you tell if you want the decoding rather
      nicer or faster, when the decoder is processing "progressive"
      (JPEG) or "interlaced" (GIF, PNG) pictures. Note: the end
      result is exactly the same. The visual difference appears only
      during the decoding.

This generic construction allows you a total freedom on where and
how to use GID in your programs. In addition, your Set_X_Y and
Put_Pixel procedures are inserted at compile-time, (no call instruction),
right in the heart of the decoding procedures, for each image format,
which should deliver a decent performance as soon as you set the right
compiler options (optimization, inlined or macro-expanded generics,
suppression of all checks, loop unrolling).

*Important note*: the performance of GID is mostly dependant of the code
you provide in Put_Pixel. If it is much more that inserting a byte into
a buffer and advancing an index or a pointer, you will get an important
performance penalty. Remember that Put_Pixel is called... for each pixel.

How to build GID
----------------
- From GPS, press F4. The main test's (to_bmp) executable is built
     in the /test folder.
- From ObjectAda's IDE, press F7. to_bmp.exe is in the folder
     created by ObjectAda upon first project opening.
- From AdaGIDE, press F3. There will be .o and .ali files at unexpected
     places, so it's better to build first with GPS or the command line
- From the command line, with GNAT:
   - default build mode: gprbuild -P gid
   - other build mode (e.g. Small): gprbuild -P gid -XBuild_Mode=Small
   
We assume here you consider GID unpacked "out of the box", with directories.

Memory requirements and usage
-----------------------------
GID uses only memory for decoding purposes (e.g. decompression
structures, color tables) and doesn't store the image itself.
As a result, memory will be reserved for at most only one copy of
the output bitmap, and this under the format you want or need to have.
As an example, the to_bmp demo stores the image as a packed
RBG byte array with a 4-byte padding which is the appropriate
format for dumping a BMP file in the end. But there are many
other possible storage formats, and GID lets you the total
freedom about it. It can be even the case that the bitmap
storage is more appropriate through an operating system or
a specific library; in such a case you would not store the
bitmap within the Ada progam at all and Put_Pixel would be used
to transmit the pixels further.
All memory used by GID is taken on the stack, with the exception
of palettes and JPEG's DHT tables. Those are dynamically allocated
on the heap and deallocated upon scope end of a variable of the
Image_descriptor type. It means there is no possible memory leak. 
The use of heap allocation is justified there because of the
relatively large size of those objects. They could very well
be also part of the descriptor record, with a maximal size for
palette (2**16, for the TGA format).

Where to find the latest version
--------------------------------
Please check the "web" constant in gid.ads.
     
Note on the construction of GID.
--------------------------------
All image formats decoded by GID have similarities in their structure.

- Most streams begin with a signature, followed by a header
  containing dimensions and the color depth. Then the image contents
  follow. This is obvious to have such a data organisation,
  since the header details are needed to calibrate the recipient
  of the image.

- Streams are structured in blocks of data which are given different
  names depending on the format:
  - PNG : chunks
  - GIF : blocks
  - JPEG: segments
  - TGA : areas
  - TIFF: tags
  etc.

