Here is a code snippet/example of how to decode WebP image and send the image to wxImage.
You also need libwebp, which can be found at https://code.google.com/p/webp/, to able to use this code.
Compile with compiler that support C++11.
Since I'm C++ and wxWidgets beginner my self, any comment of this code will be appreciated.
Hope this will give you some ideas of convert WebP image (may be any image format) to wxImage.
*Note* require this https://github.com/kytulendu/Gw2Browser ... il/Array.h array template (GPLV3) ...
see https://github.com/kytulendu/Gw2Browser ... Reader.cpp for example.
Edit: add missing thing.
Edit2: fix NULL to nullptr, remove license.
Edit3: cleanup
Edit4: fix memory leak?
Code: Select all
/*
WebP to wxImage code snippet
by Khral Steelforge
usage: [WebP]->readWebP( );
return wxImage.
*/
struct RGBA {
unsigned int r;
unsigned int g;
unsigned int b;
unsigned int a;
};
struct RGB {
unsigned int r;
unsigned int g;
unsigned int b;
};
wxImage foo::readWebP( ) const {
// Create image
wxImage image;
auto data = reinterpret_cast<const uint8_t*>( m_data.GetPointer( ) );
size_t data_size = m_data.GetSize( );
po_colors = nullptr;
po_alphas = nullptr;
WebPDecoderConfig config;
WebPBitstreamFeatures* bitstream = &config.input;
VP8StatusCode status = VP8_STATUS_OK;
status = WebPGetFeatures( reinterpret_cast<const uint8_t*>( data ), data_size, bitstream );
if ( status != VP8_STATUS_OK ) {
wxMessageBox( wxString( "This file isn't WebP!" ), _( "" ), wxOK | wxICON_EXCLAMATION );
return image;
}
if ( bitstream->has_animation ) {
wxMessageBox( wxString( "Not support Animation WebP." ), _( "" ), wxOK | wxICON_INFORMATION );
return image;
}
uint numPixels = bitstream->width * bitstream->height;
// Why it need to convert RGB to BGR?
auto decoded_data = reinterpret_cast<BGRA*>( WebPDecodeRGBA( data, data_size, nullptr, nullptr ) );
if ( decoded_data == nullptr ) {
wxMessageBox( wxString( "Invalid WebP format." ), _( "ERROR" ), wxOK | wxICON_ERROR );
return image;
}
//auto colors = allocate<RGB>( numPixels );
auto colors = static_cast<RGB*>( ::malloc( numPixels * sizeof( RGB ) ) );
//auto alphas = allocate<uint8_t>( numPixels );
auto alphas = static_cast<uint8_t*>( ::malloc( numPixels * sizeof( uint8_t ) ) );
#pragma omp parallel for // comment this out if it give you compile error or you don't want to use OpenMP
for ( int y = 0; y < static_cast<int>( bitstream->height ); y++ ) {
uint32 curPixel = ( y * bitstream->width );
for ( uint x = 0; x < static_cast<unsigned int>( bitstream->width ); x++ ) {
::memcpy( &po_colors[curPixel].b, &decoded_data[curPixel].b, sizeof( po_colors[curPixel].b ) );
::memcpy( &po_colors[curPixel].g, &decoded_data[curPixel].g, sizeof( po_colors[curPixel].g ) );
::memcpy( &po_colors[curPixel].r, &decoded_data[curPixel].r, sizeof( po_colors[curPixel].r ) );
if ( bitstream->has_alpha ) {
::memcpy( &po_alphas[curPixel], &decoded_data[curPixel].a, sizeof( po_alphas[curPixel] ) );
}
curPixel++;
}
}
freePointer( decoded_data );
image = wxImage( bitstream->width, bitstream->height, reinterpret_cast<uint8_t*>( colors ), false );
// Set alpha if the format has any
if ( output_buffer->colorspace == bitstream->has_alpha ) {
image.SetAlpha( alphas );
}
return image;
}