DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 

libmng(3)





NAME

       libmng - Multiple-image Network Graphics (MNG) Reference Library 1.0.9


SYNOPSIS


       #include <libmng.h>


DESCRIPTION

       The libmng library supports decoding, displaying, encoding, and various
       other manipulations of the Multiple-image Network Graphics (MNG) format
       image  files.  It  uses the zlib(3) compression library, and optionally
       the JPEG library by the Independant JPEG Group (IJG) and/or lcms  (lit-
       tle cms), a color-management library by Marti Maria Saguer.


I. Introduction

       This  file  describes  how  to use and modify the MNG reference library
       (known as libmng) for your own use.  There are seven sections  to  this
       file: introduction, callbacks, housekeeping, reading, displaying, writ-
       ing, and modification and configuration notes for various special plat-
       forms.   We   assume   that   libmng  is  already  installed;  see  the
       INSTALL.README file for instructions on how to install libmng.

       Libmng was written to support and promote the MNG specification.

       The       MNG-1.0       specification       is       available       at
       <http://www.libpng.org/pub/mng/spec/>.

       Other  information  about  MNG  can  be  found  at  the  MNG home page,
       <http://www.libpng.org/pub/mng/>.  The latest version of libmng can  be
       found at its own homepage at <http://www.libmng.com/>.

       In  most  cases the library will not need to be changed.  For standard-
       ization purposes the library contains both a Windows DLL and a makefile
       for building a shared library (SO). The library is written in C, but an
       interface for Borland Delphi is also available.

       Libmng has been designed to handle multiple sessions at one time, to be
       easily  modifiable,  to  be  portable  to the vast majority of machines
       (ANSI, K&R, 32-, and 64-bit) available, and to be easy to use.

       Libmng uses zlib for its compression and decompression  of  MNG  files.
       Further  information about zlib, and the latest version of zlib, can be
       found at the zlib home page, <http://www.zlib.org/>.  The zlib compres-
       sion  utility is a general purpose utility that is useful for more than
       MNG/PNG files, and can be used without libmng.  See  the  documentation
       delivered with zlib for more details.

       Libmng  optionally  uses the JPEG library by the Independant JPEG Group
       (IJG). This library is used for the JNG sub-format, which  is  part  of
       the  MNG  specification,  and  allows for inclusion of JPEG decoded and
       thus highly  compressed  (photographic)  images.   Further  information
       about  the  IJG  JPEG  library  and  the latest sources can be found at
       <http://www.ijg.org/>.

       Libmng can also optionally use the lcms (little CMS) library  by  Marti
       Maria  Saguer. This library provides an excellent color-management sys-
       tem (CMS), which gives libmng the ability to provide full color-correc-
       tion  for  images  with  the proper color-information encoded.  Further
       information and the latest sources can  be  found  at  <http://www.lit-
       tlecms.com/>.

       Libmng is thread safe, provided the threads are using different handles
       as returned by the initialization call.  Each thread  should  have  its
       own  handle  and  thus  its  own image.  Libmng does not protect itself
       against two threads using the same instance of a handle.

       The libmng.h header file is the single reference needed for programming
       with libmng:

       #include <libmng.h>


