Introduction
CxImageMNG
is the module of CxImage
used to play MNG animations. It uses the CxImage
members, but to play the animation, additional variables and functions are required. I decided to keep the MNG stuff separated from the "static" formats, to limit the growth of the base class due to the new features.
As with the other modules, CxImageMNG
is mainly an interface for the LibMNG functions, it takes care of the I/O operations and of the specific requirements of the library. CxImageMNG
can also read PNG and JNG images.
What do I need?
- LibMNG. You can find the latest version here.
- JPEG and ZLIB libraries. Used by LibMNG to endode/decode files.
All these libraries are included in the source code.
Structures and callbacks
"Libmng makes extensive use of callback functions. This is meant to keep the library as platform-independent and flexible as possible." In CxImageMNG
, these are declared as:
mng_setcb_errorproc (mng_handle, mymngerror);
mng_setcb_openstream (mng_handle, mymngopenstream);
mng_setcb_closestream (mng_handle, mymngclosestream);
mng_setcb_readdata (mng_handle, mymngreadstream);
mng_setcb_processheader(mng_handle, mymngprocessheader);
mng_setcb_getcanvasline(mng_handle, mymnggetcanvasline);
mng_setcb_refresh (mng_handle, mymngrefresh);
mng_setcb_gettickcount (mng_handle, mymnggetticks);
mng_setcb_settimer (mng_handle, mymngsettimer);
mng_setcb_refresh (mng_handle, mymngrefresh);
Some of these are empty (mymngopenstream
), or obvious (mymngreadstream
), the most useful for the final applications are mymngprocessheader
, where we get the initial information about the image, and mymngsettimer
, where we get the essential value for the timer.
Another important parameter is pUserdata
, where the application can store its parameters; in CxImageMNG
, this is a pointer to the mnginfo
variable.
typedef struct
{
FILE *file; BYTE *image; HANDLE thread; mng_uint32 delay; mng_uint32 width; mng_uint32 height;
mng_uint32 effwdt;
mng_int16 bpp;
mng_bool animation; mng_bool animation_enabled; float speed; } mngstuff;
In the callbacks, this information is available at all times through the mng_get_userdata
function.
How to play animations
First, we must load the file:
image = new CxImageMNG();
image->ReadFile(filename);
Then, if it's an animation, we must create a thread to play it:
if (image->mnginfo.animation) {
image->mnginfo.animation_enabled=1;
DWORD dwID;
image->mnginfo.thread = CreateThread(NULL,0,RunMNGThread,this,0,&dwID);
}
In the end, we must handle the execution of the thread:
unsigned long _stdcall RunMNGThread(void *lpParam){
Sleep((DWORD)(image->mnginfo.delay / image->mnginfo.speed));
while (image->mnginfo.animation_enabled && image->Resume()){
SendMessage(hWnd, WM_USER_NEWFRAME,0,0);
Sleep((DWORD)(image->mnginfo.delay / image->mnginfo.speed));
}
image->mnginfo.thread=0;
return 0;
}
The Resume()
function is used to obtain the next frame. To stop the animation, simply set image->mnginfo.animation_enabled = 0
. The thread is automatically closed in the CxImageMNG
destructor.
Credits
- LIBMNG Copyright (c) 2000,2001 Gerard Juyn.
- Original mng.cpp code created by Nikolaus Brennig, November 14th, 2000.
- Special thanks to Frank Haug for suggestions and code.
More specific credits and disclaimers are in every header file of each library.
Compatibility
Win95, WinNT, Win98, WinME, W2K, WinXP = Yes.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.