Skip site navigation (1)Skip section navigation (2)

  
 
  

home | help
LIBMNG(3)		    Library Functions Manual		       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 im-
     age files. It uses the zlib(3) compression library, and optionally the JPEG
     library by the Independant JPEG Group (IJG) and/or  lcms  (little	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: intro-
     duction, callbacks, housekeeping, reading, displaying, writing, and modifi-
     cation and configuration notes for various  special  platforms.  We  assume
     that  libmng is already installed; see the INSTALL.README file for instruc-
     tions 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 standardization
     purposes  the library contains both a Windows DLL and a makefile for build-
     ing 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.  Fur-
     ther information about zlib, and the latest version of zlib, can  be  found
     at  the zlib home page, <http://www.zlib.org/>.  The zlib compression util-
     ity 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 system (CMS),
     which gives libmng the ability to provide full color-correction for  images
     with  the	proper	color-information  encoded.  Further information and the
     latest sources can be found at <http://www.littlecms.com/>.

     Libmng is thread safe, provided the threads are using different handles  as
     returned  by the initialization call.  Each thread should have its own han-
     dle 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.   Actually,  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  indi-
     cates  the library the callback failed in some way and the library will im-
     mediately return from whatever it was doing back to  the  application.  Re-
     turning  MNG_TRUE	indicates there were no problems and processing can con-
     tinue.

     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 meaning 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  read-
     ing  an  image.  The  reading  process  supports two modes: Suspension-mode
     (SMOD) and non-suspension-mode (NSMOD).  See mng_set_suspensionmode() 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 ex-
     hausted 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 applica-
     tion must return the exact number of bytes the library requests to be writ-
     ten.

     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 error-
     code  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 drawing 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 canvas
     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  composite
     fully  or	partially  transparent	pixels	in the image against a specified
     background color. See mng_set_bgcolor() for more details.	If a chosen can-
     vas-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_can-
     vasstyle() 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 application 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 application
     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 set-
     timer() 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  direc-
     tive  during  compilation of the library. See the configuration section 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 provided
     callbacks	for  its  memory  management.  The choice is made at compilation
     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  sec-
     tion:

	   pPtr = calloc (1, iLen);

	   free (pPtr);

     If  your  compiler does not support these functions, or you wish to monitor
     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 call-
     back 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_user-
     data()  function.	This  is  especially handy in callback functions 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 callback
     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  refer-
     ence-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()  function.
     This  function  will  clear  all  internal state variables, free any stored
     chunks and/or objects, etc, etc. Your callbacks and other external  parame-
     ters will be retained.

     After  you  successfully received the handle it is time to set the required
     callbacks. The sections on reading, displaying  &	writing  indicate  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 sim-
     ply

	 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 meticu-
     lous scheme for error handling. And yes, that's exactly what it is.   Prac-
     tically  each  call  simply  returns  an errorcode, indicating success, eg.
     MNG_NOERROR or failure, anything else but	MNG_NEEDMOREDATA  and  MNG_NEED-
     TIMERWAIT.  These	latter two will be discussed in more detail in their re-
     spective fields of interest: the reading section and displaying section re-
     spectively.

     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  en-
     abled that option during compilation of the library.

     Note  that  after	receiving  an error it is still possible to call the li-
     brary, 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 ulti-
     mate goal how certain specifics are to be handled, but the basics are simi-
     lar 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 displaying  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 suspension-
     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 in-
     put. This allows your application to receive data of arbitrarily length and
     return this in the mng_readdata() callback, without  disturbing  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. Un-
     derstanding, 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  compli-
     cated:

	 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  op-
     tions set during the compilation of the library.

     Basically	the library will first read the 8-byte file header, to determine
     its validity and the type of image it is about to process. Then it will re-
     peatedly read a 4-byte chunk-length and then the remainder of the chunk un-
     til it either reaches EOF (indicated by the mng_readdata() callback) or im-
     plicitly decides EOF as it processed the logically last chunk of the image.

     Applications that require strict conformity and do  not  allow  superfluous
     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 ap-
     propriate 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-dis-
     play 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 ref-
     erence.

   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 directive 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_han-
     dle. 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 dis-
     playing 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  with-
     out an alpha channel.

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

     All styles require a compact model. Eg. MNG_CANVAS_BGR8 requires your  can-
     vas  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  special
     processing  if  you  need to display an image against some background. Note
     that the MNG header (MHDR chunk) contains	a  simplicity  field  indicating
     whether  transparency information in the file is critical 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  back-
     ground  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 mandatory
     background color and/or image. The bKGD chunk only  indicates  an	optional
     background  color.  These chunks indicate the Authors preferences. They may
     be absent in which case you need to supply some sort  of  background  your-
     self.

   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  background
     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 com-
     pose a partially transparent line.

     This canvas must hold the background against which the image should be com-
     posed.  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 background 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) transpar-
     ent 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	informa-
     tion.  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  re-
     lax. 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-correction 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 arbi-
     trary line of pixels. The other callbacks are called when the corresponding
     color-information is encountered in the file.  You must store this informa-
     tion somewhere for use in the mng_processarow() callback.

   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-differences be-
     tween 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 definitely
     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_settimer() call-
     backs.  mng_gettickcount() is used to determine the passing of time in mil-
     liseconds since the beginning of the animation. This is also used	to  com-
     pensate during suspension-mode if you are using the mng_readdisplay() func-
     tion to read & display the file simultaneously.

     The  callback may return an arbitrary number of milliseconds, but this num-
     ber 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  adequate  for
     libmng.

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

     At  that  point  you should suspend processing and wait the given interval.
     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 "finished"
     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 canvas
     onto your output device. Please do NOT suspend processing inside this call-
     back. 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	applica-
     tions 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 pri-
     marily meant for viewers with direct file access, such as	1a  local  hard-
     disk.

     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 nor-
     mal 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 li-
     brary 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 signal
     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  errorcode
     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  prac-
     tice 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_NEED-
     TIMERWAIT. 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 li-
     brary, 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 war-
     ranties of merchantability and of fitness for any purpose.  The  Contribut-
     ing  Authors assume no liability for direct, indirect, incidental, 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  misrep-
     resented 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  encourage
     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 prod-
     uct, 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  de-
     scends  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 animations. It
     is not meant as a full-featured image-editing component!  It  does  however
     offer  creation and editing functionality at the chunk level. (future modi-
     fications may include some more support for creation and or editing)

			       January 30th, 2005		       LIBMNG(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=libmng&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help