Exemple #1
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();
}
Exemple #2
0
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;
}
Exemple #3
0
/**
**  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;
}
Exemple #4
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;
}
Exemple #5
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;
}
Exemple #6
0
//---------------------------------------------------------------------------
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;
}
Exemple #7
0
// 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;
}
Exemple #8
0
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;
}
Exemple #9
0
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);
}
Exemple #10
0
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;
}	
Exemple #11
0
/**
 * \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;
}
Exemple #12
0
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
}
Exemple #13
0
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;
}
Exemple #14
0
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);
}
Exemple #15
0
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;
}
Exemple #16
0
/**
 * @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;
}