static DFBResult
Construct( IDirectFBImageProvider *thiz,
           ... )
{
     DFBResult ret = DFB_FAILURE;
     IDirectFBDataBuffer *buffer;
     CoreDFB             *core;
     va_list              tag;

     DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_MPEG2)

     va_start( tag, thiz );
     buffer = va_arg( tag, IDirectFBDataBuffer * );
     core = va_arg( tag, CoreDFB * );
     va_end( tag );
       
     data->base.ref    = 1;
     data->base.buffer = buffer;
     data->core   = core;

     /* Increase the data buffer reference counter. */
     buffer->AddRef( buffer );

     /* Initialize mpeg2 decoding. */
     data->dec = MPEG2_Init( mpeg2_read_func, buffer, &data->width, &data->height );
     if (!data->dec)
          goto error;

     data->stage = STAGE_INFO;

     /* Allocate image data. */
     data->image = D_MALLOC( data->width * data->height * 4 );
     if (!data->image)
          goto error;

     data->stage = STAGE_IMAGE;

     data->base.Destruct = IDirectFBImageProvider_MPEG2_Destruct;

     thiz->RenderTo = IDirectFBImageProvider_MPEG2_RenderTo;
     thiz->SetRenderCallback = IDirectFBImageProvider_MPEG2_SetRenderCallback;
     thiz->GetImageDescription = IDirectFBImageProvider_MPEG2_GetImageDescription;
     thiz->GetSurfaceDescription =
                              IDirectFBImageProvider_MPEG2_GetSurfaceDescription;

     return DFB_OK;

error:
     if (data->dec)
          MPEG2_Close(data->dec);

     buffer->Release( buffer );

     DIRECT_DEALLOCATE_INTERFACE(thiz);

     return ret;
}
DFBResult
ICore_Real::CreateImageProvider(
                    u32                                        buffer_call,
                    u32                                       *ret_call
)
{
     DFBResult               ret;
     IDirectFBDataBuffer    *buffer;
     IDirectFBImageProvider *provider;
     ImageProviderDispatch  *dispatch;

     D_DEBUG_AT( DirectFB_CoreDFB, "ICore_Real::%s()\n", __FUNCTION__ );

     D_MAGIC_ASSERT( obj, CoreDFB );
     D_ASSERT( ret_call != NULL );

     DIRECT_ALLOCATE_INTERFACE( buffer, IDirectFBDataBuffer );
     if (!buffer)
          return (DFBResult) D_OOM();

     /* Construct data buffer client */
     ret = IDirectFBDataBuffer_Client_Construct( buffer, core, buffer_call );
     if (ret)
          return ret;

     /* Create image provider */
     ret = buffer->CreateImageProvider( buffer, &provider );
     if (ret) {
          buffer->Release( buffer );
          return ret;
     }

     /* Create dispatch object */
     ret = ImageProviderDispatch_Create( idirectfb_singleton, buffer, provider, &dispatch );
     if (ret) {
          provider->Release( provider );
          buffer->Release( buffer );
          return ret;
     }

     *ret_call = dispatch->call.call_id;

     return DFB_OK;
}
static DFBResult
Construct( IDirectFBImageProvider *thiz,
           ... )
{
     IDirectFBDataBuffer *buffer;
     CoreDFB             *core;
     va_list              tag;

     DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_GIF)

     va_start( tag, thiz );
     buffer = va_arg( tag, IDirectFBDataBuffer * );
     core = va_arg( tag, CoreDFB * );
     va_end( tag );

     data->base.ref = 1;

     data->base.buffer = buffer;
     data->base.core = core;

     buffer->AddRef( buffer );

     data->GrayScale   = -1;
     data->transparent = -1;
     data->delayTime   = -1;

     data->image = ReadGIF( data, 1, &data->image_width, &data->image_height,
                            &data->image_transparency, &data->image_colorkey,
                            true, false );

     buffer->Release( buffer );
     data->base.buffer = NULL;

     if (!data->image ||
         (data->image_height == 0) ||
         (data->image_width  == 0) ) {
          DIRECT_DEALLOCATE_INTERFACE( thiz );
          return DFB_FAILURE;
     }

     data->base.Destruct = IDirectFBImageProvider_GIF_Destruct;

     thiz->RenderTo = IDirectFBImageProvider_GIF_RenderTo;
     thiz->GetImageDescription = IDirectFBImageProvider_GIF_GetImageDescription;
     thiz->GetSurfaceDescription =
                               IDirectFBImageProvider_GIF_GetSurfaceDescription;

     return DFB_OK;
}
static DFBResult
Construct( IDirectFBImageProvider *thiz,
           ... )
{
     DFBResult ret = DFB_FAILURE;

     IDirectFBDataBuffer *buffer;
     CoreDFB             *core;
     va_list              tag;

     DIRECT_ALLOCATE_INTERFACE_DATA(thiz, IDirectFBImageProvider_PNG)

     va_start( tag, thiz );
     buffer = va_arg( tag, IDirectFBDataBuffer * );
     core = va_arg( tag, CoreDFB * );
     va_end( tag );

     data->ref    = 1;
     data->buffer = buffer;
     data->core   = core;

     /* Increase the data buffer reference counter. */
     buffer->AddRef( buffer );

     /* Create the PNG read handle. */
     data->png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING,
                                             NULL, NULL, NULL );
     if (!data->png_ptr)
          goto error;

     if (setjmp( data->png_ptr->jmpbuf )) {
          D_ERROR( "ImageProvider/PNG: Error reading header!\n" );
          goto error;
     }

     /* Create the PNG info handle. */
     data->info_ptr = png_create_info_struct( data->png_ptr );
     if (!data->info_ptr)
          goto error;

     /* Setup progressive image loading. */
     png_set_progressive_read_fn( data->png_ptr, data,
                                  png_info_callback,
                                  png_row_callback,
                                  png_end_callback );


     /* Read until info callback is called. */
     ret = push_data_until_stage( data, STAGE_INFO, 64 );
     if (ret)
          goto error;

     thiz->AddRef                = IDirectFBImageProvider_PNG_AddRef;
     thiz->Release               = IDirectFBImageProvider_PNG_Release;
     thiz->RenderTo              = IDirectFBImageProvider_PNG_RenderTo;
     thiz->SetRenderCallback     = IDirectFBImageProvider_PNG_SetRenderCallback;
     thiz->GetImageDescription   = IDirectFBImageProvider_PNG_GetImageDescription;
     thiz->GetSurfaceDescription = IDirectFBImageProvider_PNG_GetSurfaceDescription;

     return DFB_OK;

error:
     if (data->png_ptr)
          png_destroy_read_struct( &data->png_ptr, &data->info_ptr, NULL );

     buffer->Release( buffer );

     if (data->image)
          D_FREE( data->image );

     DIRECT_DEALLOCATE_INTERFACE(thiz);

     return ret;
}