II. Callbacks

       Libmng makes extensive use of callback functions. This is meant to keep
       the library as platform-independant and flexible  as  possible.   Actu-
       ally,  the  first  call  you will make to the library, already contains
       three parameters you can use to provide callback entry-points.

       Most functions must return a mng_bool  (boolean).  Returning  MNG_FALSE
       indicates  the  library the callback failed in some way and the library
       will immediately return from whatever it was doing back to the applica-
       tion.  Returning MNG_TRUE indicates there were no problems and process-
       ing can continue.

       Let's step through each of the  possible  callbacks.  The  sections  on
       reading,  displaying  and writing will also explain which callbacks are
       needed when and where.

       - mng_ptr mng_memalloc (mng_size_t iLen)

       A very basic function which the library uses to allocate a memory-block
       with the given size. A typical implementation would be:

           mng_ptr my_alloc (mng_size_t iLen) {
             return calloc (1, iLen);
           }

       Note that the library requires you to zero-out the memory-block!!!

       - void mng_memfree (mng_ptr    pPtr,
                           mng_size_t iLen)

       Counterpart of the previous function. Typically:

           void my_free (mng_ptr pPtr, mng_size_t iLen) {
             free (pPtr);
           }

       - mng_bool mng_openstream  (mng_handle hHandle)

       - mng_bool mng_closestream (mng_handle hHandle)

       These  are  called  by  the  library  just  before it starts to process
       (either read or write) a file and  just  after  the  processing  stops.
       This  is the recommended place to do I/O initialization & finalization.
       Whether you do or not, is up to you. The library does not put any mean-
       ing into the calls. They are simply provided for your convenience.

       - mng_bool mng_readdata (mng_handle  hHandle,
                                mng_ptr     pBuf,
                                mng_uint32  iBuflen,
                                mng_uint32p pRead)

       This  function  is  called when the library needs some more input while
       reading an image. The reading process supports two  modes:  Suspension-
       mode  (SMOD)  and non-suspension-mode (NSMOD).  See mng_set_suspension-
       mode() for a more detailed description.

       In NSMOD, the library requires you to  return  exactly  the  amount  of
       bytes requested (= iBuflen). Any lesser amount indicates the input file
       is exhausted and the library will return a MNG_UNEXPECTEDEOF errorcode.

       In SMOD, you may return a smaller amount of bytes than requested.  This
       tells the library it should temporarily wait for more input to  arrive.
       The  lib  will  return with MNG_NEEDMOREDATA, and will expect a call to
       mng_read_resume() or mng_display_resume() next, as soon as more  input-
       data has arrived.

       For NSMOD this function could be as simple as:

           mng_bool my_read (mng_handle  hHandle,
                             mng_ptr     pBuf,
                             mng_uint32  iBuflen,
                             mng_uint32p pRead) {
             *pRead = fread (pBuf, 1, iBuflen, myfile);
             return MNG_TRUE;
           }

       - mng_bool mng_writedata (mng_handle  hHandle,
                                 mng_ptr     pBuf,
                                 mng_uint32  iBuflen,
                                 mng_uint32p pWritten)

       This  function  is  called  during the mng_write() function to actually
       output data to the file. There is no suspension-mode during  write,  so
       the  application  must  return  the  exact  number of bytes the library
       requests to be written.

       A typical implementation could be:

           mng_bool my_write (mng_handle  hHandle,
                              mng_ptr     pBuf,
                              mng_uint32  iBuflen,
                              mng_uint32p pWritten) {
             *pWritten = fwrite (pBuf, 1, iBuflen, myfile);
             return MNG_TRUE;
           }

       - mng_bool mng_errorproc (mng_handle  hHandle,
                                 mng_int32   iErrorcode,
                                 mng_int8    iSeverity,
                                 mng_chunkid iChunkname,
                                 mng_uint32  iChunkseq,
                                 mng_int32   iExtra1,
                                 mng_int32   iExtra2,
                                 mng_pchar   zErrortext)

       This function is called  whenever  an  error  is  detected  inside  the
       library.  This  may  be  caused  by invalid input, callbacks indicating
       failure, or wrongfully calling functions out of place.

       If you do not provide this callback the library will  still  return  an
       errorcode from the called function, and the mng_getlasterror() function
       can be used to retrieve the other parameters.

       This function is currently only provided for convenience,  but  may  at
       some  point  be  used to indicate certain errors may be acceptable, and
       processing should continue.

       - mng_bool mng_traceproc (mng_handle hHandle,
                                 mng_int32  iFuncnr,
                                 mng_int32  iFuncseq,
                                 mng_pchar  zFuncname)

       This function is  provided  to  allow  a  functional  analysis  of  the
       library.  This may be useful if you encounter certain errors and cannot
       determine what the problem is.

       Almost all functions inside the library  will  activate  this  callback
       with an appropriate function-name at the start and end of the function.
       Please note that large images may generate an enormous amount of calls.

       - mng_bool mng_processheader (mng_handle hHandle,
                                     mng_uint32 iWidth,
                                     mng_uint32 iHeight)

       This  function is called once the header information of an input- image
       has been processed. At this point the image  dimensions  are  available
       and  also some other properties depending on the type of the image. Eg.
       for a MNG the  frame-/layercount,  playtime  &  simplicity  fields  are
       known.

       The  primary  purpose  of this callback is to inform the application of
       the size of the image, and for the application to initialize the  draw-
       ing  canvas to be used by the library. This is also a good point to set
       the canvas-style. Eg. mng_set_canvasstyle().

       - mng_bool mng_processtext (mng_handle hHandle,
                                   mng_uint8  iType,
                                   mng_pchar  zKeyword,
                                   mng_pchar  zText,
                                   mng_pchar  zLanguage,
                                   mng_pchar  zTranslation)

       This callback is activated for each textual chunk in the input-  image.
       These are tEXt, zTXt & iTXt. It may be used to retain specific comments
       for presentation to the user.

       - mng_bool mng_processsave (mng_handle hHandle)

       - mng_bool mng_processseek (mng_handle hHandle,
                                   mng_pchar  zName)

       The purpose of these callbacks is to signal the processing of the  SAVE
       &  SEEK  chunks  in a MNG input-file. This may be used in the future to
       specify some special processing. At the moment these functions are only
       provided as a signal.

       - mng_ptr mng_getcanvasline (mng_handle hHandle,
                                    mng_uint32 iLinenr)

       - mng_ptr mng_getbkgdline   (mng_handle hHandle,
                                    mng_uint32 iLinenr)

       - mng_ptr mng_getalphaline  (mng_handle hHandle,
                                    mng_uint32 iLinenr)

       These  callbacks are used to access the drawing canvas, background can-
       vas and an optional separate alpha-channel canvas. The latter  is  used
       only with the MNG_CANVAS_RGB8_A8 canvas-style.

       If  the getbkgdline() callback is not supplied the library will compos-
       ite fully or partially transparent pixels in the image against a speci-
       fied  background  color.  See mng_set_bgcolor() for more details.  If a
       chosen canvas-style includes an alpha-channel, this  callback  is  very
       likely not needed.

       The  application  is  responsible  for returning a pointer to a line of
       pixels, which should be in the exact format as defined by the  call  to
       mng_set_canvasstyle() and mng_set_bkgdstyle(), without gaps between the
       representation of each pixel, unless specified by the canvas-style.

       - mng_bool mng_refresh (mng_handle hHandle,
                               mng_uint32 iX,
                               mng_uint32 iY,
                               mng_uint32 iWidth,
                               mng_uint32 iHeight)

       This callback is called when the library has  drawn  a  complete  frame
       onto the drawing canvas, and it is ready to be displayed.  The applica-
       tion is responsible for transferring the  drawing  canvas  from  memory
       onto the actual output device.

       - mng_uint32 mng_gettickcount (mng_handle hHandle)

       This function should return the number of milliseconds on some internal
       clock. The entire animation timing depends heavily  on  this  function,
       and the number returned should be as accurate as possible.

       - mng_bool mng_settimer (mng_handle hHandle,
                                mng_uint32 iMsecs)

       This  callback  is activated every time the library requires a "pause".
       Note that the function itself should NOT execute the  wait.  It  should
       simply  store  the  time-field  and allow the library to return. Libmng
       will return with the MNG_NEEDTIMERWAIT code,  indicating  the  callback
       was called and it is now time to execute the pause.

       After  the  indicated number of milliseconds have elapsed, the applica-
       tion should call  mng_display_resume(),  to  resume  the  animation  as
       planned.

       This  method  allows  for both a real timer or a simple wait command in
       the application. Whichever method you select, both  the  gettickcount()
       and settimer() callbacks are crucial for proper animation timing.

       - mng_bool mng_processgamma  (mng_handle hHandle,
                                     mng_uint32 iGamma)

       - mng_bool mng_processchroma (mng_handle hHandle,
                                     mng_uint32 iWhitepointx,
                                     mng_uint32 iWhitepointy,
                                     mng_uint32 iRedx,
                                     mng_uint32 iRedy,
                                     mng_uint32 iGreenx,
                                     mng_uint32 iGreeny,
                                     mng_uint32 iBluex,
                                     mng_uint32 iBluey)

       - mng_bool mng_processsrgb   (mng_handle hHandle,
                                     mng_uint8  iRenderingintent)

       - mng_bool mng_processiccp   (mng_handle hHandle,
                                     mng_uint32 iProfilesize,
                                     mng_ptr    pProfile)

       - mng_bool mng_processarow   (mng_handle hHandle,
                                     mng_uint32 iRowsamples,
                                     mng_bool   bIsRGBA16,
                                     mng_ptr    pRow)

       These  callbacks  are  only  required when you selected the MNG_APP_CMS
       directive during compilation of the library. See the configuration sec-
       tion for more details.

       - mng_bool mng_iteratechunk (mng_handle  hHandle,
                                    mng_handle  hChunk,
                                    mng_chunkid iChunkid,
                                    mng_uint32  iChunkseq)

       This  callback  is only used for the mng_iterate_chunks() function.  It
       is called exactly once for each chunk stored.


