/** ** 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; }
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(); }
/** ** 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; }
mng_retcode mng_render_proportional(mng_handle mngh, int progress) { mng_anim *mng = mng_get_userdata(mngh); mng_retcode ret = MNG_NOERROR; int frame_num, current_frame; frame_num = ((progress * mng->num_frames) / FBSPL_PROGRESS_MAX) + 1; if (!mng->displayed_first) { ret = mng_display(mngh); mng->displayed_first = 1; } if (mng->num_frames == 0 && mng->displayed_first) return MNG_NOERROR; if (frame_num > mng->num_frames) frame_num = mng->num_frames; current_frame = mng_get_currentframe(mngh); if (current_frame == frame_num) return ret; /* Don't bother freezing if the next frame is just n+1. mng_display_resume * will do this case by default, and it saves us from the horrid hack * below. */ if (frame_num != current_frame + 1) { mng_display_freeze(mngh); /* XXX: hack! workaround what seems to be a bug in libmng - it won't * actually repaint the canvas if you wind an animation "forwards" * using goframe, only backwards, so go to the end of the animation first. */ mng_display_goframe(mngh, mng->num_frames); if (frame_num != mng->num_frames) mng_display_goframe(mngh, frame_num); } ret = mng_display_resume(mngh); if (ret == MNG_NEEDTIMERWAIT || ret == MNG_NOERROR) return ret; print_mng_error(mngh, "mng_display failed"); return ret; }
bool CMNGAnimation::ReadNextFrame(RGBA* frame_buffer) { if (m_first_display) { mng_display(m_stream); m_first_display = false; } else { if (mng_display_resume(m_stream) != MNG_NEEDTIMERWAIT) { mng_display_reset(m_stream); // repeat } } // convert the buffers into frame_buffer memcpy(frame_buffer, m_frame_buffer, m_width * m_height * sizeof(RGBA)); return true; }
mng_retcode mng_render_next(mng_handle mngh) { mng_anim *mng = mng_get_userdata(mngh); mng_retcode ret; int last_frame = 0; /* last_frame = mng_get_currentframe(mngh) == mng->num_frames; FIXME */ if (!mng->displayed_first) { ret = mng_display(mngh); if (ret == MNG_NOERROR || ret == MNG_NEEDTIMERWAIT) mng->displayed_first = 1; } else ret = mng_display_resume(mngh); if (last_frame) return MNG_NOERROR; if (ret == MNG_NEEDTIMERWAIT || ret == MNG_NOERROR) return ret; print_mng_error(mngh, "mng_display failed"); return ret; }
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; }
/** * \brief MPlayer callback: Fill buffer from MNG stream. * \param[in] demuxer demuxer structure * \param[in] ds demuxer stream * \return \p 1 on success, \p 0 on error */ static int demux_mng_fill_buffer(demuxer_t * demuxer, demux_stream_t * ds) { mng_priv_t * mng_priv = demuxer->priv; mng_handle h_mng = mng_priv->h_mng; mng_retcode mng_ret; demux_packet_t * dp; // exit if animation is finished if (mng_priv->finished) return 0; // advance animation to requested next show time while (mng_priv->anim_cur_time_ms + mng_priv->anim_frame_duration_ms <= mng_priv->show_next_time_ms && !mng_priv->finished) { // advance global and animation time mng_priv->global_time_ms += mng_priv->anim_frame_duration_ms; mng_priv->anim_cur_time_ms += mng_priv->anim_frame_duration_ms; // Clear variable MNG library will write number of milliseconds to // (via settimer callback). mng_priv->timer_ms = 0; // get next image from MNG library if (mng_priv->displaying) mng_ret = mng_display_resume(h_mng); // resume displaying MNG data // to canvas else mng_ret = mng_display(h_mng); // start displaying MNG data to canvas if (mng_ret && mng_ret != MNG_NEEDTIMERWAIT) { mp_msg(MSGT_DEMUX, MSGL_ERR, "demux_mng: could not display MNG data to canvas: " "mng_retcode %d\n", mng_ret); return 0; } mng_priv->displaying = 1; // mng_display() has been called now mng_priv->finished = mng_ret == 0; // animation is finished iff // mng_display() returned 0 // save current frame duration mng_priv->anim_frame_duration_ms = mng_priv->timer_ms < 1 ? 1 : mng_priv->timer_ms; } // while (mng_priv->anim_cur_time_ms + ... // create a new demuxer packet dp = new_demux_packet(mng_priv->height * mng_priv->width * 4); // copy image data into demuxer packet memcpy(dp->buffer, mng_priv->canvas, mng_priv->height * mng_priv->width * 4); // set current show time to requested show time mng_priv->show_cur_time_ms = mng_priv->show_next_time_ms; // get time of next frame to show mng_priv->show_next_time_ms = mng_priv->anim_cur_time_ms + mng_priv->anim_frame_duration_ms; // Set position and timing information in demuxer video and demuxer packet. // - Time must be time of next frame and always be > 0 for the variable // frame time mechanism (GIF, MATROSKA, MNG) in video.c to work. demuxer->video->dpos++; dp->pts = (float)mng_priv->show_next_time_ms / 1000.0f + MNG_START_PTS; dp->pos = stream_tell(demuxer->stream); ds_add_packet(demuxer->video, dp); return 1; }
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; }
gboolean gtk_mng_view_load_mng_from_memory (GtkMngView * mng_view, guchar * data_to_eat, guint data_size) { FUNCTION_ENTRY(); guint available_mng_food; g_return_val_if_fail (IS_GTK_MNG_VIEW (mng_view), FALSE); g_return_val_if_fail (data_size > 27, FALSE); g_return_val_if_fail (data_to_eat != NULL, FALSE); //if (data_to_eat[0] != 0x8a || // data_to_eat[1] != 'M' || // data_to_eat[2] != 'N' || // data_to_eat[3] != 'G' || // data_to_eat[4] != 0x0d || // data_to_eat[5] != 0x0a || // data_to_eat[6] != 0x1a || // data_to_eat[7] != 0x0a) //{ // g_warning ("not mng format"); // FUNCTION_EXIT(); // return FALSE; //} if (gtk_mng_view_init_libmng (mng_view)) { mng_view->bytes_to_eat = data_size; mng_view->bytes_eaten = 0; mng_view->mng_food = data_to_eat; //if (mng_read (mng_view->MNG_handle) != MNG_NOERROR) { available_mng_food = mng_view->bytes_to_eat - mng_view->bytes_eaten; if (available_mng_food > 0 && mng_view->mng_food != NULL) { //* bytes_read = (mng_uint32) MIN ((mng_uint32) available_mng_food, bytes_requested); //memcpy (buffer, mng_view->mng_food + mng_view->bytes_eaten, * bytes_read); //printf("available_mng_food %d\n", available_mng_food); mng_read_pushdata (mng_view->MNG_handle, mng_view->mng_food, available_mng_food, MNG_FALSE); //mng_read_resume(mng_view->MNG_handle); //mng_view->bytes_eaten += * bytes_read; FUNCTION_EXIT(); return MNG_TRUE; } g_warning ("libmng read error"); mng_cleanup (&mng_view->MNG_handle); FUNCTION_EXIT(); return FALSE; } // else { FUNCTION_EXIT(); return mng_display (mng_view->MNG_handle); // } } else { g_warning ("error initializing libmng"); FUNCTION_EXIT(); return FALSE; } FUNCTION_EXIT(); return TRUE; }
/** ** Reset a MNG */ void Mng::Reset() { mng_display_reset(handle); iteration = 0; mng_display(handle); }