1LIBMNG(3)                  Library Functions Manual                  LIBMNG(3)
2
3
4

NAME

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

SYNOPSIS

9
10
11       #include <libmng.h>
12
13
14

DESCRIPTION

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

I. Introduction

25       This  file  describes  how  to use and modify the MNG reference library
26       (known as libmng) for your own use.  There are seven sections  to  this
27       file: introduction, callbacks, housekeeping, reading, displaying, writ‐
28       ing, and modification and configuration notes for various special plat‐
29       forms.   We   assume   that   libmng  is  already  installed;  see  the
30       INSTALL.README file for instructions on how to install libmng.
31
32       Libmng was written to support and promote the MNG specification.
33
34       The       MNG-1.0       specification       is       available       at
35       <http://www.libpng.org/pub/mng/spec/>.
36
37       Other  information  about  MNG  can  be  found  at  the  MNG home page,
38       <http://www.libpng.org/pub/mng/>.  The latest version of libmng can  be
39       found at its own homepage at <http://www.libmng.com/>.
40
41       In  most  cases the library will not need to be changed.  For standard‐
42       ization purposes the library contains both a Windows DLL and a makefile
43       for building a shared library (SO). The library is written in C, but an
44       interface for Borland Delphi is also available.
45
46       Libmng has been designed to handle multiple sessions at one time, to be
47       easily  modifiable,  to  be  portable  to the vast majority of machines
48       (ANSI, K&R, 32-, and 64-bit) available, and to be easy to use.
49
50       Libmng uses zlib for its compression and decompression  of  MNG  files.
51       Further  information about zlib, and the latest version of zlib, can be
52       found at the zlib home page, <http://www.zlib.org/>.  The zlib compres‐
53       sion  utility is a general purpose utility that is useful for more than
54       MNG/PNG files, and can be used without libmng.  See  the  documentation
55       delivered with zlib for more details.
56
57       Libmng  optionally  uses the JPEG library by the Independant JPEG Group
58       (IJG). This library is used for the JNG sub-format, which  is  part  of
59       the  MNG  specification,  and  allows for inclusion of JPEG decoded and
60       thus highly  compressed  (photographic)  images.   Further  information
61       about  the  IJG  JPEG  library  and  the latest sources can be found at
62       <http://www.ijg.org/>.
63
64       Libmng can also optionally use the lcms (little CMS) library  by  Marti
65       Maria  Saguer. This library provides an excellent color-management sys‐
66       tem (CMS), which gives libmng the ability to provide full color-correc‐
67       tion  for  images  with  the proper color-information encoded.  Further
68       information and the latest sources can  be  found  at  <http://www.lit
69       tlecms.com/>.
70
71       Libmng is thread safe, provided the threads are using different handles
72       as returned by the initialization call.  Each thread  should  have  its
73       own  handle  and  thus  its  own image.  Libmng does not protect itself
74       against two threads using the same instance of a handle.
75
76       The libmng.h header file is the single reference needed for programming
77       with libmng:
78
79       #include <libmng.h>
80
81
82

II. Callbacks