III. Housekeeping

   Memory management
       The library can use internal memory allocation/deallocation or use pro-
       vided callbacks for its memory management. The choice is made at compi-
       lation time. See the section on customization for details.

       If internal management has been selected, the memory callback functions
       need not be supplied. Even if you do supply them they will not be used.
       The actual code used is similar to the code discussed in  the  callback
       section:

             pPtr = calloc (1, iLen);

             free (pPtr);

       If your compiler does not support these functions, or you wish to moni-
       tor the library's use of memory for certain reasons, you can choose  to
       compile  the  library with external memory management. In this case the
       memory callback functions MUST be supplied, and should function  as  if
       the above code was used.

   Initialization
       The basic initialization of the library is short and swift:

           myhandle = mng_initialize (myuserdata, my_alloc,
                                      my_free, MNG_NULL);
           if (myhandle == MNG_NULL)
             /* process error */;

       The  first  field  is  an  application-only  parameter.  It is saved in
       libmng's internal structures and available at  all  times  through  the
       mng_get_userdata() function. This is especially handy in callback func-
       tions if your program may be handling multiple files at the same  time.

       The  second and third field supply the library with the memory callback
       function entry-points. These are described in more detail in the  call-
       back section and the previous paragraph.

       The  fourth  and  last field may be used to supply the library with the
       entry-point of a trace callback function. For regular use you will  not
       need this!

       The  function returns a handle which will be your ticket to MNG-heaven.
       All other functions rely on this handle. It is the single fixed  unique
       reference-point between your application and the library.

       You  should call the initialization function for each image you wish to
       process simultaneously. If you are processing images consecutively, you
       can reset the internal status of the library with the mng_reset() func-
       tion.  This function will clear all internal state variables, free  any
       stored chunks and/or objects, etc, etc. Your callbacks and other exter-
       nal parameters will be retained.

       After you successfully received the  handle  it  is  time  to  set  the
       required callbacks. The sections on reading, displaying & writing indi-
       cate which callbacks are required and which are optional.  To  set  the
       callbacks simply do:

           myretcode = mng_setcb_xxxxxx (myhandle, my_xxxxxx);
           if (myretcode != MNG_NOERROR)
             /* process error */;

       Naturally you'd replace the x's with the name of the callback.

   Cleanup
       Once you've gotten hold of that precious mng_handle, you should always,
       and I mean always, call the cleanup function when  you're  done.   Just
       do:

           mng_cleanup (myhandle);

       And  you're  done.  There shouldn't be an ounce of memory spilled after
       that call.

       Note that if you would like to process multiple files consecutively you
       do  not  need  to do mng_cleanup() / mng_initialize() between each file
       but simply

           myretcode = mng_reset (myhandle);
           if (myretcode != MNG_NOERROR)
             /* process error */;

       will suffice. Saves some time and effort, that.

   Error handling
       From the examples in the previous paragraphs you  may  have  noticed  a
       meticulous  scheme  for error handling. And yes, that's exactly what it
       is.  Practically each call simply returns an errorcode, indicating suc-
       cess,  eg.  MNG_NOERROR  or failure, anything else but MNG_NEEDMOREDATA
       and MNG_NEEDTIMERWAIT. These latter  two  will  be  discussed  in  more
       detail  in their respective fields of interest: the reading section and
       displaying section respectively.

       It is the application's responsibility to check  the  returncode  after
       each  call.  You  can call mng_getlasterror() to receive the details of
       the last detected error. This even includes a discriptive error-message
       if you enabled that option during compilation of the library.

       Note  that  after  receiving  an error it is still possible to call the
       library, but it's also very likely that any following call  will  fail.
       The   only   functions   deemed   to   work  will  be  mng_reset()  and
       mng_cleanup().  Yes, if you abort your  program  after  an  error,  you
       should still call mng_cleanup().


