Technical design
Here is the functional design translated to actual C-modules.
Note that some blocks do not have headers and that others consist only of headers.
This is inherent to the functional design. Eg. the implementation of the main header file is split in 4 different modules.
Now you could argue to put them in a single file, but I felt it more logical to split them up.
In other cases the functional block only results in specification rather than implementation.
Hence the result is a header-file only.
Also note that the layout of the image doesn't necessarily enforce certain dependancies.
Eg. "libmng_read" calls functions in "libmng_chunk_io" which in turn calls functions in
"libmng_zlib" which in turn calls functions in "libmng_pixels". "libmng_chunk_io"
also calls functions in "libmng_display" which in turn calls functions in "libmng_pixels".
It's a web, I know. C'est la vie! The general tendency however is top-to-bottom.
The main interface header. This is an application's link to the High Level API (HLAPI) functions of the library.
Applications need only this header.
This header defines platform-dependant stuff and some other tid-bits that are not
required in the main header file, but are quite handy to have around at the top-level. So "libmng.h"
simply includes this file. This keeps the main interface clear and concise. This is also the place of the callback prototypes.
To obtain the requirements to be re-entrant and thread-safe the library needs to store its
internal state variables in a dynamic buffer. This buffer is created when the app initializes the library.
The pointer to the buffer is then returned to the app as a handle. While this virtually hides the underlying data-structure(s),
it is still possible for the app to mess with the data.
To all developers: DO NOT ACCESS THE DATA DIRECTLY; USE THE GET&SET FUNCTIONS!!!!
The data-structure(s) may change over time and your app will be broken. Be sensible please!
This baby contains the main functions such as "initialize", "reset", "cleanup", "read", "display", etc, etc.
Here you'll find the GET/SET functions for the callbacks. libmng makes extensive use of callback functions. I'll explain on the next page.
This contains the GET/SET functions for internal variables that may be of interest to the application.
This defines the functions for access at the chunk level. Shame on you if you don't know what a chunk is (back to the basics for you then!).
Here's where the generic read-logic is housed. This module uses the read callback to get data from the input, identifies it and sends it to the appropriate chunk-read-processing function. Note that this is also the routine called for the read&display HLAPI function. The chunk-read-processing routines also know how to handle the display functionality of a chunk.
This module handles the output of a MNG.
The module that handles displaying of a MNG. Note that most basic MNG display applications will simply use the read&display HLAPI function.
This header defines the internal structures used for storing and maintaining internal objects, including the objects and object-buffers mentioned in the MNG specification.
Here are the functions that deal with the internal objects. They provide initialization, cleanup, 'cloning' and display processing.
This contains the structures for storing chunks.
These contain the chunk initialization and cleanup functions.
Here are the chunk read & write logic, but you will also find display-processing in the read-bits.
This header defines the memory management functions. It's basically just a set of macros.
The error-handling functions. Called from basically every module in case of problems.
The trace function. This is basically just the low-level interface to the trace callback.
Here's where it's happening. This module contains all the low-level pixel juggling. Bit-depth conversions, interlacing and filtering processing. All functions are actually internal callbacks, called from various other modules through the main data-structure.
This contains the actual filter routines. Called only from pixel-processing.
The module responsible for dithering.
This defines the low-level interface to the external zlib package.
The low-level interface to the Independant JPEG Group (IJG) jpgsrc.
This is where all color-correction is handled. Interfaces with lcms ("little cms" by Marti Maria Saguer) and holds the gamma-only correction functionality.