84       Libmng makes extensive use of callback functions. This is meant to keep
85       the library as platform-independant and flexible  as  possible.   Actu‐
86       ally,  the  first  call  you will make to the library, already contains
87       three parameters you can use to provide callback entry-points.
88
89       Most functions must return a mng_bool  (boolean).  Returning  MNG_FALSE
90       indicates  the  library the callback failed in some way and the library
91       will immediately return from whatever it was doing back to the applica‐
92       tion.  Returning MNG_TRUE indicates there were no problems and process‐
93       ing can continue.
94
95       Let's step through each of the  possible  callbacks.  The  sections  on
96       reading,  displaying  and writing will also explain which callbacks are
97       needed when and where.
98
99       - mng_ptr mng_memalloc (mng_size_t iLen)
100
101       A very basic function which the library uses to allocate a memory-block
102       with the given size. A typical implementation would be:
103
104           mng_ptr my_alloc (mng_size_t iLen) {
105             return calloc (1, iLen);
106           }
107
108       Note that the library requires you to zero-out the memory-block!!!
109
110       - void mng_memfree (mng_ptr    pPtr,
111                           mng_size_t iLen)
112
113       Counterpart of the previous function. Typically:
114
115           void my_free (mng_ptr pPtr, mng_size_t iLen) {
116             free (pPtr);
117           }
118
119       - mng_bool mng_openstream  (mng_handle hHandle)
120
121       - mng_bool mng_closestream (mng_handle hHandle)
122
123       These  are  called  by  the  library  just  before it starts to process
124       (either read or write) a file and  just  after  the  processing  stops.
125       This  is the recommended place to do I/O initialization & finalization.
126       Whether you do or not, is up to you. The library does not put any mean‐
127       ing into the calls. They are simply provided for your convenience.
128
129       - mng_bool mng_readdata (mng_handle  hHandle,
130                                mng_ptr     pBuf,
131                                mng_uint32  iBuflen,
132                                mng_uint32p pRead)
133
134       This  function  is  called when the library needs some more input while
135       reading an image. The reading process supports two  modes:  Suspension-
136       mode  (SMOD)  and non-suspension-mode (NSMOD).  See mng_set_suspension‐
137       mode() for a more detailed description.
138
139       In NSMOD, the library requires you to  return  exactly  the  amount  of
140       bytes requested (= iBuflen). Any lesser amount indicates the input file
141       is exhausted and the library will return a MNG_UNEXPECTEDEOF errorcode.
142
143       In SMOD, you may return a smaller amount of bytes than requested.  This
144       tells  the library it should temporarily wait for more input to arrive.
145       The lib will return with MNG_NEEDMOREDATA, and will expect  a  call  to
146       mng_read_resume()  or mng_display_resume() next, as soon as more input-
147       data has arrived.
148
149       For NSMOD this function could be as simple as:
150
151           mng_bool my_read (mng_handle  hHandle,
152                             mng_ptr     pBuf,
153                             mng_uint32  iBuflen,
154                             mng_uint32p pRead) {
155             *pRead = fread (pBuf, 1, iBuflen, myfile);
156             return MNG_TRUE;
157           }
158
159       - mng_bool mng_writedata (mng_handle  hHandle,
160                                 mng_ptr     pBuf,
161                                 mng_uint32  iBuflen,
162                                 mng_uint32p pWritten)
163
164       This function is called during the  mng_write()  function  to  actually
165       output  data  to the file. There is no suspension-mode during write, so
166       the application must return the  exact  number  of  bytes  the  library
167       requests to be written.
168
169       A typical implementation could be:
170
171           mng_bool my_write (mng_handle  hHandle,
172                              mng_ptr     pBuf,
173                              mng_uint32  iBuflen,
174                              mng_uint32p pWritten) {
175             *pWritten = fwrite (pBuf, 1, iBuflen, myfile);
176             return MNG_TRUE;
177           }
178
179       - mng_bool mng_errorproc (mng_handle  hHandle,
180                                 mng_int32   iErrorcode,
181                                 mng_int8    iSeverity,
182                                 mng_chunkid iChunkname,
183                                 mng_uint32  iChunkseq,
184                                 mng_int32   iExtra1,
185                                 mng_int32   iExtra2,
186                                 mng_pchar   zErrortext)
187
188       This  function  is  called  whenever  an  error  is detected inside the
189       library. This may be caused  by  invalid  input,  callbacks  indicating
190       failure, or wrongfully calling functions out of place.
191
192       If  you  do  not provide this callback the library will still return an
193       errorcode from the called function, and the mng_getlasterror() function
194       can be used to retrieve the other parameters.
195
196       This  function  is  currently only provided for convenience, but may at
197       some point be used to indicate certain errors may  be  acceptable,  and
198       processing should continue.
199
200       - mng_bool mng_traceproc (mng_handle hHandle,
201                                 mng_int32  iFuncnr,
202                                 mng_int32  iFuncseq,
203                                 mng_pchar  zFuncname)
204
205       This  function  is  provided  to  allow  a  functional  analysis of the
206       library. This may be useful if you encounter certain errors and  cannot
207       determine what the problem is.
208
209       Almost  all  functions  inside  the library will activate this callback
210       with an appropriate function-name at the start and end of the function.
211       Please note that large images may generate an enormous amount of calls.
212
213       - mng_bool mng_processheader (mng_handle hHandle,
214                                     mng_uint32 iWidth,
215                                     mng_uint32 iHeight)
216
217       This  function is called once the header information of an input- image
218       has been processed. At this point the image  dimensions  are  available
219       and  also some other properties depending on the type of the image. Eg.
220       for a MNG the  frame-/layercount,  playtime  &  simplicity  fields  are
221       known.
222
223       The  primary  purpose  of this callback is to inform the application of
224       the size of the image, and for the application to initialize the  draw‐
225       ing  canvas to be used by the library. This is also a good point to set
226       the canvas-style. Eg. mng_set_canvasstyle().
227
228       - mng_bool mng_processtext (mng_handle hHandle,
229                                   mng_uint8  iType,
230                                   mng_pchar  zKeyword,
231                                   mng_pchar  zText,
232                                   mng_pchar  zLanguage,
233                                   mng_pchar  zTranslation)
234
235       This callback is activated for each textual chunk in the input-  image.
236       These are tEXt, zTXt & iTXt. It may be used to retain specific comments
237       for presentation to the user.
238
239       - mng_bool mng_processsave (mng_handle hHandle)
240
241       - mng_bool mng_processseek (mng_handle hHandle,
242                                   mng_pchar  zName)
243
244       The purpose of these callbacks is to signal the processing of the  SAVE
245       &  SEEK  chunks  in a MNG input-file. This may be used in the future to
246       specify some special processing. At the moment these functions are only
247       provided as a signal.
248
249       - mng_ptr mng_getcanvasline (mng_handle hHandle,
250                                    mng_uint32 iLinenr)
251
252       - mng_ptr mng_getbkgdline   (mng_handle hHandle,
253                                    mng_uint32 iLinenr)
254
255       - mng_ptr mng_getalphaline  (mng_handle hHandle,
256                                    mng_uint32 iLinenr)
257
258       These  callbacks are used to access the drawing canvas, background can‐
259       vas and an optional separate alpha-channel canvas. The latter  is  used
260       only with the MNG_CANVAS_RGB8_A8 canvas-style.
261
262       If  the getbkgdline() callback is not supplied the library will compos‐
263       ite fully or partially transparent pixels in the image against a speci‐
264       fied  background  color.  See mng_set_bgcolor() for more details.  If a
265       chosen canvas-style includes an alpha-channel, this  callback  is  very
266       likely not needed.
267
268       The  application  is  responsible  for returning a pointer to a line of
269       pixels, which should be in the exact format as defined by the  call  to
270       mng_set_canvasstyle() and mng_set_bkgdstyle(), without gaps between the
271       representation of each pixel, unless specified by the canvas-style.
272
273       - mng_bool mng_refresh (mng_handle hHandle,
274                               mng_uint32 iX,
275                               mng_uint32 iY,
276                               mng_uint32 iWidth,
277                               mng_uint32 iHeight)
278
279       This callback is called when the library has  drawn  a  complete  frame
280       onto the drawing canvas, and it is ready to be displayed.  The applica‐
281       tion is responsible for transferring the  drawing  canvas  from  memory
282       onto the actual output device.
283
284       - mng_uint32 mng_gettickcount (mng_handle hHandle)
285
286       This function should return the number of milliseconds on some internal
287       clock. The entire animation timing depends heavily  on  this  function,
288       and the number returned should be as accurate as possible.
289
290       - mng_bool mng_settimer (mng_handle hHandle,
291                                mng_uint32 iMsecs)
292
293       This  callback  is activated every time the library requires a "pause".
294       Note that the function itself should NOT execute the  wait.  It  should
295       simply  store  the  time-field  and allow the library to return. Libmng
296       will return with the MNG_NEEDTIMERWAIT code,  indicating  the  callback
297       was called and it is now time to execute the pause.
298
299       After  the  indicated number of milliseconds have elapsed, the applica‐
300       tion should call  mng_display_resume(),  to  resume  the  animation  as
301       planned.
302
303       This  method  allows  for both a real timer or a simple wait command in
304       the application. Whichever method you select, both  the  gettickcount()
305       and settimer() callbacks are crucial for proper animation timing.
306
307       - mng_bool mng_processgamma  (mng_handle hHandle,
308                                     mng_uint32 iGamma)
309
310       - mng_bool mng_processchroma (mng_handle hHandle,
311                                     mng_uint32 iWhitepointx,
312                                     mng_uint32 iWhitepointy,
313                                     mng_uint32 iRedx,
314                                     mng_uint32 iRedy,
315                                     mng_uint32 iGreenx,
316                                     mng_uint32 iGreeny,
317                                     mng_uint32 iBluex,
318                                     mng_uint32 iBluey)
319
320       - mng_bool mng_processsrgb   (mng_handle hHandle,
321                                     mng_uint8  iRenderingintent)
322
323       - mng_bool mng_processiccp   (mng_handle hHandle,
324                                     mng_uint32 iProfilesize,
325                                     mng_ptr    pProfile)
326
327       - mng_bool mng_processarow   (mng_handle hHandle,
328                                     mng_uint32 iRowsamples,
329                                     mng_bool   bIsRGBA16,
330                                     mng_ptr    pRow)
331
332       These  callbacks  are  only  required when you selected the MNG_APP_CMS
333       directive during compilation of the library. See the configuration sec‐
334       tion for more details.
335
336       - mng_bool mng_iteratechunk (mng_handle  hHandle,
337                                    mng_handle  hChunk,
338                                    mng_chunkid iChunkid,
339                                    mng_uint32  iChunkseq)
340
341       This  callback  is only used for the mng_iterate_chunks() function.  It
342       is called exactly once for each chunk stored.
343
344
345