IV. Reading

       Reading  a  MNG, JNG or PNG is fairly easy. It depends slightly on your
       ultimate goal how certain specifics are to be handled, but  the  basics
       are similar in all cases.

       For the read functioins to work you must have compiled the library with
       the MNG_READ_SUPPRT directive. The standard DLL and Shared Library have
       this on by default!

   Setup
       Naturally  you  must have initialized the library and be the owner of a
       mng_handle. The following callbacks are essential:

           mng_openstream, mng_readdata, mng_closestream

       You may optionally define:

           mng_errorproc, mng_traceproc
           mng_processheader, mng_processtext
           mng_processsave, mng_processseek

       The reading bit will also fail if you are already creating or  display-
       ing  a file. Seems a bit obvious, but I thought I'd mention it, just in
       case.

   To suspend or not to suspend
       There is one choice you need to make before calling the read  function.
       Are you in need of suspension-mode or not?

       If  you're  reading  from a disk you most certainly do not need suspen-
       sion-mode. Even the oldest and slowest of disks will be fast enough for
       straight reading.

       However,  if  your  input  comes  from  a really slow device, such as a
       dialup-line or the likes, you may opt for suspension-mode. This is done
       by calling

           myretcode = mng_set_suspensionmode (myhandle,
                                               MNG_TRUE);
           if (myretcode != MNG_NOERROR)
             /* process error */;

       Suspension-mode  will force the library to use special buffering on the
       input. This allows your application  to  receive  data  of  arbitrarily
       length and return this in the mng_readdata() callback, without disturb-
       ing the chunk processing routines of the library.

       Suspension-mode does require a little extra care in the main  logic  of
       the  application.  The  read  function may return with MNG_NEEDMOREDATA
       when the mng_readdata() callback returns less data  then  it  needs  to
       process the next chunk. This indicates the application to wait for more
       data to arrive and then resume processing by calling mng_read_resume().

   The read HLAPI
       The  actual reading is just plain simple. Since all I/O is done outside
       the library through the callbacks, the library can focus  on  its  real
       task. Understanding, checking and labelling the input data!

       All you really need to do is this:

           myretcode = mng_read (myhandle);
           if (myretcode != MNG_NOERROR)
             /* process error */;

       Of  course, if you're on suspension-mode the code is a little more com-
       plicated:

           myretcode = mng_read (myhandle);

           while (myretcode == MNG_NEEDMOREDATA) {
             /* wait for input-data to arrive */
             myretcode = mng_read_resume (myhandle);
           }

           if (myretcode != MNG_NOERROR)
             /* process error */;

       This is rather crude and more  sophisticated  programming  methods  may
       dictate  another approach. Whatever method you decide on, it should act
       as if the above code was in its place.

       There is also the mng_readdisplay() function, but this is discussed  in
       the  displaying  section.  It  functions  pretty much as the mng_read()
       function,  but  also   immediately   starts   displaying   the   image.
       mng_read_resume()  should  be  replaced by mng_display_resume() in that
       case!

   What happens inside
       What actually happens inside the library depends on  the  configuration
       options set during the compilation of the library.

       Basically the library will first read the 8-byte file header, to deter-
       mine its validity and the type of image it is about to process. Then it
       will  repeatedly  read  a 4-byte chunk-length and then the remainder of
       the chunk until it either reaches EOF (indicated by the  mng_readdata()
       callback)  or implicitly decides EOF as it processed the logically last
       chunk of the image.

       Applications that require strict conformity and do not allow  superflu-
       ous  data  after  the  ending chunk, will need to perform this check in
       their mng_closestream() callback.

       Each chunk is then checked on CRC, after which it is handed over to the
       appropriate  chunk  processing  routine. These routines will disect the
       chunk, check the validity of its  contents,  check  its  position  with
       respect to other chunks, etc, etc.

       If everything checks out, the chunk is further processed as follows:

       If  display  support has been selected during compilation, certain pre-
       display initialization will take place.

       If chunk-storage support has  been  selected  during  compilation,  the
       chunks  data may be stored in a special internal structure and held for
       future reference.

   Storing and accessing chunks
       One of the compilation options activates  support  for  chunk  storage.
       This  option  may be useful if you want to examine an image. The direc-
       tive is MNG_STORE_CHUNKS. You must also turn on  the  MNG_ACCESS_CHUNKS
       directive.

       The  actual  storage  facility  can  be  turned  on  or  off  with  the
       mng_set_storechunks() function. If set  to  MNG_TRUE,  chunks  will  be
       stored as they are read.

       At  any  point  you  can then call the mng_iterate_chunks() function to
       iterate through the current list of chunks. This  function  requires  a
       callback  which is called for each chunk and receives a specific chunk-
       handle.  This  chunk-handle  can  be  used  to  call  the   appropriate
       mng_getchunk_xxxx() function, to access the chunks properties.

       A typical implementation may look like this:

           mng_bool my_iteratechunk (mng_handle  hHandle,
                                     mng_handle  hChunk,
                                     mng_chunkid iChunkid,
                                     mng_uint32  iChunkseq) {
             switch (iChunkid) {
               case MNG_UINT_MHDR : { /* process MHDR */;
                                      break; }
               case MNG_UINT_FRAM : { /* process FRAM */;
                                      break; }

                   ...etc...

               case MNG_UINT_HUH  : { /* unknown chunk */;
                                      break; }
               default : { /* duh; forgot one */; }
             }

             return MNG_TRUE; /* keep'm coming */
           }

       To  get  to  the actual chunk fields of lets say a SHOW chunk you would
       do:

           mng_bool isempty;
           mng_uint16 firstid, lastid;
           mng_uint8 showmode;

           myretcode mng_getchunk_show (hHandle, hChunk,
                                        isempty, firstid,
                                        lastid, showmode);
           if (myretcode != MNG_NOERROR)
             /* process error */;


