Exemple #1
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 #2
0
/**
 * @brief write frame to MNG file
 * @param[in] *frame the frame to write to MNG file
 * @param[in] mng libmng handle
 * @param[in] width width of canvas
 * @param[in] height height of canvas
 * @param[in] first_frame if the frame is the first one in the file
 * @return 0 on success, 1 on error
 */
static int vomng_write_frame(struct vomng_frame *frame, mng_handle mng,
                             unsigned int width, unsigned int height,
                             int first_frame)
{
    unsigned int delay_ms;

    /* determine delay */
    if (frame->next)
        delay_ms = frame->next->time_ms - frame->time_ms;
    else
        delay_ms = VOMNG_DEFAULT_DELAY_MS; /* default delay for last frame */

    /* write frame headers to MNG file */
    if (mng_putchunk_seek(mng, 0, MNG_NULL)) {
        mp_msg(MSGT_VO, MSGL_ERR, "vomng: writing SEEK chunk failed\n");
        return 1;
    }
    if (mng_putchunk_fram(mng, MNG_FALSE,
                          /* keep canvas if not 1st frame */
                          first_frame ? MNG_FRAMINGMODE_1
                                      : MNG_FRAMINGMODE_NOCHANGE,
                          0, MNG_NULL,              /* no frame name */
                          MNG_CHANGEDELAY_DEFAULT,  /* change only delay */
                          MNG_CHANGETIMOUT_NO,
                          MNG_CHANGECLIPPING_NO,
                          MNG_CHANGESYNCID_NO,
                          delay_ms,                 /* new delay */
                          0,                        /* no new timeout */
                          0, 0, 0, 0, 0,            /* no new boundary */
                          0, 0)) {                  /* no count, no IDs */
        mp_msg(MSGT_VO, MSGL_ERR, "vomng: writing FRAM chunk failed\n");
        return 1;
    }
    if (mng_putchunk_defi(mng, 0,                   /* no ID */
                          MNG_DONOTSHOW_VISIBLE,
                          MNG_ABSTRACT,
                          MNG_TRUE, 0, 0,           /* top left location */
                          MNG_FALSE, 0, 0, 0, 0)) { /* no clipping */
        mp_msg(MSGT_VO, MSGL_ERR, "vomng: writing DEFI chunk failed\n");
        return 1;
    }
    if (mng_putchunk_ihdr(mng, width, height,       /* dimensions */
                          8, MNG_COLORTYPE_RGB,     /* RBG */
                          MNG_COMPRESSION_DEFLATE,
                          MNG_FILTER_ADAPTIVE,
                          MNG_INTERLACE_NONE)) {
        mp_msg(MSGT_VO, MSGL_ERR, "vomng: writing IHDR chunk failed\n");
        return 1;
    }

    /* write frame data */
    if (mng_putchunk_idat(mng, frame->len, frame->data)) {
        mp_msg(MSGT_VO, MSGL_ERR, "vomng: writing IDAT chunk failed\n");
        return 1;
    }

    /* write frame footers to MNG file */
    if (mng_putchunk_iend(mng)) {
        mp_msg(MSGT_VO, MSGL_ERR, "vomng: writing IEND chunk failed\n");
        return 1;
    }

    return 0;
}