III. Housekeeping

347   Memory management
348       The library can use internal memory allocation/deallocation or use pro‐
349       vided callbacks for its memory management. The choice is made at compi‐
350       lation time. See the section on customization for details.
351
352       If internal management has been selected, the memory callback functions
353       need not be supplied. Even if you do supply them they will not be used.
354       The actual code used is similar to the code discussed in  the  callback
355       section:
356
357             pPtr = calloc (1, iLen);
358
359             free (pPtr);
360
361       If your compiler does not support these functions, or you wish to moni‐
362       tor the library's use of memory for certain reasons, you can choose  to
363       compile  the  library with external memory management. In this case the
364       memory callback functions MUST be supplied, and should function  as  if
365       the above code was used.
366
367
368
369   Initialization
370       The basic initialization of the library is short and swift:
371
372           myhandle = mng_initialize (myuserdata, my_alloc,
373                                      my_free, MNG_NULL);
374           if (myhandle == MNG_NULL)
375             /* process error */;
376
377       The  first  field  is  an  application-only  parameter.  It is saved in
378       libmng's internal structures and available at  all  times  through  the
379       mng_get_userdata() function. This is especially handy in callback func‐
380       tions if your program may be handling multiple files at the same time.
381
382       The second and third field supply the library with the memory  callback
383       function  entry-points. These are described in more detail in the call‐
384       back section and the previous paragraph.
385
386       The fourth and last field may be used to supply the  library  with  the
387       entry-point  of a trace callback function. For regular use you will not
388       need this!
389
390       The function returns a handle which will be your ticket to  MNG-heaven.
391       All  other functions rely on this handle. It is the single fixed unique
392       reference-point between your application and the library.
393
394       You should call the initialization function for each image you wish  to
395       process simultaneously. If you are processing images consecutively, you
396       can reset the internal status of the library with the mng_reset() func‐
397       tion.   This function will clear all internal state variables, free any
398       stored chunks and/or objects, etc, etc. Your callbacks and other exter‐
399       nal parameters will be retained.
400
401       After  you  successfully  received  the  handle  it  is time to set the
402       required callbacks. The sections on reading, displaying & writing indi‐
403       cate  which  callbacks are required and which are optional.  To set the
404       callbacks simply do:
405
406           myretcode = mng_setcb_xxxxxx (myhandle, my_xxxxxx);
407           if (myretcode != MNG_NOERROR)
408             /* process error */;
409
410       Naturally you'd replace the x's with the name of the callback.
411
412
413
414   Cleanup
415       Once you've gotten hold of that precious mng_handle, you should always,
416       and  I  mean  always, call the cleanup function when you're done.  Just
417       do:
418
419           mng_cleanup (myhandle);
420
421       And you're done. There shouldn't be an ounce of  memory  spilled  after
422       that call.
423
424       Note that if you would like to process multiple files consecutively you
425       do not need to do mng_cleanup() / mng_initialize()  between  each  file
426       but simply
427
428           myretcode = mng_reset (myhandle);
429           if (myretcode != MNG_NOERROR)
430             /* process error */;
431
432       will suffice. Saves some time and effort, that.
433
434
435
436   Error handling
437       From  the  examples  in  the previous paragraphs you may have noticed a
438       meticulous scheme for error handling. And yes, that's exactly  what  it
439       is.  Practically each call simply returns an errorcode, indicating suc‐
440       cess, eg. MNG_NOERROR or failure, anything  else  but  MNG_NEEDMOREDATA
441       and  MNG_NEEDTIMERWAIT.  These  latter  two  will  be discussed in more
442       detail in their respective fields of interest: the reading section  and
443       displaying section respectively.
444
445       It  is  the  application's responsibility to check the returncode after
446       each call. You can call mng_getlasterror() to receive  the  details  of
447       the last detected error. This even includes a discriptive error-message
448       if you enabled that option during compilation of the library.
449
450       Note that after receiving an error it is still  possible  to  call  the
451       library,  but  it's also very likely that any following call will fail.
452       The  only  functions  deemed  to   work   will   be   mng_reset()   and
453       mng_cleanup().   Yes,  if  you  abort  your program after an error, you
454       should still call mng_cleanup().
455
456
457