V. Displaying

   Setup
       Assuming you have initialized the  library  and  are  the  owner  of  a
       mng_handle. The following callbacks are essential:

           mng_getcanvasline, mng_refresh
           mng_gettickcount, mng_settimer

       If you wish to use an application supplied background you must supply:

           mng_getbkgdline

       If you wish to use the MNG_CANVAS_RGB8_A8 canvas style you must supply:

           mng_getalphaline

       You may optionally define:

           mng_errorproc, mng_traceproc
           mng_processheader, mng_processtext
           mng_processsave, mng_processseek

       Note that the mng_processheader() callback  is  optional  but  will  be
       quite significant for proper operation!

       Displaying  an  image  will  fail if you are creating a file or already
       displaying one. Yes, you can't display it twice!

   A word on canvas styles
       The canvas style describes how your drawing canvas  is  made  up.   You
       must  set  this  before  the  library  actually  starts drawing, so the
       mng_processheader() callback is a pretty good place for it.

       Currently only 8-bit RGB canvas styles are supported,  either  with  or
       without an alpha channel.

       If  you like to do alpha composition yourself you can select one of the
       canvas styles that include an alpha channel. You can even have a  sepa-
       rate alpha canvas by selecting the MNG_CANVAS_RGB8_A8 style.

       All  styles  require a compact model. Eg. MNG_CANVAS_BGR8 requires your
       canvas lines in bgrbgrbgr... storage, where each letter  represents  an
       8-bit value of the corresponding color, and each threesome makes up the
       values of one(1) pixel.

       The library processes a line at a time, so  the  canvas  lines  do  not
       actually need to be consecutive in memory.

   Alpha composition and application backgrounds
       All  Network  Graphics can be partially transparent. This requires spe-
       cial processing if you need to display  an  image  against  some  back-
       ground.  Note  that  the  MNG header (MHDR chunk) contains a simplicity
       field indicating whether transparency information in the file is criti-
       cal  or not. This only applies to embedded images, which means the full
       image-frame of the MNG may still contain fully transparent pixels!

       Depending on your needs you can supply a  single  background  color,  a
       background  canvas  or tell the library to return the alpha-channel and
       do alpha composition yourself.

       This is different from the BACK chunk in a MNG, or the bKGD chunk in an
       (embedded)  PNG  or JNG. The BACK chunk indicates an optional or manda-
       tory background color and/or image. The bKGD chunk  only  indicates  an
       optional  background  color.  These chunks indicate the Authors prefer-
       ences. They may be absent in which case you need to supply some sort of
       background yourself.

   Composing against a background color
       This  is the easiest method. Call the mng_set_bgcolor() function to set
       the values of the red, green and blue component of your preferred back-
       ground color.

       Use  one  of  the  canvas styles that do not have an alpha-channel, and
       which matches your output requirements.

   Composing against a background canvas
       This is somewhat more complicated. You will need to  set  the  mng_get-
       bkgdline()  callback. This will be called whenever the library needs to
       compose a partially transparent line.

       This canvas must hold the background against which the image should  be
       composed.  Its  size  must  match exactly with the image dimensions and
       thus the drawing canvas!

       Use one of the canvas styles that do not  have  an  alpha-channel,  and
       which  matches  your output requirements. The canvas style of the back-
       ground canvas may even differ from the drawing  canvas.  The  library's
       composing will still function properly.

   Composing within the application
       If you have the option in your application to draw a (partially) trans-
       parent canvas to the output device, this option is preferred.

       Select one of the canvas styles that do  have  an  alpha-channel.   The
       library will now supply the appropriate alpha information, allowing the
       application to compose the image as it sees fit.

   Color information and CMS
       Network Graphics may, and usually will, contain color-correction infor-
       mation.  This  information is intended to compensate for the difference
       in recording and display devices used.

       This document does not address the specifics of color-management.   See
       the PNG specification for a more detailed description.

   Using little cms by Marti Maria Saguer
       This is the easiest method, providing you can compile the lcms package.
       Select the MNG_FULL_CMS directive during compilation, and sit back  and
       relax. The library will take care of all color-correction for you.

   Using an OS- or application-supplied CMS
       If  you  are  so  lucky to have access to CMS functionality from within
       your application, you may instruct the library to  leave  color-correc-
       tion to you.

       Select  the  MNG_APP_CMS  directive  during compilation of the library.
       You MUST also set the following callbacks:

           mng_processgamma, mng_processchroma,
           mng_processsrgb, mng_processiccp and
           mng_processarow

       The last callback is called when the library needs you  to  correct  an
       arbitrary  line of pixels. The other callbacks are called when the cor-
       responding color-information is encountered  in  the  file.   You  must
       store this information somewhere for use in the mng_processarow() call-
       back.

   Using gamma-only correction
       This isn't a preferred method, but it's better than  no  correction  at
       all.  Gamma-only  correction will at least compensate for gamma-differ-
       ences between the original recorder and your output device.

       Select the MNG_GAMMA_ONLY directive during compilation of the  library.
       Your compiler MUST support fp operations.

   No color correction
       Ouch.  This  is really bad. This is the least preferred method, but may
       be necessary if your system cannot use lcms, doesn't have its own  CMS,
       and does not allow fp operations, ruling out the gamma-only option.

       Select  the MNG_NO_CMS directive during compilation.  Images will defi-
       nitely not be displayed as seen by the Author!!!

   Animations and timing
       Animations require some form of timing support. The library  relies  on
       two  callbacks  for  this  purpose. The mng_gettickcount() and mng_set-
       timer() callbacks. mng_gettickcount() is used to determine the  passing
       of  time  in milliseconds since the beginning of the animation. This is
       also used to compensate during suspension-mode if  you  are  using  the
       mng_readdisplay() function to read & display the file simultaneously.

       The  callback  may return an arbitrary number of milliseconds, but this
       number must increase proportionaly between calls. Most  modern  systems
       will  have  some  tickcount()  function which derives its input from an
       internal clock. The value returned from this function is more than ade-
       quate for libmng.

       The  mng_settimer()  callback  is  called when the library determines a
       little "pause" is required before rendering another frame of the anima-
       tion.  The  pause  interval  is  also  expressed in milliseconds.  Your
       application should  store  this  value  and  return  immediately.   The
       library  will  then make appropriate arrangements to store its internal
       state and returns to your application with the MNG_NEEDTIMERWAIT  code.

       At  that  point you should suspend processing and wait the given inter-
       val. Please use your OS features for this. Do not engage some  sort  of
       loop.  That  is real bad programming practice. Most modern systems will
       have some timing functions. A simple wait() function may  suffice,  but
       this may prevent your applications main-task from running, and possibly
       prevent the actual update of your output device.

   The mng_refresh() callback
       The mng_refresh() callback is called whenever  the  library  has  "fin-
       ished"  drawing  a  new frame onto your canvas, and just before it will
       call the mng_settimer() callback.

       This allows you to perform some actions necessary to "refresh" the can-
       vas  onto  your  output device. Please do NOT suspend processing inside
       this callback. This must be handled after the mng_settimer()  callback!

   Displaying while reading
       This  method  is  preferred if you are reading from a slow input device
       (such as a dialup-line) and you wish to start displaying  something  as
       quickly as possible. This functionality is provided mainly for browser-
       type applications but may be  appropriate  for  other  applications  as
       well.

       The  method  is  usually used in unison with the suspension-mode of the
       read module. A typical implementation would look like this:

           /* initiale library and set required callbacks */

           /* activate suspension-mode */
           myretcode = mng_set_suspensionmode (myhandle,
                                               MNG_TRUE);
           if (myretcode != MNG_NOERROR)
             /* process error */;

           myretcode = mng_readdisplay (myhandle);

           while ((myretcode == MNG_NEEDMOREDATA) ||
                  (myretcode == MNG_NEEDTIMERWAIT)) {
             if (myretcode == MNG_NEEDMOREDATA)
               /* wait for more input-data */;
             else
               /* wait for timer interval */;

             myretcode = mng_display_resume (myhandle);
           }

           if (myretcode != MNG_NOERROR)
             /* process error */;

       More advanced programming methods may require a different approach, but
       the final result should function as in the code above.

   Displaying after reading
       This  method is used to display a file that was previously read.  It is
       primarily meant for viewers with direct file access, such as  1a  local
       harddisk.

       Once you have successfully read the file, all you need to do is:

           myretcode = mng_display (myhandle);

           while (myretcode == MNG_NEEDTIMERWAIT) {
             /* wait for timer interval */;
             myretcode = mng_display_resume (myhandle);
           }

           if (myretcode != MNG_NOERROR)
             /* process error */;

       Again,  more  advanced  programming  methods  may  require  a different
       approach, but the final result should function as in the code above.

   Display manipulation
       Several HLAPI functions are provided to allow a user to manipulate  the
       normal flow of an animation.

       - mng_display_freeze (mng_handle hHandle)

       This will "freeze" the animation in place.

       - mng_display_resume (mng_handle hHandle)

       This function can be used to resume a frozen animation, or to force the
       library to advance the animation to the next frame.

       - mng_display_reset (mng_handle hHandle)

       This function will "reset"  the  animation  into  its  pristine  state.
       Calling mng_display() afterwards will re-display the animation from the
       first frame.

       - mng_display_golayer (mng_handle hHandle,
                               mng_uint32 iLayer)

       - mng_display_goframe (mng_handle hHandle,
                               mng_uint32 iFrame)

       - mng_display_gotime (mng_handle hHandle,
                              mng_uint32 iPlaytime)

       These three functions can be used to "jump" to a specific layer,  frame
       or  timeslot  in  the animation. You must "freeze" the animation before
       using any of these functions.

       All above functions may only be called during a timer interval!  It  is
       the  applications  responsibility to cleanup any resources with respect
       to the timer wait.


