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

FreeBSD Manual Pages

  
 
  

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
       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 IN-
       STALL.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 in-
       formation 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  (ei-
       ther  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  re-
       quests 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 li-
       brary. This may be caused by invalid input, callbacks indicating	 fail-
       ure, 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  li-
       brary.  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 di-
       rective	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 re-
       quired 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  de-
       tail  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 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
       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  di-
       alup-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 re-
       spect 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 it-
       erate 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  ac-
       tually 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 li-
       brary  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 in-
       ternal 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  ap-
       plication  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 ap-
       proach, 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 re-
       turns 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 li-
       brary 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.   Al-
       though  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)

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

home | help