source: trunk/src/3rdparty/libmng/doc/libmng.txt@ 497

Last change on this file since 497 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 40.1 KB
Line 
1libmng - Multiple-image Network Graphics (MNG) Reference Library 1.0.9
2
3DESCRIPTION
4The libmng library supports decoding, displaying, encoding, and various
5other manipulations of the Multiple-image Network Graphics (MNG) format
6image files. It uses the zlib compression library, and optionally the
7JPEG library by the Independant JPEG Group (IJG) and/or
8lcms (little cms), a color-management library by Marti Maria Saguer.
9
10
11I. Introduction
12
13This file describes how to use and modify the MNG reference library
14(known as libmng) for your own use. There are seven sections to this
15file: introduction, callbacks, housekeeping, reading, displaying,
16writing, and modification and configuration notes for various special
17platforms. We assume that libmng is already installed; see the
18INSTALL.README file for instructions on how to install libmng.
19
20Libmng was written to support and promote the MNG specification.
21
22The latest MNG specification (currently 1.0) is available at
23 http://www.libpng.org/pub/mng/
24
25Other information about MNG can be found at the MNG home page at
26 http://www.libpng.org/pub/mng/
27
28The latest version of libmng can be found at its own homepage at
29 http://www.libmng.com/
30
31In most cases the library will not need to be changed.
32For standardization purposes the library contains both a Windows DLL
33and a makefile for building a shared library (SO). The library is
34written in C, but an interface for Borland Delphi is also available.
35
36Libmng has been designed to handle multiple sessions at one time,
37to be easily modifiable, to be portable to the vast majority of
38machines (ANSI, K&R, 32-, and 64-bit) available, and to be easy
39to use.
40
41Libmng uses zlib for its compression and decompression of MNG files.
42Further information about zlib, and the latest version of zlib, can be
43found at the zlib home page, <http://www.zlib.org/>.
44The zlib compression utility is a general purpose utility that is
45useful for more than MNG/PNG files, and can be used without libmng.
46See the documentation delivered with zlib for more details.
47
48Libmng optionally uses the JPEG library by the Independant JPEG Group
49(IJG). This library is used for the JNG sub-format, which is part of
50the MNG specification, and allows for inclusion of JPEG decoded and
51thus highly compressed (photographic) images.
52Further information about the IJG JPEG library and the latest sources
53can be found at <http://www.ijg.org/>.
54
55Libmng can also optionally use the lcms (little CMS) library by
56Marti Maria Saguer. This library provides an excellent color-management
57system (CMS), which gives libmng the ability to provide full
58color-correction for images with the proper color-information encoded.
59Further information and the latest sources can be found at
60<http://www.littlecms.com/>.
61
62Libmng is thread safe, provided the threads are using different
63handles as returned by the initialization call.
64Each thread should have its own handle and thus its own image.
65Libmng does not protect itself against two threads using the
66same instance of a handle.
67
68The libmng.h header file is the single reference needed for programming
69with libmng:
70
71#include <libmng.h>
72
73
74II. Callbacks
75
76Libmng makes extensive use of callback functions. This is meant to
77keep the library as platform-independant and flexible as possible.
78Actually, the first call you will make to the library, already contains
79three parameters you can use to provide callback entry-points.
80
81Most functions must return a mng_bool (boolean). Returning MNG_FALSE
82indicates the library the callback failed in some way and the library
83will immediately return from whatever it was doing back to the
84application. Returning MNG_TRUE indicates there were no problems and
85processing can continue.
86
87Let's step through each of the possible callbacks. The sections on
88reading, displaying and writing will also explain which callbacks are
89needed when and where.
90
91- mng_ptr mng_memalloc (mng_size_t iLen)
92
93A very basic function which the library uses to allocate a memory-block
94with the given size. A typical implementation would be:
95
96 mng_ptr my_alloc (mng_size_t iLen) {
97 return calloc (1, iSize);
98 }
99
100Note that the library requires you to zero-out the memory-block!!!
101
102- void mng_memfree (mng_ptr pPtr,
103 mng_size_t iLen)
104
105Counterpart of the previous function. Typically:
106
107 void my_free (mng_ptr pPtr, mng_size_t iLen) {
108 free (pPtr);
109 }
110
111- mng_bool mng_openstream (mng_handle hHandle)
112- mng_bool mng_closestream (mng_handle hHandle)
113
114These are called by the library just before it starts to process
115(either read or write) a file and just after the processing stops.
116This is the recommended place to do I/O initialization & finalization.
117Whether you do or not, is up to you. The library does not put any
118meaning into the calls. They are simply provided for your convenience.
119
120- mng_bool mng_readdata (mng_handle hHandle,
121 mng_ptr pBuf,
122 mng_uint32 iBuflen,
123 mng_uint32p pRead)
124
125This function is called when the library needs some more input while
126reading an image. The reading process supports two modes:
127Suspension-mode (SMOD) and non-suspension-mode (NSMOD).
128See mng_set_suspensionmode() for a more detailed description.
129
130In NSMOD, the library requires you to return exactly the amount of bytes
131requested (= iBuflen). Any lesser amount indicates the input file
132is exhausted and the library will return a MNG_UNEXPECTEDEOF errorcode.
133
134In SMOD, you may return a smaller amount of bytes than requested.
135This tells the library it should temporarily wait for more input to
136arrive. The lib will return with MNG_NEEDMOREDATA, and will expect a
137call to mng_read_resume() or mng_display_resume() next, as soon as
138more input-data has arrived.
139
140For NSMOD this function could be as simple as:
141
142 mng_bool my_read (mng_handle hHandle,
143 mng_ptr pBuf,
144 mng_uint32 iBuflen,
145 mng_uint32p pRead) {
146 *pRead = fread (pBuf, 1, iBuflen, myfile);
147 return MNG_TRUE;
148 }
149
150- mng_bool mng_writedata (mng_handle hHandle,
151 mng_ptr pBuf,
152 mng_uint32 iBuflen,
153 mng_uint32p pWritten)
154
155This function is called during the mng_write() function to actually
156output data to the file. There is no suspension-mode during write,
157so the application must return the exact number of bytes the library
158requests to be written.
159
160A typical implementation could be:
161
162 mng_bool my_write (mng_handle hHandle,
163 mng_ptr pBuf,
164 mng_uint32 iBuflen,
165 mng_uint32p pWritten) {
166 *pWritten = fwrite (pBuf, 1, iBuflen, myfile);
167 return MNG_TRUE;
168 }
169
170- mng_bool mng_errorproc (mng_handle hHandle,
171 mng_int32 iErrorcode,
172 mng_int8 iSeverity,
173 mng_chunkid iChunkname,
174 mng_uint32 iChunkseq,
175 mng_int32 iExtra1,
176 mng_int32 iExtra2,
177 mng_pchar zErrortext)
178
179This function is called whenever an error is detected inside the
180library. This may be caused by invalid input, callbacks indicating
181failure, or wrongfully calling functions out of place.
182
183If you do not provide this callback the library will still return
184an errorcode from the called function, and the mng_getlasterror()
185function can be used to retrieve the other parameters.
186
187This function is currently only provided for convenience, but may
188at some point be used to indicate certain errors may be acceptable,
189and processing should continue.
190
191- mng_bool mng_traceproc (mng_handle hHandle,
192 mng_int32 iFuncnr,
193 mng_int32 iFuncseq,
194 mng_pchar zFuncname)
195
196This function is provided to allow a functional analysis of the
197library. This may be useful if you encounter certain errors and
198cannot determine what the problem is.
199
200Almost all functions inside the library will activate this
201callback with an appropriate function-name at the start and end
202of the function. Please note that large images may generate an
203enormous amount of calls.
204
205- mng_bool mng_processheader (mng_handle hHandle,
206 mng_uint32 iWidth,
207 mng_uint32 iHeight)
208
209This function is called once the header information of an input-
210image has been processed. At this point the image dimensions are
211available and also some other properties depending on the type
212of the image. Eg. for a MNG the frame-/layercount, playtime &
213simplicity fields are known.
214
215The primary purpose of this callback is to inform the application
216of the size of the image, and for the application to initialize
217the drawing canvas to be used by the library. This is also a good
218point to set the canvas-style. Eg. mng_set_canvasstyle().
219
220- mng_bool mng_processtext (mng_handle hHandle,
221 mng_uint8 iType,
222 mng_pchar zKeyword,
223 mng_pchar zText,
224 mng_pchar zLanguage,
225 mng_pchar zTranslation)
226
227This callback is activated for each textual chunk in the input-
228image. These are tEXt, zTXt & iTXt. It may be used to retain
229specific comments for presentation to the user.
230
231- mng_bool mng_processsave (mng_handle hHandle)
232- mng_bool mng_processseek (mng_handle hHandle,
233 mng_pchar zName)
234
235The purpose of these callbacks is to signal the processing of the
236SAVE & SEEK chunks in a MNG input-file. This may be used in the
237future to specify some special processing. At the moment these
238functions are only provided as a signal.
239
240- mng_ptr mng_getcanvasline (mng_handle hHandle,
241 mng_uint32 iLinenr)
242- mng_ptr mng_getbkgdline (mng_handle hHandle,
243 mng_uint32 iLinenr)
244- mng_ptr mng_getalphaline (mng_handle hHandle,
245 mng_uint32 iLinenr)
246
247These callbacks are used to access the drawing canvas, background
248canvas and an optional separate alpha-channel canvas. The latter is
249used only with the MNG_CANVAS_RGB8_A8 canvas-style.
250
251If the getbkgdline() callback is not supplied the library will
252composite full or partially transparent pixels in the image against
253a specified background color. See mng_set_bgcolor() for more details.
254If a chosen canvas-style includes an alpha-channel, this callback
255is very likely not needed.
256
257The application is responsible for returning a pointer to a line of
258pixels, which should be in the exact format as defined by the call
259to mng_set_canvasstyle() and mng_set_bkgdstyle(), without gaps between
260the representation of each pixel.
261
262- mng_bool mng_refresh (mng_handle hHandle,
263 mng_uint32 iX,
264 mng_uint32 iY,
265 mng_uint32 iWidth,
266 mng_uint32 iHeight)
267
268This callback is called when the library has drawn a complete frame
269onto the drawing canvas, and it is ready to be displayed.
270The application is responsible for transferring the drawing canvas
271from memory onto the actual output device.
272
273- mng_uint32 mng_gettickcount (mng_handle hHandle)
274
275This function should return the number of milliseconds on some internal
276clock. The entire animation timing depends heavily on this function,
2771and the number returned should be as accurate as possible.
278
279- mng_bool mng_settimer (mng_handle hHandle,
280 mng_uint32 iMsecs)
281
282This callback is activated every time the library requires a "pause".
283Note that the function itself should NOT execute the wait. It should
284simply store the time-field and allow the library to return. Libmng
285will return with the MNG_NEEDTIMERWAIT code, indicating the callback
286was called and it is now time to execute the pause.
287
288After the indicated number of milliseconds have elapsed, the application
289should call mng_display_resume(), to resume the animation as planned.
290
291This method allows for both a real timer or a simple wait command in the
292application. Whichever method you select, both the gettickcount() and
293settimer() callbacks are crucial for proper animation timing.
294
295- mng_bool mng_processgamma (mng_handle hHandle,
296 mng_uint32 iGamma)
297- mng_bool mng_processchroma (mng_handle hHandle,
298 mng_uint32 iWhitepointx,
299 mng_uint32 iWhitepointy,
300 mng_uint32 iRedx,
301 mng_uint32 iRedy,
302 mng_uint32 iGreenx,
303 mng_uint32 iGreeny,
304 mng_uint32 iBluex,
305 mng_uint32 iBluey)
306- mng_bool mng_processsrgb (mng_handle hHandle,
307 mng_uint8 iRenderingintent)
308- mng_bool mng_processiccp (mng_handle hHandle,
309 mng_uint32 iProfilesize,
310 mng_ptr pProfile)
311- mng_bool mng_processarow (mng_handle hHandle,
312 mng_uint32 iRowsamples,
313 mng_bool bIsRGBA16,
314 mng_ptr pRow)
315
316These callbacks are only required when you selected the MNG_APP_CMS
317directive during compilation of the library. See the configuration
318section for more details.
319
320- mng_bool mng_iteratechunk (mng_handle hHandle,
321 mng_handle hChunk,
322 mng_chunkid iChunkid,
323 mng_uint32 iChunkseq)
324
325This callback is only used for the mng_iterate_chunks() function.
326It is called exactly once for each chunk stored.
327
328
329III. Housekeeping
330
331
332> Memory management
333
334The library can use internal memory allocation/deallocation or use
335provided callbacks for its memory management. The choice is made at
336compilation time. See the section on customization for details.
337
338If internal management has been selected, the memory callback functions
339need not be supplied. Even if you do supply them they will not be used.
340The actual code used is similar to the code discussed in the callback
341section:
342
343 pPtr = calloc (1, iSize);
344
345 free (pPtr);
346
347If your compiler does not support these functions, or you wish to monitor
348the library's use of memory for certain reasons, you can choose to
349compile the library with external memory management. In this case the
350memory callback functions MUST be supplied, and should function as if the
351above code was used.
352
353
354> Initialization
355
356The basic initialization of the library is short and swift:
357
358 myhandle = mng_initialize (myuserdata, my_alloc,
359 my_free, MNG_NULL);
360 if (myhandle == MNG_NULL)
361 /* process error */;
362
363The first field is an application-only parameter. It is saved in
364libmng's internal structures and available at all times through the
365mng_get_userdata() function. This is especially handy in callback functions
366if your program may be handling multiple files at the same time.
367
368The second and third field supply the library with the memory callback
3691function entry-points. These are described in more detail in the callback
370section and the previous paragraph.
371
372The fourth and last field may be used to supply the library with the
373entry-point of a trace callback function. For regular use you will not
374need this!
375
376The function returns a handle which will be your ticket to MNG-heaven.
377All other functions rely on this handle. It is the single fixed unique
378reference-point between your application and the library.
379
380You should call the initialization function for each image you wish to
381process simultaneously. If you are processing images consecutively, you can
382reset the internal status of the library with the mng_reset() function.
383This function will clear all internal state variables, free any stored
384chunks and/or objects, etc, etc. Your callbacks and other external parameters
385will be retained.
386
387After you successfully received the handle it is time to set the required
388callbacks. The sections on reading, displaying & writing indicate which
389callbacks are required and which are optional.
390To set the callbacks simply do:
391
392 myretcode = mng_setcb_xxxxxx (myhandle, my_xxxxxx);
393 if (myretcode != MNG_NOERROR)
394 /* process error */;
395
396Naturally you'd replace the x's with the name of the callback.
397
398
399> Cleanup
400
401Once you've gotten hold of that precious mng_handle, you should always,
402and I mean always, call the cleanup function when you're done.
403Just do:
404
405 mng_cleanup (myhandle);
406
407And you're done. There shouldn't be an ounce of memory spilled after
408that call.
409
410Note that if you would like to process multiple files consecutively
411you do not need to do mng_cleanup() / mng_initialize() between each file
412but simply
413
414 myretcode = mng_reset (myhandle);
415 if (myretcode != MNG_NOERROR)
416 /* process error */;
417
418will suffice. Saves some time and effort, that.
419
420
421> Error handling
422
423From the examples in the previous paragraphs you may have noticed a
424meticulous scheme for error handling. And yes, that's exactly what it is.
425Practically each call simply returns an errorcode, indicating success,
426eg. MNG_NOERROR or failure, anything else but MNG_NEEDMOREDATA and
427MNG_NEEDTIMERWAIT. These latter two will be discussed in more detail in
428their respective fields of interest: the reading section and displaying
429section respectively.
430
431It is the application's responsibility to check the returncode after
432each call. You can call mng_getlasterror() to receive the details of
433the last detected error. This even includes a discriptive error-message
434if you enabled that option during compilation of the library.
435
436Note that after receiving an error it is still possible to call the
437library, but it's also very likely that any following call will fail.
438The only functions deemed to work will be mng_reset() and mng_cleanup().
439Yes, if you abort your program after an error, you should still call
440mng_cleanup().
441
442
443IV. Reading
444
445Reading a MNG, JNG or PNG is fairly easy. It depends slightly on your
446ultimate goal how certain specifics are to be handled, but the basics
447are similar in all cases.
448
449For the read functioins to work you must have compiled the library with
450the MNG_READ_SUPPRT directive. The standard DLL and Shared Library
451have this on by default!
452
453
454> Setup
455
456Naturally you must have initialized the library and be the owner of
457a mng_handle. The following callbacks are essential:
458
459 mng_openstream, mng_readdata, mng_closestream
460
461You may optionally define:
462
463 mng_errorproc, mng_traceproc
464 mng_processheader, mng_processtext
465 mng_processsave, mng_processseek
466
467The reading bit will also fail if you are already creating or
468displaying a file. Seems a bit obvious, but I thought I'd mention it,
469just in case.
470
471
472> To suspend or not to suspend
473
474There is one choice you need to make before calling the read function.
475Are you in need of suspension-mode or not?
476
477If you're reading from a disk you most certainly do not need
478suspension-mode. Even the oldest and slowest of disks will be fast
479enough for straight reading.
480
481However, if your input comes from a really slow device, such as a
482dialup-line or the likes, you may opt for suspension-mode. This is done
483by calling
484
485 myretcode = mng_set_suspensionmode (myhandle,
486 MNG_TRUE);
487 if (myretcode != MNG_NOERROR)
488 /* process error */;
489
490Suspension-mode will force the library to use special buffering on the
491input. This allows your application to receive data of arbitrarily length
492and return this in the mng_readdata() callback, without disturbing the
493chunk processing routines of the library.
494
495Suspension-mode does require a little extra care in the main logic of the
4961application. The read function may return with MNG_NEEDMOREDATA when the
497mng_readdata() callback returns less data then it needs to process the
498next chunk. This indicates the application to wait for more data to arrive
499and then resume processing by calling mng_read_resume().
500
501
502> The read HLAPI
503
504The actual reading is just plain simple. Since all I/O is done
5051outside the library through the callbacks, the library can focus on
506its real task. Understanding, checking and labelling the input data!
507
508All you really need to do is this:
509
510 myretcode = mng_read (myhandle);
511 if (myretcode != MNG_NOERROR)
512 /* process error */;
513
514Of course, if you're on suspension-mode the code is a little more
515complicated:
516
517 myretcode = mng_read (myhandle);
518
519 while (myretcode == MNG_NEEDMOREDATA) {
520 /* wait for input-data to arrive */
521 myretcode = mng_read_resume (myhandle);
522 }
523
524 if (myretcode != MNG_NOERROR)
525 /* process error */;
526
527This is rather crude and more sophisticated programming methods may
528dictate another approach. Whatever method you decide on, it should
529act as if the above code was in its place.
530
531There is also the mng_readdisplay() function, but this is discussed
532in the displaying section. It functions pretty much as the mng_read()
533function, but also immediately starts displaying the image.
534mng_read_resume() should be replaced by mng_display_resume() in that
535case!
536
537
538> What happens inside
539
540What actually happens inside the library depends on the configuration
541options set during the compilation of the library.
542
543Basically the library will first read the 8-byte file header, to determine
544its validity and the type of image it is about to process. Then it will
545repeatedly read a 4-byte chunk-length and then the remainder of the chunk
546until it either reaches EOF (indicated by the mng_readdata() callback) or
547implicitly decides EOF as it processed the logically last chunk of the
548image.
549
550Applications that require strict conformity and do not allow superfluous
551data after the ending chunk, will need to perform this check in their
552mng_closestream() callback.
553
554Each chunk is then checked on CRC, after which it is handed over to the
555appropriate chunk processing routine. These routines will disect the
556chunk, check the validity of its contents, check its position with respect
557to other chunks, etc, etc.
558
559If everything checks out, the chunk is further processed as follows:
560
561If display support has been selected during compilation, certain pre-display
562initialization will take place.
563
564If chunk-storage support has been selected during compilation, the chunks
565data may be stored in a special internal structure and held for future
566reference.
567
568
569> Storing and accessing chunks
570
571One of the compilation options activates support for chunk storage.
572This option may be useful if you want to examine an image. The directive
573is MNG_STORE_CHUNKS. You must also turn on the MNG_ACCESS_CHUNKS
574directive.
575
576The actual storage facility can be turned on or off with the
577mng_set_storechunks() function. If set to MNG_TRUE, chunks will be
578stored as they are read.
579
580At any point you can then call the mng_iterate_chunks() function
581to iterate through the current list of chunks. This function requires
582a callback which is called for each chunk and receives a specific
583chunk-handle. This chunk-handle can be used to call the appropriate
584mng_getchunk_xxxx() function, to access the chunks properties.
585
586A typical implementation may look like this:
587
588 mng_bool my_iteratechunk (mng_handle hHandle,
589 mng_handle hChunk,
590 mng_chunkid iChunkid,
591 mng_uint32 iChunkseq) {
592 switch (iChunkid) {
593 case MNG_UINT_MHDR : { /* process MHDR */;
594 break; }
595 case MNG_UINT_FRAM : { /* process FRAM */;
596 break; }
597
598 ...etc...
599
600 case MNG_UINT_HUH : { /* unknown chunk */;
601 break; }
602 default : { /* duh; forgot one */; }
603 }
604
605 return MNG_TRUE; /* keep'm coming */
606 }
607
608To get to the actual chunk fields of lets say a SHOW chunk you would do:
609
610 mng_bool isempty;
611 mng_uint16 firstid, lastid;
612 mng_uint8 showmode;
613
614 myretcode mng_getchunk_show (hHandle, hChunk,
615 isempty, firstid,
616 lastid, showmode);
617 if (myretcode != MNG_NOERROR)
618 /* process error */;
619
620
621V. Displaying
622
623
624> Setup
625
626Assuming you have initialized the library and are the owner of
627a mng_handle. The following callbacks are essential:
628
629 mng_getcanvasline, mng_refresh
630 mng_gettickcount, mng_settimer
631
632If you wish to use an application supplied background you must supply:
633
634 mng_getbkgdline
635
636If you wish to use the MNG_CANVAS_RGB8_A8 canvas style you must supply:
637
638 mng_getalphaline
639
640You may optionally define:
641
642 mng_errorproc, mng_traceproc
643 mng_processheader, mng_processtext
644 mng_processsave, mng_processseek
645
646Note that the mng_processheader() callback is optional but will
647be quite significant for proper operation!
648
649Displaying an image will fail if you are creating a file or already
650displaying one. Yes, you can't display it twice!
651
652
653> A word on canvas styles
654
655The canvas style describes how your drawing canvas is made up.
656You must set this before the library actually starts drawing, so
657the mng_processheader() callback is a pretty good place for it.
658
659Currently only 8-bit RGB canvas styles are supported, either with
660or without an alpha channel.
661
662If you like to do alpha composition yourself you can select one of
663the canvas styles that include an alpha channel. You can even have
664a separate alpha canvas by selecting the MNG_CANVAS_RGB8_A8 style.
665
666All styles require a compact model. Eg. MNG_CANVAS_BGR8 requires
667your canvas lines in bgrbgrbgr... storage, where each letter
668represents an 8-bit value of the corresponding color, and each
669threesome makes up the values of one(1) pixel.
670
671The library processes a line at a time, so the canvas lines do not
672actually need to be consecutive in memory.
673
674
675> Alpha composition and application backgrounds
676
677All Network Graphics can be partially transparent. This requires
678special processing if you need to display an image against some
679background. Note that the MNG header (MHDR chunk) contains a
680simplicity field indicating whether transparency information in
681the file is critical or not. This only applies to embedded images,
682which means the full image-frame of the MNG may still contain fully
683transparent pixels!
684
685Depending on your needs you can supply a single background color,
686a background canvas or tell the library to return the alpha-channel
687and do alpha composition yourself.
688
689This is different from the BACK chunk in a MNG, or the bKGD chunk
690in an (embedded) PNG or JNG. The BACK chunk indicates an optional or
691mandatory background color and/or image. The bKGD chunk only indicates
692an optional background color. These chunks indicate the Authors
693preferences. They may be absent in which case you need to supply
694some sort of background yourself.
695
696> Composing against a background color
697
698This is the easiest method. Call the mng_set_bgcolor() function to
699set the values of the red, green and blue component of your preferred
700background color.
701
702Use one of the canvas styles that do not have an alpha-channel, and
703which matches your output requirements.
704
705> Composing against a background canvas
706
707This is somewhat more complicated. You will need to set the
708mng_getbkgdline() callback. This will be called whenever the library
709needs to compose a partially transparent line.
710
711This canvas must hold the background against which the image should
712be composed. Its size must match exactly with the image dimensions
713and thus the drawing canvas!
714
715Use one of the canvas styles that do not have an alpha-channel, and
716which matches your output requirements. The canvas style of the
717background canvas may even differ from the drawing canvas. The library's
718composing will still function properly.
719
720> Composing within the application
721
722If you have the option in your application to draw a (partially)
723transparent canvas to the output device, this option is preferred.
724
725Select one of the canvas styles that do have an alpha-channel.
726The library will now supply the appropriate alpha information,
727allowing the application to compose the image as it sees fit.
728
729
730> Color information and CMS
731
732Network Graphics may, and usually will, contain color-correction
733information. This information is intended to compensate for the
734difference in recording and display devices used.
735