VI. Writing

       The main focus of the library lies in its displaying capabilites.   But
       it  does  offer  writing  support  as well.  You can create and write a
       file, or you can write a file you have previously read,  providing  the
       storage of chunks was enabled and active.

       For  this  to  work  you  must  have  compiled  the  library  with  the
       MNG_WRITE_SUPPO1RT and MNG_ACCESS_CHUNKS directives. The  standard  DLL
       and Shared Library have this on by default!

   Setup
       As  always  you must have initialized the library and be the owner of a
       mng_handle. The following callbacks are essential:

           mng_openstream, mng_writedata, mng_closestream

       You can optionally define:

           mng_errorproc, mng_traceproc

       The creation and writing functions will fail if you are in  the  middle
       of reading, creating or writing a file.

   Creating a new file
       To  start  a  new file the library must be in its initial state.  First
       you need to tell the library your intentions:

           myretcode = mng_create (myhandle);
           if (myretcode != MNG_NOERROR)
             /* process error */;

       After that you start adding the appropriate chunks:

           myretcode = mng_put1chunk_mhdr (myhandle, ...);
           if (myretcode != MNG_NOERROR)
             /* process error */;

       And so on, and so forth. Note that the library will automatically  sig-
       nal  the  logical  end  of the file by the ending chunk. Also the first
       chunk will indicate the library the filetype (eg. PNG, JNG or MNG)  and
       force the proper signature when writing the file.

       The code above can be simplified, as you can always get the last error-
       code by using the mng_getlasterror() function:

           if ( (mng_putchunk_xxxx (myhandle, ...)) or
                (mng_putchunk_xxxx (myhandle, ...)) or
                    ...etc...                          )
             /* process error */;

       Please note that you must have a pretty good understanding of the chunk
       specification.  Unlike  the  read  functions,  there  are  virtually no
       checks, so it is quite possible to write completely wrong files.  It is
       a  good  practice to read back your file into the library to verify its
       integrity.

       Once you've got all the chunks added, all you do is:

           myretcode mng_write (myhandle);
           if (myretcode != MNG_NOERROR)
             /* process error */;

       And presto. You're done. The real work is of course carried out in your
       callbacks.  Note that this is a single operation as opposed to the read
       & display  functions  that  may  return  with  MNG_NEEDMOREDATA  and/or
       MNG_NEEDTIMERWAIT.  The  write  function  just  does  the job, and only
       returns after it's finished or  if  it  encounters  some  unrecoverable
       error.

   Writing a previously read file
       If  you  have already successfully read a file, you can use the library
       to write it out as a copy or something.  You  MUST  have  compiled  the
       library  with  the  MNG_STORE_CHUNKS  directive, and you must have done
       mng_set_storechunks (myhandle, MNG_TRUE).

       This doesn't require the MNG_ACCESS_CHUNKS directive, unless  you  want
       to fiddle with the chunks as well.

       Again all you need to do is:

           myretcode mng_write (myhandle);
           if (myretcode != MNG_NOERROR)
             /* process error */;