IV. Reading

459       Reading a MNG, JNG or PNG is fairly easy. It depends slightly  on  your
460       ultimate  goal  how certain specifics are to be handled, but the basics
461       are similar in all cases.
462
463       For the read functioins to work you must have compiled the library with
464       the MNG_READ_SUPPRT directive. The standard DLL and Shared Library have
465       this on by default!
466
467
468
469   Setup
470       Naturally you must have initialized the library and be the owner  of  a
471       mng_handle. The following callbacks are essential:
472
473           mng_openstream, mng_readdata, mng_closestream
474
475       You may optionally define:
476
477           mng_errorproc, mng_traceproc
478           mng_processheader, mng_processtext
479           mng_processsave, mng_processseek
480
481       The  reading bit will also fail if you are already creating or display‐
482       ing a file. Seems a bit obvious, but I thought I'd mention it, just  in
483       case.
484
485
486
487   To suspend or not to suspend
488       There  is one choice you need to make before calling the read function.
489       Are you in need of suspension-mode or not?
490
491       If you're reading from a disk you most certainly do  not  need  suspen‐
492       sion-mode. Even the oldest and slowest of disks will be fast enough for
493       straight reading.
494
495       However, if your input comes from a  really  slow  device,  such  as  a
496       dialup-line or the likes, you may opt for suspension-mode. This is done
497       by calling
498
499           myretcode = mng_set_suspensionmode (myhandle,
500                                               MNG_TRUE);
501           if (myretcode != MNG_NOERROR)
502             /* process error */;
503
504       Suspension-mode will force the library to use special buffering on  the
505       input.  This  allows  your  application  to receive data of arbitrarily
506       length and return this in the mng_readdata() callback, without disturb‐
507       ing the chunk processing routines of the library.
508
509       Suspension-mode  does  require a little extra care in the main logic of
510       the application. The read function  may  return  with  MNG_NEEDMOREDATA
511       when  the  mng_readdata()  callback  returns less data then it needs to
512       process the next chunk. This indicates the application to wait for more
513       data to arrive and then resume processing by calling mng_read_resume().
514
515
516
517   The read HLAPI
518       The  actual reading is just plain simple. Since all I/O is done outside
519       the library through the callbacks, the library can focus  on  its  real
520       task. Understanding, checking and labelling the input data!
521
522       All you really need to do is this:
523
524           myretcode = mng_read (myhandle);
525           if (myretcode != MNG_NOERROR)
526             /* process error */;
527
528       Of  course, if you're on suspension-mode the code is a little more com‐
529       plicated:
530
531           myretcode = mng_read (myhandle);
532
533           while (myretcode == MNG_NEEDMOREDATA) {
534             /* wait for input-data to arrive */
535             myretcode = mng_read_resume (myhandle);
536           }
537
538           if (myretcode != MNG_NOERROR)
539             /* process error */;
540
541       This is rather crude and more  sophisticated  programming  methods  may
542       dictate  another approach. Whatever method you decide on, it should act
543       as if the above code was in its place.
544
545       There is also the mng_readdisplay() function, but this is discussed  in
546       the  displaying  section.  It  functions  pretty much as the mng_read()
547       function,  but  also   immediately   starts   displaying   the   image.
548       mng_read_resume()  should  be  replaced by mng_display_resume() in that
549       case!
550
551
552
553   What happens inside
554       What actually happens inside the library depends on  the  configuration
555       options set during the compilation of the library.
556
557       Basically the library will first read the 8-byte file header, to deter‐
558       mine its validity and the type of image it is about to process. Then it
559       will  repeatedly  read  a 4-byte chunk-length and then the remainder of
560       the chunk until it either reaches EOF (indicated by the  mng_readdata()
561       callback)  or implicitly decides EOF as it processed the logically last
562       chunk of the image.
563
564       Applications that require strict conformity and do not allow  superflu‐
565       ous  data  after  the  ending chunk, will need to perform this check in
566       their mng_closestream() callback.
567
568       Each chunk is then checked on CRC, after which it is handed over to the
569       appropriate  chunk  processing  routine. These routines will disect the
570       chunk, check the validity of its  contents,  check  its  position  with
571       respect to other chunks, etc, etc.
572
573       If everything checks out, the chunk is further processed as follows:
574
575       If  display  support has been selected during compilation, certain pre-
576       display initialization will take place.
577
578       If chunk-storage support has  been  selected  during  compilation,  the
579       chunks  data may be stored in a special internal structure and held for
580       future reference.
581
582
583
584   Storing and accessing chunks
585       One of the compilation options activates  support  for  chunk  storage.
586       This  option  may be useful if you want to examine an image. The direc‐
587       tive is MNG_STORE_CHUNKS. You must also turn on  the  MNG_ACCESS_CHUNKS
588       directive.
589
590       The  actual  storage  facility  can  be  turned  on  or  off  with  the
591       mng_set_storechunks() function. If set  to  MNG_TRUE,  chunks  will  be
592       stored as they are read.
593
594       At  any  point  you  can then call the mng_iterate_chunks() function to
595       iterate through the current list of chunks. This  function  requires  a
596       callback  which is called for each chunk and receives a specific chunk-
597       handle.  This  chunk-handle  can  be  used  to  call  the   appropriate
598       mng_getchunk_xxxx() function, to access the chunks properties.
599
600       A typical implementation may look like this:
601
602           mng_bool my_iteratechunk (mng_handle  hHandle,
603                                     mng_handle  hChunk,
604                                     mng_chunkid iChunkid,
605                                     mng_uint32  iChunkseq) {
606             switch (iChunkid) {
607               case MNG_UINT_MHDR : { /* process MHDR */;
608                                      break; }
609               case MNG_UINT_FRAM : { /* process FRAM */;
610                                      break; }
611
612                   ...etc...
613
614               case MNG_UINT_HUH  : { /* unknown chunk */;
615                                      break; }
616               default : { /* duh; forgot one */; }
617             }
618
619             return MNG_TRUE; /* keep'm coming */
620           }
621
622       To  get  to  the actual chunk fields of lets say a SHOW chunk you would
623       do:
624
625           mng_bool isempty;
626           mng_uint16 firstid, lastid;
627           mng_uint8 showmode;
628
629           myretcode mng_getchunk_show (hHandle, hChunk,
630                                        isempty, firstid,
631                                        lastid, showmode);
632           if (myretcode != MNG_NOERROR)
633             /* process error */;
634
635
636

