std::vector<gimg::colorRGB24> ImportPaletteFromBMP( const std::string & filepath ) { std::vector<gimg::colorRGB24> outpal; BMP input; input.ReadFromFile( filepath.c_str() ); const unsigned int nbColors = static_cast<unsigned int>( ( input.TellNumberOfColors() > 0 )? input.TellNumberOfColors() : 0 ); if( nbColors == 0 ) throw runtime_error("ERROR: BMP image being imported has an invalid palette!"); outpal.resize( nbColors ); for( unsigned int i = 0; i < nbColors; ++i ) { RGBApixel acolor = input.GetColor(i); outpal[i].red = acolor.Red; outpal[i].green = acolor.Green; outpal[i].blue = acolor.Blue; //Alpha is ignored } return std::move(outpal); }
bool ImportBMP( _TImg_t & out_timg, const std::string & filepath, unsigned int forcedwidth, unsigned int forcedheight, bool erroronwrongres ) { //The max nb of colors possible with that bitdepth! static const unsigned int NB_Colors_Support = utils::do_exponent_of_2_<_TImg_t::pixel_t::mypixeltrait_t::BITS_PER_PIXEL>::value; bool hasWarnedOORPixel = false; //Whether we warned about out of range pixels at least once during the pixel loop! If applicable.. bool isWrongResolution = false; BMP input; auto & outpal = out_timg.getPalette(); input.ReadFromFile( filepath.c_str() ); if( input.TellBitDepth() != _TImg_t::pixel_t::GetBitsPerPixel() ) { //We don't support anything with a different bitdepth! //Mention the palette length mismatch cerr <<"\n<!>-ERROR: The file : " <<filepath <<", is not a " <<_TImg_t::pixel_t::GetBitsPerPixel() <<"bpp indexed bmp ! Its in fact " <<input.TellBitDepth() <<"bpp!\n" <<"Make sure the bmp file is saved as " <<_TImg_t::pixel_t::GetBitsPerPixel() <<"bpp, " <<NB_Colors_Support << " colors!\n"; return false; } //Only force resolution when we were asked to! if( forcedwidth != 0 && forcedheight != 0 ) isWrongResolution = input.TellWidth() != forcedwidth || input.TellHeight() != forcedheight; if( erroronwrongres && isWrongResolution ) { cerr <<"\n<!>-ERROR: The file : " <<filepath <<" has an unexpected resolution!\n" <<" Expected :" <<forcedwidth <<"x" <<forcedheight <<", and got " <<input.TellWidth() <<"x" <<input.TellHeight() <<"! Skipping!\n"; return false; } if( utils::LibraryWide::getInstance().Data().isVerboseOn() && input.TellNumberOfColors() <= NB_Colors_Support ) { //Mention the palette length mismatch cerr <<"\n<!>-Warning: " <<filepath <<" has a different palette length than expected!\n" <<"Fixing and continuing happily..\n"; } out_timg.setNbColors( NB_Colors_Support ); //Build palette const unsigned int nbColors = static_cast<unsigned int>( ( input.TellNumberOfColors() > 0 )? input.TellNumberOfColors() : 0 ); if( nbColors == 0 ) throw runtime_error("ERROR: BMP image being imported has an invalid palette!"); for( unsigned int i = 0; i < nbColors; ++i ) { RGBApixel acolor = input.GetColor(i); outpal[i].red = acolor.Red; outpal[i].green = acolor.Green; outpal[i].blue = acolor.Blue; //Alpha is ignored } //Image Resolution int tiledwidth = (forcedwidth != 0)? forcedwidth : input.TellWidth(); int tiledheight = (forcedheight != 0)? forcedheight : input.TellHeight(); //Make sure the height and width are divisible by the size of the tiles! if( tiledwidth % _TImg_t::tile_t::WIDTH ) tiledwidth = CalcClosestHighestDenominator( tiledwidth, _TImg_t::tile_t::WIDTH ); if( tiledheight % _TImg_t::tile_t::HEIGHT ) tiledheight = CalcClosestHighestDenominator( tiledheight, _TImg_t::tile_t::HEIGHT ); //Resize target image out_timg.setPixelResolution( tiledwidth, tiledheight ); //If the image we read is not divisible by the dimension of our tiles, // we have to ensure that we won't got out of bound while copying! int maxCopyWidth = out_timg.getNbPixelWidth(); int maxCopyHeight = out_timg.getNbPixelHeight(); if( maxCopyWidth != input.TellWidth() || maxCopyHeight != input.TellHeight() ) { //Take the smallest resolution, so we don't go out of bound! maxCopyWidth = std::min( input.TellWidth(), maxCopyWidth ); maxCopyHeight = std::min( input.TellHeight(), maxCopyHeight ); } //Copy pixels over for( int i = 0; i < maxCopyWidth; ++i ) { for( int j = 0; j < maxCopyHeight; ++j ) { RGBApixel apixel = input.GetPixel(i,j); //First we need to find out what index the color is.. gimg::colorRGB24::colordata_t colorindex = FindIndexForColor( apixel, outpal ); if( !hasWarnedOORPixel && colorindex == -1 ) { //We got a problem cerr <<"\n<!>-Warning: Image " <<filepath <<", has pixels with colors that aren't in the colormap/palette!\n" <<"Defaulting pixels out of range to color 0!\n"; hasWarnedOORPixel = true; colorindex = 0; } out_timg.getPixel( i, j ) = colorindex; } } return true; }