VII. Modifying/Customizing libmng:

       not finished yet

   Compilation directives
       not finished yet

   Platform dependant modification
       not finished yet


SEE ALSO

       mng(5),jng(5),png(5),libpng(3)

       libmng :

              http://www.libmng.com

       zlib :

              http://www.info-zip.org/pub/infozip/zlib/

       IJG JPEG library :

              http://www.ijg.org

       lcms (little CMS) by Marti Maria Saguer :

              http://www.littlecms.com/

       MNG specification:

              http://www.libpng.org/pub/mng

       In the case of any inconsistency between the MNG specification and this
       library, the specification takes precedence.


AUTHORS

       This man page: Gerard Juyn <gerard at libmng.com>

       The contributing authors would like to thank all those who helped  with
       testing,  bug  fixes,  and  patience.  This wouldn't have been possible
       without all of you!!!


COPYRIGHT NOTICE:

       Copyright (c) 2000-2002 Gerard Juyn

       For the purposes of this copyright and license, "Contributing  Authors"
       is defined as the following set of individuals:

          Gerard Juyn

       The MNG Library is supplied "AS IS".  The Contributing Authors disclaim
       all warranties, expressed or implied,  including,  without  limitation,
       the  warranties of merchantability and of fitness for any purpose.  The
       Contributing Authors assume no liability for direct, indirect, inciden-
       tal,  special,  exemplary,  or  consequential damages, which may result
       from the use of the MNG Library, even if advised of the possibility  of
       such damage.

       Permission  is hereby granted to use, copy, modify, and distribute this
       source code, or portions hereof, for any purpose, without fee,  subject
       to the following restrictions:

       1.  The origin of this source code must not be misrepresented; you must
       not claim that you wrote the original software.

       2. Altered versions must be plainly marked as such and must not be mis-
       represented as being the original source.

       3.  This Copyright notice may not be removed or altered from any source
       or altered source distribution.

       The Contributing Authors specifically permit, without fee, and  encour-
       age  the  use  of this source code as a component to supporting the MNG
       and JNG file format in commercial products.  If  you  use  this  source
       code in a product, acknowledgment would be highly appreciated.


Remarks

       Parts  of  this  software  have  been  adapted from the libpng library.
       Although this library supports all features from the PNG  specification
       (as  MNG  descends from it) it does not require the libpng library.  It
       does require the zlib library and  optionally  the  IJG  JPEG  library,
       and/or the "little-cms" library by Marti Maria Saguer (depending on the
       inclusion of support for JNG and Full-Color-Management respectively.

       This library's function is primarily to read  and  display  MNG  anima-
       tions.  It  is not meant as a full-featured image-editing component! It
       does however offer creation and  editing  functionality  at  the  chunk
       level. (future modifications may include some more support for creation
       and or editing)

                              January 30th, 2005                     LIBMNG(3)

Man(1) output converted with man2html