V. Displaying

638   Setup
639       Assuming you have initialized the  library  and  are  the  owner  of  a
640       mng_handle. The following callbacks are essential:
641
642           mng_getcanvasline, mng_refresh
643           mng_gettickcount, mng_settimer
644
645       If you wish to use an application supplied background you must supply:
646
647           mng_getbkgdline
648
649       If you wish to use the MNG_CANVAS_RGB8_A8 canvas style you must supply:
650
651           mng_getalphaline
652
653       You may optionally define:
654
655           mng_errorproc, mng_traceproc
656           mng_processheader, mng_processtext
657           mng_processsave, mng_processseek
658
659       Note  that  the  mng_processheader()  callback  is optional but will be
660       quite significant for proper operation!
661
662       Displaying an image will fail if you are creating  a  file  or  already
663       displaying one. Yes, you can't display it twice!
664
665
666
667   A word on canvas styles
668       The  canvas  style  describes  how your drawing canvas is made up.  You
669       must set this before  the  library  actually  starts  drawing,  so  the
670       mng_processheader() callback is a pretty good place for it.
671
672       Currently  only  8-bit  RGB canvas styles are supported, either with or
673       without an alpha channel.
674
675       If you like to do alpha composition yourself you can select one of  the
676       canvas  styles that include an alpha channel. You can even have a sepa‐
677       rate alpha canvas by selecting the MNG_CANVAS_RGB8_A8 style.
678
679       All styles require a compact model. Eg. MNG_CANVAS_BGR8  requires  your
680       canvas  lines  in bgrbgrbgr... storage, where each letter represents an
681       8-bit value of the corresponding color, and each threesome makes up the
682       values of one(1) pixel.
683
684       The  library  processes  a  line  at a time, so the canvas lines do not
685       actually need to be consecutive in memory.
686
687
688
689   Alpha composition and application backgrounds
690       All Network Graphics can be partially transparent. This  requires  spe‐
691       cial  processing  if  you  need  to display an image against some back‐
692       ground. Note that the MNG header (MHDR  chunk)  contains  a  simplicity
693       field indicating whether transparency information in the file is criti‐
694       cal or not. This only applies to embedded images, which means the  full
695       image-frame of the MNG may still contain fully transparent pixels!
696
697       Depending  on  your  needs  you can supply a single background color, a
698       background canvas or tell the library to return the  alpha-channel  and
699       do alpha composition yourself.
700
701       This is different from the BACK chunk in a MNG, or the bKGD chunk in an
702       (embedded) PNG or JNG. The BACK chunk indicates an optional  or  manda‐
703       tory  background  color  and/or image. The bKGD chunk only indicates an
704       optional background color. These chunks indicate  the  Authors  prefer‐
705       ences. They may be absent in which case you need to supply some sort of
706       background yourself.
707
708
709   Composing against a background color
710       This is the easiest method. Call the mng_set_bgcolor() function to  set
711       the values of the red, green and blue component of your preferred back‐
712       ground color.
713
714       Use one of the canvas styles that do not  have  an  alpha-channel,  and
715       which matches your output requirements.
716
717
718   Composing against a background canvas
719       This  is  somewhat  more complicated. You will need to set the mng_get‐
720       bkgdline() callback. This will be called whenever the library needs  to
721       compose a partially transparent line.
722
723       This  canvas must hold the background against which the image should be
724       composed. Its size must match exactly with  the  image  dimensions  and
725       thus the drawing canvas!
726
727       Use  one  of  the  canvas styles that do not have an alpha-channel, and
728       which matches your output requirements. The canvas style of  the  back‐
729       ground  canvas  may  even differ from the drawing canvas. The library's
730       composing will still function properly.
731
732
733   Composing within the application
734       If you have the option in your application to draw a (partially) trans‐
735       parent canvas to the output device, this option is preferred.
736
737       Select  one  of  the  canvas styles that do have an alpha-channel.  The
738       library will now supply the appropriate alpha information, allowing the
739       application to compose the image as it sees fit.
740
741
742
743   Color information and CMS
744       Network Graphics may, and usually will, contain color-correction infor‐
745       mation. This information is intended to compensate for  the  difference
746       in recording and display devices used.
747
748       This  document does not address the specifics of color-management.  See
749       the PNG specification for a more detailed description.
750
751
752   Using little cms by Marti Maria Saguer
753       This is the easiest method, providing you can compile the lcms package.
754       Select  the MNG_FULL_CMS directive during compilation, and sit back and
755       relax. The library will take care of all color-correction for you.
756
757
758   Using an OS- or application-supplied CMS
759       If you are so lucky to have access to  CMS  functionality  from  within
760       your  application,  you may instruct the library to leave color-correc‐
761       tion to you.
762
763       Select the MNG_APP_CMS directive during  compilation  of  the  library.
764       You MUST also set the following callbacks:
765
766           mng_processgamma, mng_processchroma,
767           mng_processsrgb, mng_processiccp and
768           mng_processarow
769
770       The  last  callback  is called when the library needs you to correct an
771       arbitrary line of pixels. The other callbacks are called when the  cor‐
772       responding  color-information  is  encountered  in  the file.  You must
773       store this information somewhere for use in the mng_processarow() call‐
774       back.
775
776
777   Using gamma-only correction
778       This  isn't  a  preferred method, but it's better than no correction at
779       all. Gamma-only correction will at least compensate  for  gamma-differ‐
780       ences between the original recorder and your output device.
781
782       Select  the MNG_GAMMA_ONLY directive during compilation of the library.
783       Your compiler MUST support fp operations.
784
785
786   No color correction
787       Ouch. This is really bad. This is the least preferred method,  but  may
788       be  necessary if your system cannot use lcms, doesn't have its own CMS,
789       and does not allow fp operations, ruling out the gamma-only option.
790
791       Select the MNG_NO_CMS directive during compilation.  Images will  defi‐
792       nitely not be displayed as seen by the Author!!!
793
794
795
796   Animations and timing
797       Animations  require  some form of timing support. The library relies on
798       two callbacks for this purpose.  The  mng_gettickcount()  and  mng_set‐
799       timer()  callbacks. mng_gettickcount() is used to determine the passing
800       of time in milliseconds since the beginning of the animation.  This  is
801       also  used  to  compensate  during suspension-mode if you are using the
802       mng_readdisplay() function to read & display the file simultaneously.
803
804       The callback may return an arbitrary number of milliseconds,  but  this
805       number  must  increase proportionaly between calls. Most modern systems
806       will have some tickcount() function which derives  its  input  from  an
807       internal clock. The value returned from this function is more than ade‐
808       quate for libmng.
809
810       The mng_settimer() callback is called when  the  library  determines  a
811       little "pause" is required before rendering another frame of the anima‐
812       tion. The pause interval  is  also  expressed  in  milliseconds.   Your
813       application  should  store  this  value  and  return  immediately.  The
814       library will then make appropriate arrangements to store  its  internal
815       state and returns to your application with the MNG_NEEDTIMERWAIT code.
816
817       At  that  point you should suspend processing and wait the given inter‐
818       val. Please use your OS features for this. Do not engage some  sort  of
819       loop.  That  is real bad programming practice. Most modern systems will
820       have some timing functions. A simple wait() function may  suffice,  but
821       this may prevent your applications main-task from running, and possibly
822       prevent the actual update of your output device.
823
824
825
826   The mng_refresh() callback
827       The mng_refresh() callback is called whenever  the  library  has  "fin‐
828       ished"  drawing  a  new frame onto your canvas, and just before it will
829       call the mng_settimer() callback.
830
831       This allows you to perform some actions necessary to "refresh" the can‐
832       vas  onto  your  output device. Please do NOT suspend processing inside
833       this callback. This must be handled after the mng_settimer() callback!
834
835
836
837   Displaying while reading
838       This method is preferred if you are reading from a  slow  input  device
839       (such  as  a dialup-line) and you wish to start displaying something as
840       quickly as possible. This functionality is provided mainly for browser-
841       type  applications  but  may  be  appropriate for other applications as
842       well.
843
844       The method is usually used in unison with the  suspension-mode  of  the
845       read module. A typical implementation would look like this:
846
847           /* initiale library and set required callbacks */
848
849           /* activate suspension-mode */
850           myretcode = mng_set_suspensionmode (myhandle,
851                                               MNG_TRUE);
852           if (myretcode != MNG_NOERROR)
853             /* process error */;
854
855           myretcode = mng_readdisplay (myhandle);
856
857           while ((myretcode == MNG_NEEDMOREDATA) ||
858                  (myretcode == MNG_NEEDTIMERWAIT)) {
859             if (myretcode == MNG_NEEDMOREDATA)
860               /* wait for more input-data */;
861             else
862               /* wait for timer interval */;
863
864             myretcode = mng_display_resume (myhandle);
865           }
866
867           if (myretcode != MNG_NOERROR)
868             /* process error */;
869
870       More advanced programming methods may require a different approach, but
871       the final result should function as in the code above.
872
873
874
875   Displaying after reading
876       This method is used to display a file that was previously read.  It  is
877       primarily  meant  for viewers with direct file access, such as 1a local
878       harddisk.
879
880       Once you have successfully read the file, all you need to do is:
881
882           myretcode = mng_display (myhandle);
883
884           while (myretcode == MNG_NEEDTIMERWAIT) {
885             /* wait for timer interval */;
886             myretcode = mng_display_resume (myhandle);
887           }
888
889           if (myretcode != MNG_NOERROR)
890             /* process error */;
891
892       Again, more  advanced  programming  methods  may  require  a  different
893       approach, but the final result should function as in the code above.
894
895
896
897   Display manipulation
898       Several  HLAPI functions are provided to allow a user to manipulate the
899       normal flow of an animation.
900
901       - mng_display_freeze (mng_handle hHandle)
902
903       This will "freeze" the animation in place.
904
905       - mng_display_resume (mng_handle hHandle)
906
907       This function can be used to resume a frozen animation, or to force the
908       library to advance the animation to the next frame.
909
910       - mng_display_reset (mng_handle hHandle)
911
912       This  function  will  "reset"  the  animation  into its pristine state.
913       Calling mng_display() afterwards will re-display the animation from the
914       first frame.
915
916       - mng_display_golayer (mng_handle hHandle,
917                               mng_uint32 iLayer)
918
919       - mng_display_goframe (mng_handle hHandle,
920                               mng_uint32 iFrame)
921
922       - mng_display_gotime (mng_handle hHandle,
923                              mng_uint32 iPlaytime)
924
925       These  three functions can be used to "jump" to a specific layer, frame
926       or timeslot in the animation. You must "freeze"  the  animation  before
927       using any of these functions.
928
929       All  above functions may only be called during a timer interval!  It is
930       the applications responsibility to cleanup any resources  with  respect
931       to the timer wait.
932
933
934

