.TH LIBMNG 3 "January 30th, 2005".SH NAMElibmng \- Multiple-image Network Graphics (MNG) Reference Library 1.0.9.SH SYNOPSIS\fI\fB\fB#include <libmng.h>\fP.SH DESCRIPTIONThe.I libmnglibrary supports decoding, displaying, encoding, and various othermanipulations of the Multiple-image Network Graphics (MNG) formatimage files. It uses the.IR zlib(3)compression library, and optionally the JPEG library by the IndependantJPEG Group (IJG) and/or lcms (little cms), a color-management libraryby Marti Maria Saguer..SH I. IntroductionThis file describes how to use and modify the MNG reference library(known as libmng) for your own use. There are seven sections to thisfile: introduction, callbacks, housekeeping, reading, displaying,writing, and modification and configuration notes for various specialplatforms. We assume that libmng is already installed; see theINSTALL.README file for instructions on how to install libmng.Libmng was written to support and promote the MNG specification.The MNG-1.0 specification is available at<http://www.libpng.org/pub/mng/spec/>.Other information about MNG can be found at the MNG home page,<http://www.libpng.org/pub/mng/>.The latest version of libmng can be found at its own homepage at<http://www.libmng.com/>.In most cases the library will not need to be changed.For standardization purposes the library contains both a Windows DLLand a makefile for building a shared library (SO). The library iswritten in C, but an interface for Borland Delphi is also available.Libmng has been designed to handle multiple sessions at one time,to be easily modifiable, to be portable to the vast majority ofmachines (ANSI, K&R, 32-, and 64-bit) available, and to be easyto use.Libmng uses zlib for its compression and decompression of MNG files.Further information about zlib, and the latest version of zlib, can befound at the zlib home page, <http://www.zlib.org/>.The zlib compression utility is a general purpose utility that isuseful for more than MNG/PNG files, and can be used without libmng.See the documentation delivered with zlib for more details.Libmng optionally uses the JPEG library by the Independant JPEG Group(IJG). This library is used for the JNG sub-format, which is part ofthe MNG specification, and allows for inclusion of JPEG decoded andthus highly compressed (photographic) images.Further information about the IJG JPEG library and the latest sourcescan be found at <http://www.ijg.org/>.Libmng can also optionally use the lcms (little CMS) library byMarti Maria Saguer. This library provides an excellent color-managementsystem (CMS), which gives libmng the ability to provide fullcolor-correction for images with the proper color-information encoded.Further information and the latest sources can be found at<http://www.littlecms.com/>.Libmng is thread safe, provided the threads are using differenthandles as returned by the initialization call.Each thread should have its own handle and thus its own image.Libmng does not protect itself against two threads using thesame instance of a handle.The libmng.h header file is the single reference needed for programmingwith libmng:#include <libmng.h>.SH II. CallbacksLibmng makes extensive use of callback functions. This is meant tokeep the library as platform-independant and flexible as possible.Actually, the first call you will make to the library, already containsthree parameters you can use to provide callback entry-points.Most functions must return a mng_bool (boolean). Returning MNG_FALSEindicates the library the callback failed in some way and the librarywill immediately return from whatever it was doing back to theapplication. Returning MNG_TRUE indicates there were no problems andprocessing can continue.Let's step through each of the possible callbacks. The sections onreading, displaying and writing will also explain which callbacks areneeded when and where.\- mng_ptr mng_memalloc (mng_size_t iLen)A very basic function which the library uses to allocate a memory-blockwith the given size. A typical implementation would be: mng_ptr my_alloc (mng_size_t iLen) { return calloc (1, iLen); }Note that the library requires you to zero-out the memory-block!!!\- void mng_memfree (mng_ptr pPtr, mng_size_t iLen)Counterpart of the previous function. Typically: void my_free (mng_ptr pPtr, mng_size_t iLen) { free (pPtr); }\- mng_bool mng_openstream (mng_handle hHandle)\- mng_bool mng_closestream (mng_handle hHandle)These are called by the library just before it starts to process(either read or write) a file and just after the processing stops.This is the recommended place to do I/O initialization & finalization.Whether you do or not, is up to you. The library does not put anymeaning into the calls. They are simply provided for your convenience.\- mng_bool mng_readdata (mng_handle hHandle, mng_ptr pBuf, mng_uint32 iBuflen, mng_uint32p pRead)This function is called when the library needs some more input whilereading an image. The reading process supports two modes:Suspension-mode (SMOD) and non-suspension-mode (NSMOD).See mng_set_suspensionmode() for a more detailed description.In NSMOD, the library requires you to return exactly the amount of bytesrequested (= iBuflen). Any lesser amount indicates the input fileis exhausted and the library will return a MNG_UNEXPECTEDEOF errorcode.In SMOD, you may return a smaller amount of bytes than requested.This tells the library it should temporarily wait for more input toarrive. The lib will return with MNG_NEEDMOREDATA, and will expect acall to mng_read_resume() or mng_display_resume() next, as soon asmore input-data has arrived.For NSMOD this function could be as simple as: mng_bool my_read (mng_handle hHandle, mng_ptr pBuf, mng_uint32 iBuflen, mng_uint32p pRead) { *pRead = fread (pBuf, 1, iBuflen, myfile); return MNG_TRUE; }\- mng_bool mng_writedata (mng_handle hHandle, mng_ptr pBuf, mng_uint32 iBuflen, mng_uint32p pWritten)This function is called during the mng_write() function to actuallyoutput data to the file. There is no suspension-mode during write,so the application must return the exact number of bytes the libraryrequests to be written.A typical implementation could be: mng_bool my_write (mng_handle hHandle, mng_ptr pBuf, mng_uint32 iBuflen, mng_uint32p pWritten) { *pWritten = fwrite (pBuf, 1, iBuflen, myfile); return MNG_TRUE; }\- mng_bool mng_errorproc (mng_handle hHandle, mng_int32 iErrorcode, mng_int8 iSeverity, mng_chunkid iChunkname, mng_uint32 iChunkseq, mng_int32 iExtra1, mng_int32 iExtra2, mng_pchar zErrortext)This function is called whenever an error is detected inside thelibrary. This may be caused by invalid input, callbacks indicatingfailure, or wrongfully calling functions out of place.If you do not provide this callback the library will still returnan errorcode from the called function, and the mng_getlasterror()function can be used to retrieve the other parameters.This function is currently only provided for convenience, but mayat some point be used to indicate certain errors may be acceptable,and processing should continue.\- mng_bool mng_traceproc (mng_handle hHandle, mng_int32 iFuncnr, mng_int32 iFuncseq, mng_pchar zFuncname)This function is provided to allow a functional analysis of thelibrary. This may be useful if you encounter certain errors andcannot determine what the problem is.Almost all functions inside the library will activate thiscallback with an appropriate function-name at the start and endof the function. Please note that large images may generate anenormous amount of calls.\- mng_bool mng_processheader (mng_handle hHandle, mng_uint32 iWidth, mng_uint32 iHeight)This function is called once the header information of an input-image has been processed. At this point the image dimensions areavailable and also some other properties depending on the typeof the image. Eg. for a MNG the frame-/layercount, playtime &simplicity fields are known.The primary purpose of this callback is to inform the applicationof the size of the image, and for the application to initializethe drawing canvas to be used by the library. This is also a goodpoint to set the canvas-style. Eg. mng_set_canvasstyle().\- mng_bool mng_processtext (mng_handle hHandle, mng_uint8 iType, mng_pchar zKeyword, mng_pchar zText, mng_pchar zLanguage, mng_pchar zTranslation)This callback is activated for each textual chunk in the input-image. These are tEXt, zTXt & iTXt. It may be used to retainspecific comments for presentation to the user.\- mng_bool mng_processsave (mng_handle hHandle)\- mng_bool mng_processseek (mng_handle hHandle, mng_pchar zName)The purpose of these callbacks is to signal the processing of theSAVE & SEEK chunks in a MNG input-file. This may be used in thefuture to specify some special processing. At the moment thesefunctions are only provided as a signal.\- mng_ptr mng_getcanvasline (mng_handle hHandle, mng_uint32 iLinenr)\- mng_ptr mng_getbkgdline (mng_handle hHandle, mng_uint32 iLinenr)\- mng_ptr mng_getalphaline (mng_handle hHandle, mng_uint32 iLinenr)These callbacks are used to access the drawing canvas, backgroundcanvas and an optional separate alpha-channel canvas. The latter isused only with the MNG_CANVAS_RGB8_A8 canvas-style.If the getbkgdline() callback is not supplied the library willcomposite fully or partially transparent pixels in the image againsta specified background color. See mng_set_bgcolor() for more details.If a chosen canvas-style includes an alpha-channel, this callbackis very likely not needed.The application is responsible for returning a pointer to a line ofpixels, which should be in the exact format as defined by the callto mng_set_canvasstyle() and mng_set_bkgdstyle(), without gaps betweenthe representation of each pixel, unless specified by the canvas-style.\- mng_bool mng_refresh (mng_handle hHandle, mng_uint32 iX, mng_uint32 iY, mng_uint32 iWidth, mng_uint32 iHeight)This callback is called when the library has drawn a complete frameonto the drawing canvas, and it is ready to be displayed.The application is responsible for transferring the drawing canvasfrom memory onto the actual output device.\- mng_uint32 mng_gettickcount (mng_handle hHandle)This function should return the number of milliseconds on some internalclock. The entire animation timing depends heavily on this function,and the number returned should be as accurate as possible.\- mng_bool mng_settimer (mng_handle hHandle, mng_uint32 iMsecs)This callback is activated every time the library requires a "pause".Note that the function itself should NOT execute the wait. It shouldsimply store the time-field and allow the library to return. Libmngwill return with the MNG_NEEDTIMERWAIT code, indicating the callbackwas called and it is now time to execute the pause.After the indicated number of milliseconds have elapsed, the applicationshould call mng_display_resume(), to resume the animation as planned.This method allows for both a real timer or a simple wait command in theapplication. Whichever method you select, both the gettickcount() andsettimer() callbacks are crucial for proper animation timing.\- mng_bool mng_processgamma (mng_handle hHandle, mng_uint32 iGamma)\- mng_bool mng_processchroma (mng_handle hHandle, mng_uint32 iWhitepointx, mng_uint32 iWhitepointy, mng_uint32 iRedx, mng_uint32 iRedy, mng_uint32 iGreenx, mng_uint32 iGreeny, mng_uint32 iBluex, mng_uint32 iBluey)\- mng_bool mng_processsrgb (mng_handle hHandle, mng_uint8 iRenderingintent)\- mng_bool mng_processiccp (mng_handle hHandle, mng_uint32 iProfilesize, mng_ptr pProfile)\- mng_bool mng_processarow (mng_handle hHandle, mng_uint32 iRowsamples, mng_bool bIsRGBA16, mng_ptr pRow)These callbacks are only required when you selected the MNG_APP_CMSdirective during compilation of the library. See the configurationsection for more details.\- mng_bool mng_iteratechunk (mng_handle hHandle, mng_handle hChunk, mng_chunkid iChunkid, mng_uint32 iChunkseq)This callback is only used for the mng_iterate_chunks() function.It is called exactly once for each chunk stored..SH III. Housekeeping.SS Memory managementThe library can use internal memory allocation/deallocation or useprovided callbacks for its memory management. The choice is made atcompilation time. See the section on customization for details.If internal management has been selected, the memory callback functionsneed not be supplied. Even if you do supply them they will not be used.The actual code used is similar to the code discussed in the callbacksection: pPtr = calloc (1, iLen); free (pPtr);If your compiler does not support these functions, or you wish to monitorthe library's use of memory for certain reasons, you can choose tocompile the library with external memory management. In this case thememory callback functions MUST be supplied, and should function as if theabove code was used..SS InitializationThe basic initialization of the library is short and swift: myhandle = mng_initialize (myuserdata, my_alloc, my_free, MNG_NULL); if (myhandle == MNG_NULL) /* process error */;The first field is an application-only parameter. It is saved inlibmng's internal structures and available at all times through themng_get_userdata() function. This is especially handy in callback functionsif your program may be handling multiple files at the same time.The second and third field supply the library with the memory callbackfunction entry-points. These are described in more detail in the callbacksection and the previous paragraph.The fourth and last field may be used to supply the library with theentry-point of a trace callback function. For regular use you will notneed this!The function returns a handle which will be your ticket to MNG-heaven.All other functions rely on this handle. It is the single fixed uniquereference-point between your application and the library.You should call the initialization function for each image you wish toprocess simultaneously. If you are processing images consecutively, you canreset the internal status of the library with the mng_reset() function.This function will clear all internal state variables, free any storedchunks and/or objects, etc, etc. Your callbacks and other external parameterswill be retained.After you successfully received the handle it is time to set the requiredcallbacks. The sections on reading, displaying & writing indicate whichcallbacks are required and which are optional.To set the callbacks simply do: myretcode = mng_setcb_xxxxxx (myhandle, my_xxxxxx); if (myretcode != MNG_NOERROR) /* process error */;Naturally you'd replace the x's with the name of the callback..SS CleanupOnce you've gotten hold of that precious mng_handle, you should always,and I mean always, call the cleanup function when you're done.Just do: mng_cleanup (myhandle);And you're done. There shouldn't be an ounce of memory spilled afterthat call.Note that if you would like to process multiple files consecutivelyyou do not need to do mng_cleanup() / mng_initialize() between each filebut simply myretcode = mng_reset (myhandle); if (myretcode != MNG_NOERROR) /* process error */;will suffice. Saves some time and effort, that..SS Error handlingFrom the examples in the previous paragraphs you may have noticed ameticulous scheme for error handling. And yes, that's exactly what it is.Practically each call simply returns an errorcode, indicating success,eg. MNG_NOERROR or failure, anything else but MNG_NEEDMOREDATA andMNG_NEEDTIMERWAIT. These latter two will be discussed in more detail intheir respective fields of interest: the reading section and displayingsection respectively.It is the application's responsibility to check the returncode aftereach call. You can call mng_getlasterror() to receive the details ofthe last detected error. This even includes a discriptive error-messageif you enabled that option during compilation of the library.Note that after receiving an error it is still possible to call thelibrary, but it's also very likely that any following call will fail.The only functions deemed to work will be mng_reset() and mng_cleanup().Yes, if you abort your program after an error, you should still callmng_cleanup()..SH IV. ReadingReading a MNG, JNG or PNG is fairly easy. It depends slightly on yourultimate goal how certain specifics are to be handled, but the basicsare similar in all cases.For the read functioins to work you must have compiled the library withthe MNG_READ_SUPPRT directive. The standard DLL and Shared Libraryhave this on by default!.SS SetupNaturally you must have initialized the library and be the owner ofa mng_handle. The following callbacks are essential: mng_openstream, mng_readdata, mng_closestreamYou may optionally define: mng_errorproc, mng_traceproc mng_processheader, mng_processtext mng_processsave, mng_processseekThe reading bit will also fail if you are already creating ordisplaying a file. Seems a bit obvious, but I thought I'd mention it,just in case..SS To suspend or not to suspendThere is one choice you need to make before calling the read function.Are you in need of suspension-mode or not?If you're reading from a disk you most certainly do not needsuspension-mode. Even the oldest and slowest of disks will be fastenough for straight reading.However, if your input comes from a really slow device, such as adialup-line or the likes, you may opt for suspension-mode. This is doneby calling myretcode = mng_set_suspensionmode (myhandle, MNG_TRUE); if (myretcode != MNG_NOERROR) /* process error */;Suspension-mode will force the library to use special buffering on theinput. This allows your application to receive data of arbitrarily lengthand return this in the mng_readdata() callback, without disturbing thechunk processing routines of the library.Suspension-mode does require a little extra care in the main logic of theapplication. The read function may return with MNG_NEEDMOREDATA when themng_readdata() callback returns less data then it needs to process thenext chunk. This indicates the application to wait for more data to arriveand then resume processing by calling mng_read_resume()..SS The read HLAPIThe actual reading is just plain simple. Since all I/O is doneoutside the library through the callbacks, the library can focus onits real task. Understanding, checking and labelling the input data!All you really need to do is this: myretcode = mng_read (myhandle); if (myretcode != MNG_NOERROR) /* process error */;Of course, if you're on suspension-mode the code is a little morecomplicated: myretcode = mng_read (myhandle); while (myretcode == MNG_NEEDMOREDATA) { /* wait for input-data to arrive */ myretcode = mng_read_resume (myhandle); } if (myretcode != MNG_NOERROR) /* process error */;This is rather crude and more sophisticated programming methods maydictate another approach. Whatever method you decide on, it shouldact as if the above code was in its place.There is also the mng_readdisplay() function, but this is discussedin the displaying section. It functions pretty much as the mng_read()function, but also immediately starts displaying the image.mng_read_resume() should be replaced by mng_display_resume() in thatcase!.SS What happens insideWhat actually happens inside the library depends on the configurationoptions set during the compilation of the library.Basically the library will first read the 8-byte file header, to determineits validity and the type of image it is about to process. Then it willrepeatedly read a 4-byte chunk-length and then the remainder of the chunkuntil it either reaches EOF (indicated by the mng_readdata() callback) orimplicitly decides EOF as it processed the logically last chunk of theimage.Applications that require strict conformity and do not allow superfluousdata after the ending chunk, will need to perform this check in theirmng_closestream() callback.Each chunk is then checked on CRC, after which it is handed over to theappropriate chunk processing routine. These routines will disect thechunk, check the validity of its contents, check its position with respectto other chunks, etc, etc.If everything checks out, the chunk is further processed as follows:If display support has been selected during compilation, certain pre-displayinitialization will take place.If chunk-storage support has been selected during compilation, the chunksdata may be stored in a special internal structure and held for futurereference..SS Storing and accessing chunksOne of the compilation options activates support for chunk storage.This option may be useful if you want to examine an image. The directiveis MNG_STORE_CHUNKS. You must also turn on the MNG_ACCESS_CHUNKSdirective.The actual storage facility can be turned on or off with themng_set_storechunks() function. If set to MNG_TRUE, chunks will bestored as they are read.At any point you can then call the mng_iterate_chunks() functionto iterate through the current list of chunks. This function requiresa callback which is called for each chunk and receives a specificchunk-handle. This chunk-handle can be used to call the appropriatemng_getchunk_xxxx() function, to access the chunks properties.A typical implementation may look like this: mng_bool my_iteratechunk (mng_handle hHandle, mng_handle hChunk, mng_chunkid iChunkid, mng_uint32 iChunkseq) { switch (iChunkid) { case MNG_UINT_MHDR : { /* process MHDR */; break; } case MNG_UINT_FRAM : { /* process FRAM */; break; } ...etc... case MNG_UINT_HUH : { /* unknown chunk */; break; } default : { /* duh; forgot one */; } } return MNG_TRUE; /* keep'm coming */ }To get to the actual chunk fields of lets say a SHOW chunk you would do: mng_bool isempty; mng_uint16 firstid, lastid; mng_uint8 showmode; myretcode mng_getchunk_show (hHandle, hChunk, isempty, firstid, lastid, showmode); if (myretcode != MNG_NOERROR) /* process error */;.SH V. Displaying.SS SetupAssuming you have initialized the library and are the owner ofa mng_handle. The following callbacks are essential: mng_getcanvasline, mng_refresh mng_gettickcount, mng_settimerIf you wish to use an application supplied background you must supply: mng_getbkgdlineIf you wish to use the MNG_CANVAS_RGB8_A8 canvas style you must supply: mng_getalphalineYou may optionally define: mng_errorproc, mng_traceproc mng_processheader, mng_processtext mng_processsave, mng_processseekNote that the mng_processheader() callback is optional but willbe quite significant for proper operation!Displaying an image will fail if you are creating a file or alreadydisplaying one. Yes, you can't display it twice!.SS A word on canvas stylesThe canvas style describes how your drawing canvas is made up.You must set this before the library actually starts drawing, sothe mng_processheader() callback is a pretty good place for it.Currently only 8-bit RGB canvas styles are supported, either withor without an alpha channel.If you like to do alpha composition yourself you can select one ofthe canvas styles that include an alpha channel. You can even havea separate alpha canvas by selecting the MNG_CANVAS_RGB8_A8 style.All styles require a compact model. Eg. MNG_CANVAS_BGR8 requiresyour canvas lines in bgrbgrbgr... storage, where each letterrepresents an 8-bit value of the corresponding color, and eachthreesome makes up the values of one(1) pixel.The library processes a line at a time, so the canvas lines do notactually need to be consecutive in memory..SS Alpha composition and application backgroundsAll Network Graphics can be partially transparent. This requiresspecial processing if you need to display an image against somebackground. Note that the MNG header (MHDR chunk) contains asimplicity field indicating whether transparency information inthe file is critical or not. This only applies to embedded images,which means the full image-frame of the MNG may still contain fullytransparent pixels!Depending on your needs you can supply a single background color,a background canvas or tell the library to return the alpha-channeland do alpha composition yourself.This is different from the BACK chunk in a MNG, or the bKGD chunkin an (embedded) PNG or JNG. The BACK chunk indicates an optional ormandatory background color and/or image. The bKGD chunk only indicatesan optional background color. These chunks indicate the Authorspreferences. They may be absent in which case you need to supplysome sort of background yourself..SS Composing against a background colorThis is the easiest method. Call the mng_set_bgcolor() function toset the values of the red, green and blue component of your preferredbackground color.Use one of the canvas styles that do not have an alpha-channel, andwhich matches your output requirements..SS Composing against a background canvasThis is somewhat more complicated. You will need to set themng_getbkgdline() callback. This will be called whenever the libraryneeds to compose a partially transparent line.This canvas must hold the background against which the image shouldbe composed. Its size must match exactly with the image dimensionsand thus the drawing canvas!Use one of the canvas styles that do not have an alpha-channel, andwhich matches your output requirements. The canvas style of thebackground canvas may even differ from the drawing canvas. The library'scomposing will still function properly..SS Composing within the applicationIf you have the option in your application to draw a (partially)transparent canvas to the output device, this option is preferred.Select one of the canvas styles that do have an alpha-channel.The library will now supply the appropriate alpha information,allowing the application to compose the image as it sees fit..SS Color information and CMSNetwork Graphics may, and usually will, contain color-correctioninformation. This information is intended to compensate for thedifference in recording and display devices used.This document does not address the specifics of color-management.See the PNG specification for a more detailed description..SS Using little cms by Marti Maria SaguerThis is the easiest method, providing you can compile the lcms package.Select the MNG_FULL_CMS directive during compilation, and sit back andrelax. The library will take care of all color-correction for you..SS Using an OS- or application-supplied CMSIf you are so lucky to have access to CMS functionality from withinyour application, you may instruct the library to leave color-correctionto you.Select the MNG_APP_CMS directive during compilation of the library.You MUST also set the following callbacks: mng_processgamma, mng_processchroma, mng_processsrgb, mng_processiccp and mng_processarowThe last callback is called when the library needs you to correctan arbitrary line of pixels. The other callbacks are called whenthe corresponding color-information is encountered in the file.You must store this information somewhere for use in themng_processarow() callback..SS Using gamma-only correctionThis isn't a preferred method, but it's better than no correctionat all. Gamma-only correction will at least compensate forgamma-differences between the original recorder and your output device.Select the MNG_GAMMA_ONLY directive during compilationof the library. Your compiler MUST support fp operations..SS No color correctionOuch. This is really bad. This is the least preferred method,but may be necessary if your system cannot use lcms, doesn'thave its own CMS, and does not allow fp operations, ruling outthe gamma-only option.Select the MNG_NO_CMS directive during compilation.Images will definitely not be displayed as seen by the Author!!!.SS Animations and timingAnimations require some form of timing support. The library relieson two callbacks for this purpose. The mng_gettickcount() andmng_settimer() callbacks. mng_gettickcount() is used to determinethe passing of time in milliseconds since the beginning of theanimation. This is also used to compensate during suspension-modeif you are using the mng_readdisplay() function to read & displaythe file simultaneously.The callback may return an arbitrary number of milliseconds, butthis number must increase proportionaly between calls. Most modernsystems will have some tickcount() function which derives itsinput from an internal clock. The value returned from this functionis more than adequate for libmng.The mng_settimer() callback is called when the library determinesa little "pause" is required before rendering another frame of theanimation. The pause interval is also expressed in milliseconds.Your application should store this value and return immediately.The library will then make appropriate arrangements to store itsinternal state and returns to your application with theMNG_NEEDTIMERWAIT code.At that point you should suspend processing and wait the giveninterval. Please use your OS features for this. Do not engage somesort of loop. That is real bad programming practice. Most modernsystems will have some timing functions. A simple wait() functionmay suffice, but this may prevent your applications main-task fromrunning, and possibly prevent the actual update of your output device..SS The mng_refresh() callbackThe mng_refresh() callback is called whenever the library has"finished" drawing a new frame onto your canvas, and just before itwill call the mng_settimer() callback.This allows you to perform some actions necessary to "refresh" thecanvas onto your output device. Please do NOT suspend processinginside this callback. This must be handled after the mng_settimer()callback!.SS Displaying while readingThis method is preferred if you are reading from a slow input device(such as a dialup-line) and you wish to start displaying somethingas quickly as possible. This functionality is provided mainly forbrowser-type applications but may be appropriate for otherapplications as well.The method is usually used in unison with the suspension-mode ofthe read module. A typical implementation would look like this: /* initiale library and set required callbacks */ /* activate suspension-mode */ myretcode = mng_set_suspensionmode (myhandle, MNG_TRUE); if (myretcode != MNG_NOERROR) /* process error */; myretcode = mng_readdisplay (myhandle); while ((myretcode == MNG_NEEDMOREDATA) || (myretcode == MNG_NEEDTIMERWAIT)) { if (myretcode == MNG_NEEDMOREDATA) /* wait for more input-data */; else /* wait for timer interval */; myretcode = mng_display_resume (myhandle); } if (myretcode != MNG_NOERROR) /* process error */;More advanced programming methods may require a different approach,but the final result should function as in the code above..SS Displaying after readingThis method is used to display a file that was previously read.It is primarily meant for viewers with direct file access, such as1a local harddisk.Once you have successfully read the file, all you need to do is: myretcode = mng_display (myhandle); while (myretcode == MNG_NEEDTIMERWAIT) { /* wait for timer interval */; myretcode = mng_display_resume (myhandle); } if (myretcode != MNG_NOERROR) /* process error */;Again, more advanced programming methods may require a differentapproach, but the final result should function as in the code above..SS Display manipulationSeveral HLAPI functions are provided to allow a user to manipulatethe normal flow of an animation.\- mng_display_freeze (mng_handle hHandle)This will "freeze" the animation in place.\- mng_display_resume (mng_handle hHandle)This function can be used to resume a frozen animation, or to forcethe library to advance the animation to the next frame.\- mng_display_reset (mng_handle hHandle)This function will "reset" the animation into its pristine state.Calling mng_display() afterwards will re-display the animationfrom the first frame.\- mng_display_golayer (mng_handle hHandle, mng_uint32 iLayer)\- mng_display_goframe (mng_handle hHandle, mng_uint32 iFrame)\- mng_display_gotime (mng_handle hHandle, mng_uint32 iPlaytime)These three functions can be used to "jump" to a specific layer, frameor timeslot in the animation. You must "freeze" the animation beforeusing any of these functions.All above functions may only be called during a timer interval!It is the applications responsibility to cleanup any resources withrespect to the timer wait..SH VI. WritingThe main focus of the library lies in its displaying capabilites.But it does offer writing support as well.You can create and write a file, or you can write a file youhave previously read, providing the storage of chunks was enabledand active.For this to work you must have compiled the library with theMNG_WRITE_SUPPO1RT and MNG_ACCESS_CHUNKS directives. The standard DLL andShared Library have this on by default!.SS SetupAs always you must have initialized the library and be the owner ofa mng_handle. The following callbacks are essential: mng_openstream, mng_writedata, mng_closestreamYou can optionally define: mng_errorproc, mng_traceprocThe creation and writing functions will fail if you are in the middleof reading, creating or writing a file..SS Creating a new fileTo start a new file the library must be in its initial state.First you need to tell the library your intentions: myretcode = mng_create (myhandle); if (myretcode != MNG_NOERROR) /* process error */;After that you start adding the appropriate chunks: myretcode = mng_put1chunk_mhdr (myhandle, ...); if (myretcode != MNG_NOERROR) /* process error */;And so on, and so forth. Note that the library will automatically signalthe logical end of the file by the ending chunk. Also the first chunkwill indicate the library the filetype (eg. PNG, JNG or MNG) and forcethe proper signature when writing the file.The code above can be simplified, as you can always get the last errorcodeby using the mng_getlasterror() function: if ( (mng_putchunk_xxxx (myhandle, ...)) or (mng_putchunk_xxxx (myhandle, ...)) or ...etc... ) /* process error */;Please note that you must have a pretty good understanding of the chunkspecification. Unlike the read functions, there are virtually no checks,so it is quite possible to write completely wrong files.It is a good practice to read back your file into the library to verifyits integrity.Once you've got all the chunks added, all you do is: myretcode mng_write (myhandle); if (myretcode != MNG_NOERROR) /* process error */;And presto. You're done. The real work is of course carried out inyour callbacks. Note that this is a single operation as opposed tothe read & display functions that may return with MNG_NEEDMOREDATAand/or MNG_NEEDTIMERWAIT. The write function just does the job, andonly returns after it's finished or if it encounters someunrecoverable error..SS Writing a previously read fileIf you have already successfully read a file, you can use the library towrite it out as a copy or something. You MUST have compiled the librarywith the MNG_STORE_CHUNKS directive, and you must have donemng_set_storechunks (myhandle, MNG_TRUE).This doesn't require the MNG_ACCESS_CHUNKS directive, unless you wantto fiddle with the chunks as well.Again all you need to do is: myretcode mng_write (myhandle); if (myretcode != MNG_NOERROR) /* process error */;.SH VII. Modifying/Customizing libmng:not finished yet.SS Compilation directivesnot finished yet.SS Platform dependant modificationnot finished yet.SH "SEE ALSO".IR mng(5), jng(5), png(5), libpng(3).LPlibmng :.IP.brhttp://www.libmng.com.LPzlib :.IP.brhttp://www.info-zip.org/pub/infozip/zlib/.LPIJG JPEG library :.IP.brhttp://www.ijg.org.LPlcms (little CMS) by Marti Maria Saguer :.IP.brhttp://www.littlecms.com/.LPMNG specification:.IP.brhttp://www.libpng.org/pub/mng.LPIn the case of any inconsistency between the MNG specificationand this library, the specification takes precedence..SH AUTHORSThis man page: Gerard Juyn<gerard at libmng.com>The contributing authors would like to thank all those who helpedwith testing, bug fixes, and patience. This wouldn't have beenpossible without all of you!!!.SH COPYRIGHT NOTICE:Copyright (c) 2000-2002 Gerard JuynFor the purposes of this copyright and license, "Contributing Authors"is defined as the following set of individuals: Gerard JuynThe MNG Library is supplied "AS IS". The Contributing Authorsdisclaim all warranties, expressed or implied, including, withoutlimitation, the warranties of merchantability and of fitness for anypurpose. The Contributing Authors assume no liability for direct,indirect, incidental, special, exemplary, or consequential damages,which may result from the use of the MNG Library, even if advised ofthe possibility of such damage.Permission is hereby granted to use, copy, modify, and distribute thissource code, or portions hereof, for any purpose, without fee, subjectto the following restrictions:1. The origin of this source code must not be misrepresented;you must not claim that you wrote the original software.2. Altered versions must be plainly marked as such and must not bemisrepresented as being the original source.3. This Copyright notice may not be removed or altered from any sourceor altered source distribution.The Contributing Authors specifically permit, without fee, andencourage the use of this source code as a component to supportingthe MNG and JNG file format in commercial products. If you use thissource code in a product, acknowledgment would be highly appreciated..SH RemarksParts of this software have been adapted from the libpng library.Although this library supports all features from the PNG specification(as MNG descends from it) it does not require the libpng library.It does require the zlib library and optionally the IJG JPEG library,and/or the "little-cms" library by Marti Maria Saguer (depending on theinclusion of support for JNG and Full-Color-Management respectively.This library's function is primarily to read and display MNGanimations. It is not meant as a full-featured image-editingcomponent! It does however offer creation and editing functionalityat the chunk level. (future modifications may include some moresupport for creation and or editing).\" end of man page