ILboolean iLoadMngInternal() { mng_handle mng; if (iCurImage == NULL) { ilSetError(IL_ILLEGAL_OPERATION); return IL_FALSE; } mng = mng_initialize(MNG_NULL, mymngalloc, mymngfree, MNG_NULL); if (mng == MNG_NULL) { ilSetError(IL_LIB_MNG_ERROR); return IL_FALSE; } // If .mng background is available, use it. mng_set_usebkgd(mng, MNG_TRUE); // Set the callbacks. mng_setcb_errorproc(mng, mymngerror); mng_setcb_openstream(mng, mymngopenstream); mng_setcb_closestream(mng, mymngclosestream); mng_setcb_readdata(mng, (mng_readdata)mymngreadstream); mng_setcb_gettickcount(mng, mymnggetticks); mng_setcb_settimer(mng, mymngsettimer); mng_setcb_processheader(mng, mymngprocessheader); mng_setcb_getcanvasline(mng, mymnggetcanvasline); mng_setcb_refresh(mng, mymngrefresh); mng_read(mng); mng_display(mng); return ilFixImage(); }
bool CMNGAnimation::Load(const char* filename, IFileSystem& fs) { this->~CMNGAnimation(); // open the file m_file = fs.Open(filename, IFileSystem::read); if (m_file == NULL) { return false; } // initialize MNG playback m_stream = mng_initialize(this, CB_Allocate, CB_Free, NULL); // set all of the callbacks mng_setcb_openstream(m_stream, CB_OpenStream); mng_setcb_closestream(m_stream, CB_CloseStream); mng_setcb_readdata(m_stream, CB_ReadData); mng_setcb_processheader(m_stream, CB_ProcessHeader); mng_setcb_gettickcount(m_stream, CB_GetTickCount); mng_setcb_getcanvasline(m_stream, CB_GetCanvasLine); mng_setcb_refresh(m_stream, CB_Refresh); mng_setcb_settimer(m_stream, CB_SetTimer); // do some reading if (mng_read(m_stream) != MNG_NOERROR) { return false; } return true; }
/** ** Load a MNG ** ** @param name Name of the MNG file */ int Mng::Load(const char *name) { mng_retcode myretcode; char buf[PATH_MAX]; LibraryFileName(name, buf, sizeof(buf)); this->name = new_strdup(buf); handle = mng_initialize(this, my_alloc, my_free, MNG_NULL); if (handle == MNG_NULL) { return -1; } mng_setcb_openstream(handle, my_openstream); mng_setcb_closestream(handle, my_closestream); mng_setcb_readdata(handle, my_readdata); mng_setcb_processheader(handle, my_processheader); mng_setcb_processmend(handle, my_processmend); mng_setcb_getcanvasline(handle, my_getcanvasline); mng_setcb_refresh(handle, my_refresh); mng_setcb_gettickcount(handle, my_gettickcount); mng_setcb_settimer(handle, my_settimer); mng_setcb_errorproc(handle, my_errorproc); mng_read(handle); if (surface && iteration != 0x7fffffff) { myretcode = mng_display(handle); } if (!surface || iteration == 0x7fffffff) { return -1; } return 0; }
/** ** Load a MNG ** ** @param name Name of the MNG file */ int Mng::Load(const std::string &name) { this->name = LibraryFileName(name.c_str()); handle = mng_initialize(this, my_alloc, my_free, MNG_NULL); if (handle == MNG_NULL) { return -1; } mng_setcb_openstream(handle, my_openstream); mng_setcb_closestream(handle, my_closestream); mng_setcb_readdata(handle, my_readdata); mng_setcb_processheader(handle, my_processheader); mng_setcb_processmend(handle, my_processmend); mng_setcb_getcanvasline(handle, my_getcanvasline); mng_setcb_refresh(handle, my_refresh); mng_setcb_gettickcount(handle, my_gettickcount); mng_setcb_settimer(handle, my_settimer); mng_setcb_errorproc(handle, my_errorproc); mng_read(handle); if (surface && iteration != 0x7fffffff) { mng_display(handle); } if (!surface || iteration == 0x7fffffff) { return -1; } return 0; }
static gboolean gtk_mng_view_init_libmng (GtkMngView * mng_view) { FUNCTION_ENTRY(); GtkWidget * widget; g_return_val_if_fail (IS_GTK_MNG_VIEW (mng_view), FALSE); if (mng_view->MNG_handle) mng_cleanup (&mng_view->MNG_handle); mng_view->MNG_handle = mng_initialize (mng_view, mng_malloc_callback, mng_free_callback, MNG_NULL); if (mng_view->MNG_handle == MNG_NULL) { FUNCTION_EXIT(); return FALSE; } mng_set_storechunks(mng_view->MNG_handle, MNG_TRUE); //mng_set_dfltimggamma(mng_view->MNG_handle, 5); //mng_set_displaygamma(mng_view->MNG_handle, 4); if (mng_setcb_openstream (mng_view->MNG_handle, mng_open_stream_callback) != MNG_NOERROR || mng_setcb_closestream (mng_view->MNG_handle, mng_close_stream_callback) != MNG_NOERROR || mng_setcb_readdata (mng_view->MNG_handle, mng_read_data_callback) != MNG_NOERROR || mng_setcb_processheader (mng_view->MNG_handle, mng_process_header_callback) != MNG_NOERROR || mng_setcb_processmend (mng_view->MNG_handle, mng_process_mend_callback) != MNG_NOERROR || mng_setcb_processterm (mng_view->MNG_handle, mng_process_term_callback) != MNG_NOERROR || mng_setcb_settimer (mng_view->MNG_handle, mng_set_timer_callback) != MNG_NOERROR || mng_setcb_gettickcount (mng_view->MNG_handle, mng_get_tickcount_callback) != MNG_NOERROR || mng_setcb_getcanvasline (mng_view->MNG_handle, mng_get_canvas_line_callback) != MNG_NOERROR || mng_setcb_getalphaline (mng_view->MNG_handle, mng_get_alpha_line_callback) != MNG_NOERROR || mng_setcb_refresh (mng_view->MNG_handle, mng_refresh_callback) != MNG_NOERROR) { mng_cleanup (&mng_view->MNG_handle); FUNCTION_EXIT(); return FALSE; } //mng_set_suspensionmode(mng_view->MNG_handle, MNG_TRUE); mng_set_canvasstyle (mng_view->MNG_handle, MNG_CANVAS_RGB8_A8); widget = GTK_WIDGET (mng_view); if (!GTK_WIDGET_REALIZED (widget)) gtk_widget_realize (widget); mng_set_bgcolor (mng_view->MNG_handle, widget->style->bg[GTK_STATE_NORMAL].red, widget->style->bg[GTK_STATE_NORMAL].green, widget->style->bg[GTK_STATE_NORMAL].blue); FUNCTION_EXIT(); return TRUE; }
//--------------------------------------------------------------------------- bool __fastcall TMainForm::DumpTree( void ) { mng_handle hMNG; // let's initialize the library hMNG = mng_initialize( (mng_ptr)this, Alloc, Free, NULL ); if( !hMNG ) // did that work out ? { MNGError( hMNG, "Cannot initialize libmng." ); mng_cleanup( &hMNG ); // Always cleanup the library MsgBoxStop( "Bye!" ); Application->Terminate(); // Exit now } // setup callbacks if( (mng_setcb_openstream ( hMNG, OpenStream ) != 0) || (mng_setcb_closestream ( hMNG, CloseStream ) != 0) || (mng_setcb_processheader( hMNG,ProcessHeader ) != 0) || (mng_setcb_readdata ( hMNG, FileReadData ) != 0) ) { MNGError( hMNG, "Cannot set callbacks for libmng."); mng_cleanup( &hMNG ); // Always cleanup the library MsgBoxStop( "Bye!" ); Application->Terminate(); // Exit now } else { // read the file into memory if( mng_read( hMNG ) != 0 ) { // Because we read the whole file in first, // here is where bad input files first choke ! MNGError( hMNG, "Cannot read the file." ); mng_cleanup( &hMNG ); // Always cleanup the library return false; } else { // run through the chunk list if( mng_iterate_chunks( hMNG, 0, IterateChunks ) != 0 ) { MNGError( hMNG, "Error Getting Chunk info!" ); mng_cleanup( &hMNG ); // Always cleanup the library return false; // Errors may occur with bad chunk data } } } mng_cleanup( &hMNG ); // Always cleanup the library return true; }
// return 1 if okay static int my_init_mng(PluginInstance *This) { mng_retcode rv; int err; This->mng = mng_initialize((mng_ptr)This,memallocfunc,memfreefunc,NULL); //(mng_memalloc) (mng_memfree) #ifdef MNGPLG_CMS init_color_management(This); #endif err=0; rv=mng_setcb_openstream (This->mng, callback_openstream ); if(rv) err++; rv=mng_setcb_closestream (This->mng, callback_closestream ); if(rv) err++; rv=mng_setcb_readdata (This->mng, callback_readdata ); if(rv) err++; rv=mng_setcb_processheader (This->mng, callback_processheader); if(rv) err++; rv=mng_setcb_getcanvasline (This->mng, callback_getcanvasline); if(rv) err++; rv=mng_setcb_refresh (This->mng, callback_refresh ); if(rv) err++; rv=mng_setcb_gettickcount (This->mng, callback_gettickcount ); if(rv) err++; rv=mng_setcb_settimer (This->mng, callback_settimer ); if(rv) err++; rv=mng_setcb_processtext (This->mng, callback_processtext ); if(rv) err++; #ifdef MNGPLG_TRACE rv=mng_setcb_traceproc (This->mng, callback_traceproc ); if(rv) err++; #endif if(err) { warn(This,"Error setting libmng callback functions"); return 0; } rv= mng_set_suspensionmode (This->mng,MNG_TRUE); if(rv) { warn(This,"Error setting suspension mode"); return 0; } // if the web page author provided a bgcolor, use it if(This->force_bgcolor) { rv=mng_set_bgcolor (This->mng, This->bg_r, This->bg_g, This->bg_b); } #ifdef MNGPLG_TRACE fprintf(tracefile,"initial readdisplay\n"); #endif handle_read_error(This, mng_readdisplay(This->mng) ); return 1; }
bool ImageJngFile::Load (uint8 *iBuffer, size_t iSize) { mng_retcode retcode; const int magicSize = 8; const char magicMNG[] = "\x8aMNG\x0d\x0a\x1a\x0a"; const char magicJNG[] = "\x8bJNG\x0d\x0a\x1a\x0a"; // check for magic JNG/MNG bytes. If not correct, we can skip // messing around w/ libmng entirely. if ((iSize < 8) || ((memcmp ((void*)iBuffer, (void*)&magicMNG, magicSize)) && (memcmp ((void*)iBuffer, (void*)&magicJNG, magicSize)))) { return false; } handle = mng_initialize (mng_ptr(this), cb_alloc, cb_free, MNG_NULL); if (!handle) { Report (object_reg, CS_REPORTER_SEVERITY_WARNING, "failed to initialize libmng"); return false; } buffer = iBuffer; bufptr = buffer; bufferSize = iSize; if ((mng_setcb_openstream (handle, cb_openstream) != MNG_NOERROR) || (mng_setcb_closestream (handle, cb_closestream) != MNG_NOERROR) || (mng_setcb_readdata (handle, cb_readdata) != MNG_NOERROR) || (mng_setcb_processheader(handle, cb_processheader) != MNG_NOERROR) || (mng_setcb_getcanvasline(handle, cb_getcanvasline) != MNG_NOERROR) || (mng_setcb_refresh(handle, cb_imagerefresh) != MNG_NOERROR) || (mng_setcb_gettickcount(handle, cb_gettickcount) != MNG_NOERROR) || (mng_setcb_settimer(handle, cb_settimer) != MNG_NOERROR)) { ReportLibmngError (object_reg, handle, "failed to set libmng callbacks"); mng_cleanup (&handle); return false; } retcode = mng_read (handle); if (retcode != MNG_NOERROR) { if (retcode != MNG_INVALIDSIG) // maybe its just not an jng/mng... ReportLibmngError (object_reg, handle, "failed to read data"); mng_cleanup (&handle); return false; } // Don't read PNGs if (mng_get_sigtype (handle) == mng_it_png) { delete[] NewImage; mng_cleanup (&handle); return false; } // Even on still images, libmng issues timer requests. // so, as long as the requests are 'immediate' we continue // displaying. If a delay is requested we end loading. timer = 2; retcode = mng_display (handle); while ((retcode == MNG_NEEDTIMERWAIT) && (timer <= 1)) { retcode = mng_display_resume (handle); } if ((retcode != MNG_NOERROR) && (retcode != MNG_NEEDTIMERWAIT)) { ReportLibmngError (object_reg, handle, "failed to display data"); mng_cleanup (&handle); return false; } doWait = (retcode == MNG_NEEDTIMERWAIT); animated = doWait; if (NewImage) { csRGBpixel *rgbImage = csPackRGBA::CopyUnpackRGBAtoRGBpixel (NewImage, Width*Height); ConvertFromRGBA (rgbImage); // Subsequent images may contain alpha, so don't check if (!doWait) CheckAlpha(); } if (mng_get_sigtype (handle) != mng_it_mng) { delete[] NewImage; NewImage = 0; mng_cleanup (&handle); handle = 0; } return true; }
csPtr<iDataBuffer> csJNGImageIO::Save (iImage *Image, iImageIO::FileFormatDescription *, const char* extraoptions) { // we need to get a RGB/RGBA version of the image. switch (Image->GetFormat() & CS_IMGFMT_MASK) { case CS_IMGFMT_PALETTED8: //imgRGBA = Image->Clone (); //imgRGBA->SetFormat (CS_IMGFMT_TRUECOLOR | (Image->GetFormat() & CS_IMGFMT_ALPHA)); // act like JPEG plugin; reject paletted image so no // unwanted/unnoticed conversions take place. return 0; break; case CS_IMGFMT_TRUECOLOR: imgRGBA = csRef<iImage>(Image); break; default: // unknown format return 0; } // compression options int quality = 80; bool progressive = false; bool alpha_jpeg = false; int alpha_png_compress = 6; int alpha_jpeg_quality = -1; /* parse output options. options are a comma-separated list and can be either 'option' or 'option=value'. supported options: compress=# image color compression, 0..100 higher values give smaller files but uglier results. progressive progressive encoding. jng_lossy_alpha use lossy JPEG compression for alpha channel (instead of default lossles PNG) jng_alpha_compress alpha channel compression, 0..100 Impact of higher value depends on alpha channel type. JPEG - smaller files, uglier results. PNG - smaller files, longer time to encode. Note: defaults to value for image color compression if lossy alpha is selected. examples: compress=50 progressive,compress=30 */ csImageLoaderOptionsParser optparser (extraoptions); optparser.GetBool ("progressive", progressive); if (optparser.GetInt ("compress", quality)) { quality = 100 - quality; if (quality < 0) quality = 0; if (quality > 100) quality = 100; if (alpha_jpeg_quality == -1) alpha_jpeg_quality = quality; } if (optparser.GetBool ("jng_lossy_alpha", alpha_jpeg)) { if (alpha_jpeg_quality == -1) alpha_jpeg_quality = quality; } if (optparser.GetInt ("jng_alpha_compress", alpha_png_compress)) { alpha_jpeg_quality = 100 - alpha_png_compress; if (alpha_jpeg_quality < 0) alpha_jpeg_quality = 0; if (alpha_jpeg_quality > 100) alpha_jpeg_quality = 100; alpha_png_compress /= 10; if (alpha_png_compress < 0) alpha_png_compress = 0; if (alpha_png_compress > 9) alpha_png_compress = 9; } mng_handle handle = mng_initialize ( mng_ptr(this), cb_alloc, cb_free, MNG_NULL); if (!handle) { Report (object_reg, CS_REPORTER_SEVERITY_WARNING, "failed to initialize libmng"); return 0; } if ((mng_setcb_openstream (handle, cb_openstream) != MNG_NOERROR) || (mng_setcb_closestream (handle, cb_closestream) != MNG_NOERROR) || (mng_setcb_writedata (handle, cb_writedata) != MNG_NOERROR)) { ReportLibmngError (object_reg, handle, "failed to set libmng callbacks"); mng_cleanup (&handle); return 0; } outfile = new csMemFile (); if (mng_create (handle) != MNG_NOERROR) { ReportLibmngError (object_reg, handle, "failed to create new jng"); mng_cleanup (&handle); delete outfile; imgRGBA = 0; return 0; } bool has_alpha = (imgRGBA->GetFormat() & CS_IMGFMT_ALPHA) != 0; if (mng_putchunk_jhdr (handle, imgRGBA->GetWidth(), imgRGBA->GetHeight(), has_alpha ? MNG_COLORTYPE_JPEGCOLORA : MNG_COLORTYPE_JPEGCOLOR, MNG_BITDEPTH_JPEG8, MNG_COMPRESSION_BASELINEJPEG, progressive ? MNG_INTERLACE_PROGRESSIVE : MNG_INTERLACE_SEQUENTIAL, has_alpha?8:0, has_alpha?(alpha_jpeg?8:0):0, 0, 0) != MNG_NOERROR) { ReportLibmngError (object_reg, handle, "failed to put JHDR chunk"); mng_cleanup (&handle); delete outfile; imgRGBA = 0; return 0; } // @@@ chunk data generation. // lots of stuff needs to be done manually. // should be changed as libmng evolves. // write out alpha channel if (has_alpha) { // extract the alpha channel from the image int pixels = imgRGBA->GetWidth() * imgRGBA->GetHeight(); uint8 *alpha = new uint8 [pixels]; uint8 *alphaptr = alpha; csRGBpixel *imgdata = (csRGBpixel*)imgRGBA->GetImageData(); while (pixels>0) { *alphaptr++ = (imgdata++)->alpha; pixels--; } if (alpha_jpeg) { // compress the alpha data as JPEG and write it out. uint8* volatile row = 0; struct jpg_datastore ds; struct jpeg_compress_struct cinfo; struct my_error_mgr jerr; cinfo.err = jpeg_std_error (&jerr.pub); jerr.pub.error_exit = my_error_exit; if (setjmp (jerr.setjmp_buffer)) { Report (object_reg, CS_REPORTER_SEVERITY_WARNING, "failed to JPEG compress alpha data"); mng_cleanup (&handle); delete outfile; delete [] row; delete[] alpha; jpeg_destroy_compress (&cinfo); imgRGBA = 0; return 0; } jpeg_create_compress (&cinfo); jpeg_buffer_dest (&cinfo, &ds); cinfo.image_width = imgRGBA->GetWidth (); cinfo.image_height = imgRGBA->GetHeight (); cinfo.input_components = 1; cinfo.in_color_space = JCS_GRAYSCALE; row = new uint8[cinfo.image_width]; jpeg_set_defaults (&cinfo); jpeg_set_quality (&cinfo, alpha_jpeg_quality, true); jpeg_start_compress (&cinfo, true); JSAMPROW row_pointer[1]; uint8 *image = alpha; row_pointer[0] = (JSAMPLE*)&row[0]; while (cinfo.next_scanline < cinfo.image_height) { for (size_t i=0; i < cinfo.image_width; i++) row[i] = image[cinfo.next_scanline * cinfo.image_width + i]; jpeg_write_scanlines (&cinfo, row_pointer, 1); } jpeg_finish_compress (&cinfo); jpeg_destroy_compress (&cinfo); delete [] row; // funny, mng_putchunk_jdaa is missing from libmng //if (mng_putchunk_jdaa (handle, ds.len, ds.data) != MNG_NOERROR) if (mng_putchunk_unknown (handle, MNG_UINT_JDAA, (mng_uint32)ds.len, ds.data) != MNG_NOERROR) { ReportLibmngError (object_reg, handle, "failed to put JDAA chunk"); mng_cleanup (&handle); delete outfile; delete[] alpha; imgRGBA = 0; return 0; } } else { // generate the IDAT chunk data // we use the "Up" filter. uint8* chunkdata = new uint8[(imgRGBA->GetWidth() + 1) * imgRGBA->GetHeight()]; uint8* lastline = new uint8[imgRGBA->GetWidth()]; uint8* chunkptr = chunkdata; alphaptr = alpha; memset (lastline, 0, imgRGBA->GetWidth()); int lines = imgRGBA->GetHeight(); while (lines > 0) { *chunkptr++ = 2; int pix = 0; while (pix<imgRGBA->GetWidth()) { *chunkptr++ = *alphaptr - lastline[pix]; lastline[pix] = *alphaptr++; pix++; } lines--; } delete[] lastline; // now compress the data z_stream zs; zs.zalloc = (alloc_func) 0; zs.zfree = (free_func) 0; zs.next_in = (Byte *) chunkdata; zs.avail_in = (imgRGBA->GetWidth() + 1) * imgRGBA->GetHeight(); if (deflateInit (&zs, alpha_png_compress) != Z_OK) { Report (object_reg, CS_REPORTER_SEVERITY_WARNING, "deflateInit() failed"); mng_cleanup (&handle); delete outfile; delete[] chunkdata; delete[] alpha; imgRGBA = 0; return 0; } char buff[0x8000]; while (1) { zs.next_out = (Byte *)buff; zs.avail_out = sizeof (buff); int rc = deflate (&zs, Z_FINISH); /* Do actual compression */ size_t size = sizeof (buff) - zs.avail_out; // create a chuk w/compressed data. if (mng_putchunk_idat (handle, (mng_uint32)size, &buff) != MNG_NOERROR) { ReportLibmngError (object_reg, handle, "failed to put IDAT chunk"); deflateEnd (&zs); mng_cleanup (&handle); delete outfile; delete[] chunkdata; delete[] alpha; imgRGBA = 0; return 0; } if (rc == Z_STREAM_END) break; /* finished */ } deflateEnd (&zs); delete[] chunkdata; } delete[] alpha; } // compress the color data as JPEG and write it out. csRGBcolor* volatile row = 0; struct jpg_datastore ds; struct jpeg_compress_struct cinfo; struct my_error_mgr jerr; cinfo.err = jpeg_std_error (&jerr.pub); jerr.pub.error_exit = my_error_exit; if (setjmp (jerr.setjmp_buffer)) { Report (object_reg, CS_REPORTER_SEVERITY_WARNING, "failed to JPEG compress color data"); mng_cleanup (&handle); delete outfile; delete [] row; jpeg_destroy_compress (&cinfo); imgRGBA = 0; return 0; } jpeg_create_compress (&cinfo); jpeg_buffer_dest (&cinfo, &ds); cinfo.image_width = imgRGBA->GetWidth (); cinfo.image_height = imgRGBA->GetHeight (); cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; row = new csRGBcolor[cinfo.image_width]; jpeg_set_defaults (&cinfo); jpeg_set_quality (&cinfo, quality, true); if (progressive) jpeg_simple_progression (&cinfo); jpeg_start_compress (&cinfo, true); JSAMPROW row_pointer[1]; JSAMPLE *image = (JSAMPLE*)csPackRGB::PackRGBpixelToRGB ((csRGBpixel*)Image->GetImageData (), Image->GetWidth () * Image->GetHeight ()); row_pointer[0] = (JSAMPLE*)&row[0]; while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = (JSAMPLE*)&image[cinfo.next_scanline * cinfo.image_width * 3]; jpeg_write_scanlines (&cinfo, row_pointer, 1); } jpeg_finish_compress (&cinfo); jpeg_destroy_compress (&cinfo); delete [] row; if (mng_putchunk_jdat (handle, (mng_uint32)ds.len, ds.data) != MNG_NOERROR) { ReportLibmngError (object_reg, handle, "failed to put JDAT chunk"); mng_cleanup (&handle); delete outfile; imgRGBA = 0; return 0; } imgRGBA = 0; if (mng_putchunk_iend (handle) != MNG_NOERROR) { ReportLibmngError (object_reg, handle, "failed to put IEND chunk"); mng_cleanup (&handle); delete outfile; return 0; } if (mng_write (handle) != MNG_NOERROR) { ReportLibmngError (object_reg, handle, "failed to write out JNG data"); mng_cleanup (&handle); delete outfile; return 0; } mng_cleanup (&handle); csRef<iDataBuffer> db (outfile->GetAllData ()); delete outfile; return csPtr<iDataBuffer> (db); }
static FIBITMAP * DLL_CALLCONV Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) { mng_handle hmng = NULL; if (handle != NULL) { try { // allocate our stream data structure mngstuff *mymng = (mngstuff *)data; // set up the mng decoder for our stream hmng = mng_initialize(mymng, mymngalloc, mymngfree, MNG_NULL); if (hmng == MNG_NULL) { throw "could not initialize libmng"; } // set the colorprofile, lcms uses this mng_set_srgb(hmng, MNG_TRUE ); // set white as background color WORD wRed, wGreen, wBlue; wRed = wGreen = wBlue = (255 << 8) + 255; mng_set_bgcolor(hmng, wRed, wGreen, wBlue); // if PNG Background is available, use it mng_set_usebkgd(hmng, MNG_TRUE ); // no need to store chunks mng_set_storechunks(hmng, MNG_FALSE); // no need to wait: straight reading mng_set_suspensionmode(hmng, MNG_FALSE); // set the callbacks mng_setcb_errorproc(hmng, mymngerror); mng_setcb_openstream(hmng, mymngopenstream); mng_setcb_closestream(hmng, mymngclosestream); mng_setcb_readdata(hmng, mymngreadstream); mng_setcb_processheader(hmng, mymngprocessheader); mng_setcb_getcanvasline(hmng, mymnggetcanvasline); mng_setcb_refresh(hmng, mymngrefresh); mng_setcb_gettickcount(hmng, mymnggetticks); mng_setcb_settimer(hmng, mymngsettimer); // read in the bitmap mng_readdisplay(hmng); // read all bitmaps int retval = MNG_NOERROR; mng_datap pData = (mng_datap)hmng; while(pData->bReading) { retval = mng_display_resume(hmng); if((retval == MNG_NEEDTIMERWAIT) || (retval == MNG_FUNCTIONINVALID)) break; } // temp store the newly created bitmap FIBITMAP *bitmap = mymng->bitmap; // cleanup and return the temp stored bitmap mng_cleanup(&hmng); return bitmap; } catch (const char *message) { FIBITMAP *bitmap = ((mngstuff *)mng_get_userdata(hmng))->bitmap; if(bitmap) { FreeImage_Unload(bitmap); } mng_cleanup(&hmng); FreeImage_OutputMessageProc(s_format_id, message); } } return NULL; }
/** * \brief MPlayer callback: Open MNG stream. * \param[in] demuxer demuxer structure * \return demuxer structure on success, \p NULL on error */ static demuxer_t * demux_mng_open(demuxer_t * demuxer) { mng_priv_t * mng_priv; mng_handle h_mng; mng_retcode mng_ret; sh_video_t * sh_video; // create private data structure mng_priv = calloc(1, sizeof(mng_priv_t)); //stream pointer into private data mng_priv->stream = demuxer->stream; // initialize MNG image instance h_mng = mng_initialize((mng_ptr)mng_priv, demux_mng_alloc, demux_mng_free, MNG_NULL); if (!h_mng) { mp_msg(MSGT_DEMUX, MSGL_ERR, "demux_mng: could not initialize MNG image instance\n"); free(mng_priv); return NULL; } // MNG image handle into private data mng_priv->h_mng = h_mng; // set required MNG callbacks if (mng_setcb_openstream(h_mng, demux_mng_openstream) || mng_setcb_closestream(h_mng, demux_mng_closestream) || mng_setcb_readdata(h_mng, demux_mng_readdata) || mng_setcb_processheader(h_mng, demux_mng_processheader) || mng_setcb_getcanvasline(h_mng, demux_mng_getcanvasline) || mng_setcb_refresh(h_mng, demux_mng_refresh) || mng_setcb_gettickcount(h_mng, demux_mng_gettickcount) || mng_setcb_settimer(h_mng, demux_mng_settimer) || mng_set_canvasstyle(h_mng, MNG_CANVAS_RGBA8)) { mp_msg(MSGT_DEMUX, MSGL_ERR, "demux_mng: could not set MNG callbacks\n"); mng_cleanup(&h_mng); free(mng_priv); return NULL; } // start reading MNG data mng_ret = mng_read(h_mng); if (mng_ret) { mp_msg(MSGT_DEMUX, MSGL_ERR, "demux_mng: could not start reading MNG data: " "mng_retcode %d\n", mng_ret); mng_cleanup(&h_mng); free(mng_priv); return NULL; } // check that MNG header is processed now if (!mng_priv->header_processed) { mp_msg(MSGT_DEMUX, MSGL_ERR, "demux_mng: internal error: header not processed\n"); mng_cleanup(&h_mng); free(mng_priv); return NULL; } // create a new video stream header sh_video = new_sh_video(demuxer, 0); // Make sure the demuxer knows about the new video stream header // (even though new_sh_video() ought to take care of it). // (Thanks to demux_gif.c for this.) demuxer->video->sh = sh_video; // Make sure that the video demuxer stream header knows about its // parent video demuxer stream (this is getting wacky), or else // video_read_properties() will choke. // (Thanks to demux_gif.c for this.) sh_video->ds = demuxer->video; // set format of pixels in video packets sh_video->format = mmioFOURCC(32, 'B', 'G', 'R'); // set framerate to some value (MNG does not have a fixed framerate) sh_video->fps = 5.0f; sh_video->frametime = 1.0f / sh_video->fps; // set video frame parameters sh_video->bih = malloc(sizeof(*sh_video->bih)); sh_video->bih->biCompression = sh_video->format; sh_video->bih->biWidth = mng_priv->width; sh_video->bih->biHeight = mng_priv->height; sh_video->bih->biBitCount = 32; sh_video->bih->biPlanes = 1; // Set start time to something > 0. // - This is required for the variable frame time mechanism // (GIF, MATROSKA, MNG) in video.c to work for the first frame. sh_video->ds->pts = MNG_START_PTS; // set private data in demuxer and return demuxer demuxer->priv = mng_priv; return demuxer; }
static bool sWriteMNG(GBitmap *bitmap, Stream &stream, U32 compressionLevel) { TORQUE_UNUSED( bitmap ); TORQUE_UNUSED( stream ); TORQUE_UNUSED( compressionLevel ); return false; #if 0 // ONLY RGB bitmap writing supported at this time! AssertFatal(getFormat() == GFXFormatR8G8B8 || getFormat() == GFXFormatR8G8B8A8 || getFormat() == GFXFormatA8, "GBitmap::writeMNG: ONLY RGB bitmap writing supported at this time."); if(getFormat() != GFXFormatR8G8B8 && getFormat() != GFXFormatR8G8B8A8 && getFormat() != GFXFormatA8) return (false); // maximum image size allowed #define MAX_HEIGHT 4096 if(getHeight() >= MAX_HEIGHT) return false; mngstuff mnginfo; dMemset(&mnginfo, 0, sizeof(mngstuff)); mng_handle mng = mng_initialize(&mnginfo, mngMallocFn, mngFreeFn, MNG_NULL); if(mng == NULL) { return false; } // setup the callbacks mng_setcb_openstream(mng, mngOpenDataFn); mng_setcb_closestream(mng, mngCloseDataFn); mng_setcb_writedata(mng, mngWriteDataFn); // create the file in memory mng_create(mng); mng_putchunk_defi(mng, 0, 0, 0, MNG_FALSE, 0, 0, MNG_FALSE, 0, getWidth(), 0, getHeight()); mnginfo.image = (GBitmap*)this; mnginfo.stream = &stream; switch(getFormat()) { case GFXFormatA8: mng_putchunk_ihdr(mng, getWidth(), getHeight(), MNG_BITDEPTH_8, MNG_COLORTYPE_GRAY, MNG_COMPRESSION_DEFLATE, MNG_FILTER_ADAPTIVE, MNG_INTERLACE_NONE); // not implemented in lib yet //mng_putimgdata_ihdr(mng, getWidth(), getHeight(), // MNG_COLORTYPE_GRAY, // MNG_BITDEPTH_8, // MNG_COMPRESSION_DEFLATE, // MNG_FILTER_ADAPTIVE, // MNG_INTERLACE_NONE, // MNG_CANVAS_GRAY8, mngCanvasLineFn); break; case GFXFormatR8G8B8: mng_putchunk_ihdr(mng, getWidth(), getHeight(), MNG_BITDEPTH_8, MNG_COLORTYPE_RGB, MNG_COMPRESSION_DEFLATE, MNG_FILTER_ADAPTIVE, MNG_INTERLACE_NONE); // not implemented in lib yet //mng_putimgdata_ihdr(mng, getWidth(), getHeight(), // MNG_COLORTYPE_RGB, // MNG_BITDEPTH_8, // MNG_COMPRESSION_DEFLATE, // MNG_FILTER_ADAPTIVE, // MNG_INTERLACE_NONE, // MNG_CANVAS_RGB8, mngCanvasLineFn); break; case GFXFormatR8G8B8A8: mng_putchunk_ihdr(mng, getWidth(), getHeight(), MNG_BITDEPTH_8, MNG_COLORTYPE_RGBA, MNG_COMPRESSION_DEFLATE, MNG_FILTER_ADAPTIVE, MNG_INTERLACE_NONE); // not implemented in lib yet //mng_putimgdata_ihdr(mng, getWidth(), getHeight(), // MNG_COLORTYPE_RGBA, // MNG_BITDEPTH_8, // MNG_COMPRESSION_DEFLATE, // MNG_FILTER_ADAPTIVE, // MNG_INTERLACE_NONE, // MNG_CANVAS_RGBA8, mngCanvasLineFn); break; } // below is a hack until libmng is mature enough to handle this itself //----------------------------------------------------------------------------- U8 *tmpbuffer = new U8[this->byteSize + getHeight()]; if(tmpbuffer == 0) { mng_cleanup(&mng); return false; } // transfer data, add filterbyte U32 effwdt = getWidth() * this->bytesPerPixel; for(U32 Row = 0; Row < getHeight(); Row++) { // first Byte in each scanline is filterbyte: currently 0 -> no filter tmpbuffer[Row * (effwdt + 1)] = 0; // copy the scanline dMemcpy(tmpbuffer + Row * (effwdt + 1) + 1, getAddress(0, Row), effwdt); } // compress data with zlib U8 *dstbuffer = new U8[this->byteSize + getHeight()]; if(dstbuffer == 0) { delete [] tmpbuffer; mng_cleanup(&mng); return false; } U32 dstbufferSize = this->byteSize + getHeight(); if(Z_OK != compress2((Bytef*)dstbuffer,(uLongf*)&dstbufferSize, (const Bytef*)tmpbuffer, dstbufferSize, 9)) { delete [] tmpbuffer; delete [] dstbuffer; mng_cleanup(&mng); return false; } mng_putchunk_idat(mng, dstbufferSize, (mng_ptr*)dstbuffer); //----------------------------------------------------------------------------- mng_putchunk_iend(mng); delete [] tmpbuffer; delete [] dstbuffer; mng_write(mng); mng_cleanup(&mng); return true; #endif }
static bool sReadMNG(Stream &stream, GBitmap *bitmap) { PROFILE_SCOPE(sReadMNG); mngstuff mnginfo; dMemset(&mnginfo, 0, sizeof(mngstuff)); mng_handle mng = mng_initialize(&mnginfo, mngMallocFn, mngFreeFn, MNG_NULL); if(mng == NULL) return false; // setup the callbacks mng_setcb_errorproc(mng, mngFatalErrorFn); mng_setcb_openstream(mng, mngOpenDataFn); mng_setcb_closestream(mng, mngCloseDataFn); mng_setcb_readdata(mng, mngReadDataFn); mng_setcb_processheader(mng, mngProcessHeaderFn); mng_setcb_getcanvasline(mng, mngCanvasLineFn); mng_setcb_refresh(mng, mngRefreshFn); mng_setcb_gettickcount(mng, mngGetTicksFn); mng_setcb_settimer(mng, mngSetTimerFn); mnginfo.image = bitmap; mnginfo.stream = &stream; mng_read(mng); mng_display(mng); // hacks :( // libmng doesn't support returning data in gray/gray alpha format, // so we grab as RGB/RGBA and just cut off the g and b mng_uint8 colorType = mng_get_colortype(mng); switch(colorType) { case MNG_COLORTYPE_GRAY: case MNG_COLORTYPE_JPEGGRAY: { GBitmap temp(*bitmap); bitmap->deleteImage(); bitmap->allocateBitmap(temp.getWidth(), temp.getHeight(), false, GFXFormatA8); // force getColor to read in in the same color value for each channel // since the gray colortype has the real alpha in the first channel temp.setFormat( GFXFormatA8 ); ColorI color; for(U32 row = 0; row < bitmap->getHeight(); row++) { for(U32 col = 0; col < bitmap->getWidth(); col++) { temp.getColor(col, row, color); bitmap->setColor(col, row, color); } } } break; } mng_cleanup(&mng); // Check this bitmap for transparency bitmap->checkForTransparency(); return true; }
int main(int argc, char *argv[]) { int fbdev,c,option_index; unsigned int alpha; struct fb_var_screeninfo var; /* Check which console we're running on */ init_consoles(); /* allocate our stream data structure */ mng = (mngstuff *) calloc(1, sizeof(*mng)); if (mng == NULL) { fprintf(stderr, "could not allocate stream structure.\n"); exit(0); } alpha = 100; mng->alpha = 100; mng->fbx = 15; mng->fby = 15; mng->background = NULL; while (1) { static struct option long_options[] = { {"help", 0, 0, 'h'}, {"verbose", 0, 0, 'v'}, {"alpha", 1, 0, 'a'}, {"buffered", 0, 0, 'b'}, {"signal", 0, 0, 's'}, {"delta", 0, 0, 'd'}, {"position", 0, 0, 'p'}, {"version", 0, 0, 'V'}, {"start-console",0,0,'S'}, {"console",1,0,'c'}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, "a:x:y:bh?vsd:pVSc:", long_options, &option_index); if (c == -1) break; switch (c) { case 'a': alpha = atoi(optarg); if (alpha > 100) alpha = 100; mng->alpha = alpha; break; case 'x': mng->fbx = atoi(optarg); break; case 'y': mng->fby = atoi(optarg); break; case 'd': delta = atoi(optarg); break; case '?': case 'h': usage(argv[0]); exit(0); case 'v': verbose = 1; break; case 's': waitsignal = 1; break; case 'b': buffered = 1; break; case 'p': dynpos = 1; break; case 'V': version(); exit(0); case 'c': start_console=atoi(optarg); case 'S': sconly=1; break; default: break; } } if (optind >= argc) { printf("Which files do you want to play?\n"); exit(0); } //init_consoles(); /* Initialize framebuffer */ fbdev = open("/dev/fb0", O_RDWR); if (fbdev < 0) { fprintf(stderr, "error while opening framebuffer.\n"); exit(fbdev); } ioctl(fbdev, FBIOGET_VSCREENINFO, &var); mng->fbwidth = var.xres; mng->fbheight = var.yres; mng->fbbpp = var.bits_per_pixel; mng->display = mmap(NULL, var.xres * var.yres * (var.bits_per_pixel >> 3), PROT_WRITE | PROT_READ, MAP_SHARED, fbdev, 0); /* arrange to call the shutdown routine before we exit */ atexit(&cleanup); while (optind < argc) { // leftover arguements are filenames. mng->filename = argv[optind++]; /* set up the mng decoder for our stream */ mng->mng = mng_initialize(mng, mngalloc, mngfree, MNG_NULL); if (mng->mng == MNG_NULL) { fprintf(stderr, "could not initialize libmng.\n"); exit(1); } /* set the callbacks */ mng_setcb_errorproc(mng->mng, mngerror); mng_setcb_openstream(mng->mng, mngopenstream); mng_setcb_closestream(mng->mng, mngclosestream); mng_setcb_readdata(mng->mng, mngreadstream); mng_setcb_gettickcount(mng->mng, mnggetticks); mng_setcb_settimer(mng->mng, mngsettimer); mng_setcb_processheader(mng->mng, mngprocessheader); mng_setcb_getcanvasline(mng->mng, mnggetcanvasline); mng_setcb_refresh(mng->mng, mngrefresh); /* FIXME: should check for errors here */ signal(SIGINT, sigint_handler); signal(SIGTERM, sigterm_handler); mng_readdisplay(mng->mng); /* loop though the frames */ while (mng->delay && run) { mdelay(mng->delay); mng->delay = 0; mng_display_resume(mng->mng); if (run == 2) { if (mng->alpha == 0) run = 0; mng->alpha -= delta; if (mng->alpha < 0) mng->alpha = 0; } } if (waitsignal && optind < argc) { signal(SIGUSR1, sigusr1_handler); run = 1; while (run) { sleep(2); } } memset(mng->copybuffer, 0, 4 * mng->width * mng->height); run = 1; mng->alpha = alpha; if (optind == argc) { /* last file */ restore_area(); } } /* cleanup and quit */ return mngquit(mng->mng); }
int fixit (char * zFilenameI, char * zFilenameO) { userdatap pMydata; mng_retcode iRC; /* get a data buffer */ pMydata = (userdatap)calloc (1, sizeof (userdata)); if (pMydata == NULL) /* oke ? */ { fprintf (stderr, "Cannot allocate a data buffer.\n"); return 1; } pMydata->hFileO = 0; /* initialize some stuff! */ pMydata->hHandleI = MNG_NULL; pMydata->hHandleO = MNG_NULL; pMydata->bHasSAVE = MNG_FALSE; pMydata->bHasTERM = MNG_FALSE; pMydata->bIsJASC = MNG_TRUE; pMydata->iLastchunk = MNG_UINT_HUH; pMydata->iTermaction = 0; pMydata->iIteraction = 0; pMydata->iDelay = 0; pMydata->iItermax = 0; /* can we open the input file ? */ if ((pMydata->hFileI = fopen (zFilenameI, "rb")) == NULL) { /* error out if we can't */ fprintf (stderr, "Cannot open input file %s.\n", zFilenameI); return 1; } /* let's initialize the library */ pMydata->hHandleI = mng_initialize ((mng_ptr)pMydata, myalloc, myfree, MNG_NULL); if (!pMydata->hHandleI) /* did that work out ? */ { fprintf (stderr, "Cannot initialize libmng.\n"); iRC = 1; } else { /* some informatory messages */ fprintf (stderr, "Compiled with libmng %s.\n", MNG_VERSION_TEXT); fprintf (stderr, "Running with libmng %s.\n", mng_version_text()); /* setup callbacks */ if ( ((iRC = mng_setcb_openstream (pMydata->hHandleI, myopenstream )) != 0) || ((iRC = mng_setcb_closestream (pMydata->hHandleI, myclosestream )) != 0) || ((iRC = mng_setcb_readdata (pMydata->hHandleI, myreaddata )) != 0) || ((iRC = mng_setcb_errorproc (pMydata->hHandleI, myprocesserror)) != 0) ) fprintf (stderr, "Cannot set callbacks for libmng.\n"); else { /* reaad the file into memory */ if ((iRC = mng_read (pMydata->hHandleI)) != 0) fprintf (stderr, "Cannot read the input file.\n"); else { /* run through the chunk list to get TERM */ if ((iRC = mng_iterate_chunks (pMydata->hHandleI, 0, myiterchunk)) != 0) fprintf (stderr, "Cannot iterate the chunks.\n"); else { if (pMydata->iError) /* did the iteration fail somehow ? */ iRC = pMydata->iError; else { /* can we open the output file ? */ if ((pMydata->hFileO = fopen (zFilenameO, "wb")) == NULL) { /* error out if we can't */ fprintf (stderr, "Cannot open output file %s.\n", zFilenameO); iRC = 1; } else { /* let's initialize the library */ pMydata->hHandleO = mng_initialize ((mng_ptr)pMydata, myalloc, myfree, MNG_NULL); if (!pMydata->hHandleO) /* did that work out ? */ { fprintf (stderr, "Cannot initialize libmng.\n"); iRC = 1; } else { /* setup callbacks */ if ( ((iRC = mng_setcb_openstream (pMydata->hHandleO, myopenstream )) != 0) || ((iRC = mng_setcb_closestream (pMydata->hHandleO, myclosestream)) != 0) || ((iRC = mng_setcb_writedata (pMydata->hHandleO, mywritedata )) != 0) ) fprintf (stderr, "Cannot set callbacks for libmng.\n"); else { if ((iRC = mng_create (pMydata->hHandleO)) != 0) fprintf (stderr, "Cannot create a new MNG.\n"); else { /* run through the chunk again and create the new file */ if ((iRC = mng_iterate_chunks (pMydata->hHandleI, 0, myiterchunk)) != 0) fprintf (stderr, "Cannot iterate the chunks.\n"); else { /* did the iteration fail somehow ? */ if (pMydata->iError) iRC = pMydata->iError; else { /* now write the created new file !! */ if ((iRC = mng_write (pMydata->hHandleO)) != 0) fprintf (stderr, "Cannot write the output file.\n"); } } } } /* cleanup the library */ mng_cleanup (&pMydata->hHandleO); } /* cleanup output file */ fclose (pMydata->hFileO); } } } } } mng_cleanup (&pMydata->hHandleI); /* cleanup the library */ } fclose (pMydata->hFileI); /* cleanup input file and userdata */ free (pMydata); return iRC; }
/** * @brief write buffered frames to MNG file * @return 0 on success, 1 on error */ static int vomng_write_file(void) { FILE *file; mng_handle mng; struct vomng_frame *frame; unsigned int frames, duration_ms; int first; /* refuse to create empty MNG file */ if (!vomng.frame_first || !vomng.frame_last) { mp_msg(MSGT_VO, MSGL_ERR, "vomng: not creating empty file\n"); return 1; } /* create output file */ file = fopen(vomng.out_file_name, "wb"); if (!file) { mp_msg(MSGT_VO, MSGL_ERR, "vomng: could not open output file \"%s\": %s\n", vomng.out_file_name, strerror(errno)); return 1; } /* inititalize MNG library */ mng = mng_initialize(file, vomng_alloc, vomng_free, MNG_NULL); if (!mng) { mp_msg(MSGT_VO, MSGL_ERR, "vomng: could not initialize libmng\n"); fclose(file); return 1; } if (mng_setcb_openstream (mng, vomng_openstream ) || mng_setcb_closestream(mng, vomng_closestream) || mng_setcb_writedata (mng, vomng_writedata )) { mp_msg(MSGT_VO, MSGL_ERR, "vomng: cannot set callbacks for libmng\n"); mng_cleanup(&mng); fclose(file); return 1; } /* create new MNG image in memory */ if (mng_create(mng)) { mp_msg(MSGT_VO, MSGL_ERR, "vomng: cannot create MNG image in memory\n"); mng_cleanup(&mng); fclose(file); return 1; } /* determine number of frames and total duration */ frames = 0; for (frame = vomng.frame_first; frame; frame = frame->next) frames++; duration_ms = vomng.frame_last->time_ms - vomng.frame_first->time_ms; /* write MNG header chunks */ if (mng_putchunk_mhdr(mng, vomng.width, /* dimensions */ vomng.height, 1000, 0, /* ticks per second, layer */ frames, /* number of frames */ duration_ms, /* total duration */ MNG_SIMPLICITY_VALID | MNG_SIMPLICITY_SIMPLEFEATURES | MNG_SIMPLICITY_COMPLEXFEATURES) || mng_putchunk_save(mng, MNG_TRUE, 0, 0) || /* empty save chunk */ mng_putchunk_term(mng, MNG_TERMACTION_CLEAR, /* show last frame forever */ MNG_ITERACTION_CLEAR, 0, 0)) { mp_msg(MSGT_VO, MSGL_ERR, "vomng: writing MHDR/SAVE/TERM chunks failed\n"); mng_write(mng); /* write out buffered chunks before cleanup */ mng_cleanup(&mng); fclose(file); return 1; } /* write frames */ first = 1; for (frame = vomng.frame_first; frame; frame = frame->next) { if (vomng_write_frame(frame, mng, vomng.width, vomng.height, first)) break; first = 0; } if (frame) { mp_msg(MSGT_VO, MSGL_ERR, "vomng: writing frames failed\n"); mng_write(mng); /* write out buffered chunks before cleanup */ mng_cleanup(&mng); fclose(file); return 1; } /* write MNG end chunk */ if (mng_putchunk_mend(mng)) { mp_msg(MSGT_VO, MSGL_ERR, "vomng: writing end chunk failed\n"); mng_write(mng); /* write out buffered chunks before cleanup */ mng_cleanup(&mng); fclose(file); return 1; } /* finish and cleanup */ mng_write(mng); /* write out buffered chunks before cleanup */ mng_cleanup(&mng); fclose(file); return 0; }