VI. Writing

936       The  main focus of the library lies in its displaying capabilites.  But
937       it does offer writing support as well.  You  can  create  and  write  a
938       file,  or  you can write a file you have previously read, providing the
939       storage of chunks was enabled and active.
940
941       For  this  to  work  you  must  have  compiled  the  library  with  the
942       MNG_WRITE_SUPPO1RT  and  MNG_ACCESS_CHUNKS directives. The standard DLL
943       and Shared Library have this on by default!
944
945
946
947   Setup
948       As always you must have initialized the library and be the owner  of  a
949       mng_handle. The following callbacks are essential:
950
951           mng_openstream, mng_writedata, mng_closestream
952
953       You can optionally define:
954
955           mng_errorproc, mng_traceproc
956
957       The  creation  and writing functions will fail if you are in the middle
958       of reading, creating or writing a file.
959
960
961
962   Creating a new file
963       To start a new file the library must be in its  initial  state.   First
964       you need to tell the library your intentions:
965
966           myretcode = mng_create (myhandle);
967           if (myretcode != MNG_NOERROR)
968             /* process error */;
969
970       After that you start adding the appropriate chunks:
971
972           myretcode = mng_put1chunk_mhdr (myhandle, ...);
973           if (myretcode != MNG_NOERROR)
974             /* process error */;
975
976       And  so on, and so forth. Note that the library will automatically sig‐
977       nal the logical end of the file by the ending  chunk.  Also  the  first
978       chunk  will indicate the library the filetype (eg. PNG, JNG or MNG) and
979       force the proper signature when writing the file.
980
981       The code above can be simplified, as you can always get the last error‐
982       code by using the mng_getlasterror() function:
983
984           if ( (mng_putchunk_xxxx (myhandle, ...)) or
985                (mng_putchunk_xxxx (myhandle, ...)) or
986                    ...etc...                          )
987             /* process error */;
988
989       Please note that you must have a pretty good understanding of the chunk
990       specification. Unlike  the  read  functions,  there  are  virtually  no
991       checks, so it is quite possible to write completely wrong files.  It is
992       a good practice to read back your file into the library to  verify  its
993       integrity.
994
995       Once you've got all the chunks added, all you do is:
996
997           myretcode mng_write (myhandle);
998           if (myretcode != MNG_NOERROR)
999             /* process error */;
1000
1001       And presto. You're done. The real work is of course carried out in your
1002       callbacks. Note that this is a single operation as opposed to the  read
1003       &  display  functions  that  may  return  with  MNG_NEEDMOREDATA and/or
1004       MNG_NEEDTIMERWAIT. The write function  just  does  the  job,  and  only
1005       returns  after  it's  finished  or  if it encounters some unrecoverable
1006       error.
1007
1008
1009
1010   Writing a previously read file
1011       If you have already successfully read a file, you can use  the  library
1012       to  write  it  out  as  a copy or something. You MUST have compiled the
1013       library with the MNG_STORE_CHUNKS directive, and  you  must  have  done
1014       mng_set_storechunks (myhandle, MNG_TRUE).
1015
1016       This  doesn't  require the MNG_ACCESS_CHUNKS directive, unless you want
1017       to fiddle with the chunks as well.
1018
1019       Again all you need to do is:
1020
1021           myretcode mng_write (myhandle);
1022           if (myretcode != MNG_NOERROR)
1023             /* process error */;
1024
1025
1026

