#include #include #include #include #include #include "lz4/lz4.h" #include "Bitmap.hpp" #include "Debug.hpp" Bitmap::Bitmap( const char* fn, unsigned int lines, bool bgr ) : m_block( nullptr ) , m_lines( lines ) , m_alpha( true ) , m_sema( 0 ) { FILE* f = fopen( fn, "rb" ); assert( f ); char buf[4]; fread( buf, 1, 4, f ); if( memcmp( buf, "raw4", 4 ) == 0 ) { uint8_t a; fread( &a, 1, 1, f ); m_alpha = a == 1; uint32_t d; fread( &d, 1, 4, f ); m_size.x = d; fread( &d, 1, 4, f ); m_size.y = d; DBGPRINT( "Raw bitmap " << fn << " " << m_size.x << "x" << m_size.y ); assert( m_size.x % 4 == 0 ); assert( m_size.y % 4 == 0 ); int32_t csize; fread( &csize, 1, 4, f ); char* cbuf = new char[csize]; fread( cbuf, 1, csize, f ); fclose( f ); m_block = m_data = new uint32_t[m_size.x*m_size.y]; m_linesLeft = m_size.y / 4; LZ4_decompress_fast( cbuf, (char*)m_data, m_size.x*m_size.y*4 ); delete[] cbuf; for( int i=0; i= m_lines ) { lines = 0; m_sema.unlock(); } } if( lines != 0 ) { m_sema.unlock(); } png_read_end( png_ptr, info_ptr ); png_destroy_read_struct( &png_ptr, &info_ptr, NULL ); fclose( f ); } ); } } Bitmap::Bitmap( const v2i& size ) : m_data( new uint32_t[size.x*size.y] ) , m_block( nullptr ) , m_lines( 1 ) , m_linesLeft( size.y / 4 ) , m_size( size ) , m_sema( 0 ) { } Bitmap::Bitmap( const Bitmap& src, unsigned int lines ) : m_lines( lines ) , m_alpha( src.Alpha() ) , m_sema( 0 ) { } Bitmap::~Bitmap() { delete[] m_data; } void Bitmap::Write( const char* fn ) { FILE* f = fopen( fn, "wb" ); assert( f ); png_structp png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ); png_infop info_ptr = png_create_info_struct( png_ptr ); setjmp( png_jmpbuf( png_ptr ) ); png_init_io( png_ptr, f ); png_set_IHDR( png_ptr, info_ptr, m_size.x, m_size.y, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE ); png_write_info( png_ptr, info_ptr ); uint32_t* ptr = m_data; for( int i=0; i lock( m_lock ); lines = std::min( m_lines, m_linesLeft ); auto ret = m_block; m_sema.lock(); m_block += m_size.x * 4 * lines; m_linesLeft -= lines; done = m_linesLeft == 0; return ret; }