1LIBMNG(3) Library Functions Manual LIBMNG(3)
2
3
4
6 libmng - Multiple-image Network Graphics (MNG) Reference Library 1.0.9
7
9
10
11 #include <libmng.h>
12
13
14
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
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
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
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
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
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
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
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
1040 mng(5),[24mjng(5),png(5),[24mlibpng(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
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
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)