VII. Modifying/Customizing libmng:

1028       not finished yet
1029
1030
1031   Compilation directives
1032       not finished yet
1033
1034
1035   Platform dependant modification
1036       not finished yet
1037
1038

SEE ALSO

1040       mng(5),jng(5),png(5),libpng(3)
1041
1042
1043       libmng :
1044
1045              http://www.libmng.com
1046
1047
1048       zlib :
1049
1050              http://www.info-zip.org/pub/infozip/zlib/
1051
1052
1053       IJG JPEG library :
1054
1055              http://www.ijg.org
1056
1057
1058       lcms (little CMS) by Marti Maria Saguer :
1059
1060              http://www.littlecms.com/
1061
1062
1063       MNG specification:
1064
1065              http://www.libpng.org/pub/mng
1066
1067
1068       In the case of any inconsistency between the MNG specification and this
1069       library, the specification takes precedence.
1070
1071
1072

AUTHORS

1074       This man page: Gerard Juyn <gerard at libmng.com>
1075
1076       The  contributing authors would like to thank all those who helped with
1077       testing, bug fixes, and patience.  This  wouldn't  have  been  possible
1078       without all of you!!!
1079
1080
1081
1083       Copyright (c) 2000-2002 Gerard Juyn
1084
1085       For  the purposes of this copyright and license, "Contributing Authors"
1086       is defined as the following set of individuals:
1087
1088          Gerard Juyn
1089
1090       The MNG Library is supplied "AS IS".  The Contributing Authors disclaim
1091       all  warranties,  expressed  or implied, including, without limitation,
1092       the warranties of merchantability and of fitness for any purpose.   The
1093       Contributing Authors assume no liability for direct, indirect, inciden‐
1094       tal, special, exemplary, or consequential  damages,  which  may  result
1095       from  the use of the MNG Library, even if advised of the possibility of
1096       such damage.
1097
1098       Permission is hereby granted to use, copy, modify, and distribute  this
1099       source  code, or portions hereof, for any purpose, without fee, subject
1100       to the following restrictions:
1101
1102       1. The origin of this source code must not be misrepresented; you  must
1103       not claim that you wrote the original software.
1104
1105       2. Altered versions must be plainly marked as such and must not be mis‐
1106       represented as being the original source.
1107
1108       3. This Copyright notice may not be removed or altered from any  source
1109       or altered source distribution.
1110
1111       The  Contributing Authors specifically permit, without fee, and encour‐
1112       age the use of this source code as a component to  supporting  the  MNG
1113       and  JNG  file  format  in commercial products.  If you use this source
1114       code in a product, acknowledgment would be highly appreciated.
1115
1116

Remarks

1118       Parts of this software have  been  adapted  from  the  libpng  library.
1119       Although  this library supports all features from the PNG specification
1120       (as MNG descends from it) it does not require the libpng  library.   It
1121       does  require  the  zlib  library  and optionally the IJG JPEG library,
1122       and/or the "little-cms" library by Marti Maria Saguer (depending on the
1123       inclusion of support for JNG and Full-Color-Management respectively.
1124
1125       This  library's  function  is  primarily to read and display MNG anima‐
1126       tions. It is not meant as a full-featured image-editing  component!  It
1127       does  however  offer  creation  and  editing functionality at the chunk
1128       level. (future modifications may include some more support for creation
1129       and or editing)
1130
1131
1132
1133
1134                              January 30th, 2005                     LIBMNG(3)
Impressum