void encode(string infile, string outfile, string payload) { BMP input; if(!input.ReadFromFile(infile.c_str())) { cout << "The Bitmap doesn\'t exist!" << endl; return; } int msglength = payload.length() * 2; if(msglength > input.TellWidth() * input.TellHeight()) { cout << "That message is too large for that image! (" << msglength << " as opposed to " << input.TellWidth() * input.TellHeight() << "; " << input.TellWidth() << " * " << input.TellHeight() << ")"<<endl; return; } stringstream msglength_ss; msglength_ss << setfill('0') << setw(8) << hex << msglength; string msglength_str = msglength_ss.str(); uchar msgLength_split[8]; for(uint i = 0; i < msglength_str.length(); i++) { msgLength_split[i] = (uchar)single_char_to_int(msglength_str[i]); } char* payload_split = new char[payload.length() * 2]; for(uint i = 0; i < payload.length() * 2 - 1; i+=2) { payload_split[i] = payload[i / 2] >> 4; payload_split[i + 1] = payload[i/ 2] & 0x0F; } RGBApixel pix; for(int x = 0; x < 8; x++) { pix = input.GetPixel(x, 0); pix.Blue &= 0xF0; pix.Blue += msgLength_split[x]; input.SetPixel(x, 0, pix); } for(int y = 0; y < input.TellHeight(); y++) { for(int x = 0; x < input.TellWidth(); x++) { if(y == 0 && x < 8) continue; pix = input.GetPixel(x, y); if(payload.length() * 2 > (uint)input.TellWidth() * y + x - 8) { pix.Blue &= 0xF0; pix.Blue += payload_split[input.TellWidth() * y + x - 8]; } input.SetPixel(x, y, pix); } } fclose(fopen(outfile.c_str(),"w")); input.WriteToFile(outfile.c_str()); delete[] payload_split; }
/** @function Get4Pixels16Bit reads four consecutive pixels of the specified row started from given column and writes they to the two registers out_BG and out_RA. Uses 16 bit per channel @param in_img is a input image @param in_row_idx is an index of a row to read pixels @param in_col_idx ia an index of a column with a first pixel @param out_BG is a pointer to a 128bit register to store blue and green channels for the pixels four consecutive pixels in format BBBB GGGG. Order of pixels is [0, 1, 2, 3] @param out_RA is a pointer to a 128bit register to store red and alpha channels for the pixels four consecutive pixels in format RRRR AAAA. Order of pixels is [0, 1, 2, 3] */ inline void Get4Pixels16Bit(BMP &in_img, int in_row_idx, int in_col_idx, __m128i *out_BG, __m128i *out_RA) { // read four consecutive pixels RGBApixel pixel0 = in_img.GetPixel(in_col_idx, in_row_idx); RGBApixel pixel1 = in_img.GetPixel(in_col_idx + 1, in_row_idx); RGBApixel pixel2 = in_img.GetPixel(in_col_idx + 2, in_row_idx); RGBApixel pixel3 = in_img.GetPixel(in_col_idx + 3, in_row_idx); // write two pixel0 and pixel2 to the p02 and other to the p13 __m128i p02 = _mm_setr_epi32(*(reinterpret_cast<int*>(&pixel0)), *(reinterpret_cast<int*>(&pixel2)), 0, 0); __m128i p13 = _mm_setr_epi32(*(reinterpret_cast<int*>(&pixel1)), *(reinterpret_cast<int*>(&pixel3)), 0, 0); /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * convert BGRA BGRA BGRA BGRA * to BBBB GGGG RRRR AAAA * order of pixels corresponds to the digits in the name of variables ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ // BGRA BGRA 0000 0000 + BGRA BGRA 0000 0000 -> BBGG RRAA BBGG RRAA __m128i p0123 = _mm_unpacklo_epi8(p02, p13); // extract BBGG RRAA 0000 0000 of pixel2 and pixel3 __m128i p23xx = _mm_unpackhi_epi64(p0123, _mm_setzero_si128()); // BBGG RRAA XXXX XXXX + BBGG RRAA 0000 0000 -> BBBB GGGG RRRR AAAA // X denotes unused characters __m128i p0123_8bit = _mm_unpacklo_epi16(p0123, p23xx); // extend to 16bit *out_BG = _mm_unpacklo_epi8(p0123_8bit, _mm_setzero_si128()); *out_RA = _mm_unpackhi_epi8(p0123_8bit, _mm_setzero_si128()); }
Color Sphere::calculateTextureFromMaterial(Point intercept, bool diagnosticEnabled) { BMP* texture; texture = &this->texture; int height = texture->TellHeight(); int width = texture->TellWidth(); Vector vectorToIntercept = intercept - origin; vectorToIntercept.normalize(); double u = 0.5 + atan2(vectorToIntercept.z,vectorToIntercept.x) / 2 / 3.1415; double v = 0.5 - asin(vectorToIntercept.y) / 3.1415; int pixelX = abs((int)(u * width)); int pixelY = abs((int)(v * height)); pixelX %= width; pixelY %= height; Color matColor; if(diagnosticEnabled) { matColor = Color(v,0,sin(u * 3.1415)); } else { matColor.r = texture->GetPixel(pixelX,pixelY).Red/255.f; matColor.g = texture->GetPixel(pixelX,pixelY).Green/255.f; matColor.b = texture->GetPixel(pixelX,pixelY).Blue/255.f; } return matColor; }
void tile(BMP& Input, BMP& Output) { if (Input.TellHeight() == 1) { Output.SetPixel(Output.TellWidth() - 1, 0, Input.GetPixel(0, 0)); } else { BMP* ScaledInput = new BMP(Input); Rescale(*ScaledInput, 'p', 50); // SW quadrant RangedPixelToPixelCopy(*ScaledInput, 0, ScaledInput -> TellWidth(), 0, ScaledInput -> TellHeight(), Output, Output.TellWidth() - 2 * ScaledInput -> TellWidth(), ScaledInput -> TellHeight()); // NE quadrant tile(*ScaledInput, Output); // NW quadrant RangedPixelToPixelCopy(Output, Output.TellWidth() - ScaledInput -> TellWidth(), Output.TellWidth() - ScaledInput -> TellWidth() / 2 - 1, 0, ScaledInput -> TellHeight() - 1, Output, Output.TellWidth() - 2 * ScaledInput -> TellWidth(), 0); RangedPixelToPixelCopy(Output, Output.TellWidth() - ScaledInput -> TellWidth(), Output.TellWidth() - ScaledInput -> TellWidth() / 2 - 1, 0, ScaledInput -> TellHeight() - 1, Output, Output.TellWidth() - 3 * ScaledInput -> TellWidth() / 2, 0); // SE quadrant RangedPixelToPixelCopy(Output, Output.TellWidth() - ScaledInput -> TellWidth(), Output.TellWidth() - 1, ScaledInput -> TellHeight() / 2, ScaledInput -> TellHeight() - 1, Output, Output.TellWidth() - ScaledInput -> TellWidth(), ScaledInput -> TellHeight()); RangedPixelToPixelCopy(Output, Output.TellWidth() - ScaledInput -> TellWidth(), Output.TellWidth() - 1, ScaledInput -> TellHeight() / 2, ScaledInput -> TellHeight() - 1, Output, Output.TellWidth() - ScaledInput -> TellWidth(), 3 * ScaledInput -> TellHeight() / 2); } }
bool Image::readFromBMPFile(const std::string & inputFileName) { bool success = true; // use BMP object to read image BMP inputImage; success = inputImage.ReadFromFile(inputFileName.c_str() ); if( success ) { // allocate memory for image (deleting old, if exists) m_numRows = inputImage.TellHeight(); m_numCols = inputImage.TellWidth(); if( m_pixels != NULL ) // deallocate old memory { delete [] m_pixels; } m_pixels = new double[m_numRows * m_numCols]; // copy pixels for( int r = 0; r < m_numRows; ++r ) { for( int c = 0; c < m_numCols; ++c ) { RGBApixel pixelVal = inputImage.GetPixel(c, r); double val = (double) pixelVal.Blue + (double) pixelVal.Green + (double) pixelVal.Red; val = (val / 3.0 + 0.5); m_pixels[r * m_numCols + c] = val; } } } return success; }
unsigned int loadImage(const char * fname) { if ( ! fname ) { return 0; } BMP bmp; if ( ! bmp.ReadFromFile(fname) ) { printf( "not loaded : %s\n",fname ); return 0; } int w = bmp.TellWidth(); int h = bmp.TellHeight(); int d = bmp.TellBitDepth() / 8; RGBApixel* pix = bmp(0,0); char bytes[0x7ffff], *b=bytes; for ( int j=0; j<h; j++ ) { for ( int i=0; i<w; i++ ) { RGBApixel pix = bmp.GetPixel(i, j); *b++ = pix.Red; *b++ = pix.Green; *b++ = pix.Blue; if ( d == 4 ) *b++ = pix.Alpha; } } size_t i = RGL::texCreate( w, h, d, bytes, true );; printf( "created : %d [%d %d %d] %s\n", i, w,h,d,fname ); return i; }
string decode(string infile) { BMP input; if(!input.ReadFromFile(infile.c_str())) { cout << "The input file didn't exist!" << endl; return ""; } stringstream ret; int count = 0; char currentChar; RGBApixel pix; int msgLength = 0; stringstream msglength_ss; for(int x = 0; x < 8; x++) { pix = input.GetPixel(x, 0); msglength_ss << hex << (ushort)(pix.Blue & 0x0F); } msgLength = strtol(msglength_ss.str().c_str(), NULL, 16); for(int y = 0; y < input.TellHeight(); y++) { for(int x = 0; x < input.TellWidth(); x++) { if(input.TellWidth() * y + x - 8 > msgLength) goto end; if(y == 0 && x < 8) continue; pix = input.GetPixel(x, y); if(count % 2 == 0) { // Begin new Char currentChar = pix.Blue & 0x0F; } else { // Add to current char currentChar <<= 4; currentChar += pix.Blue & 0x0F; ret << currentChar; } count++; } } end: return ret.str(); }
int rowMatch (BMP& UseTop, BMP& UseBottom ) { // Compares the top edge of UseTop to the bottom edge of UseBottom. // Assumes UseTop and UseBottom are squares of same size // score obtained by adding the difference between color components int rowSize = UseTop.TellWidth(); int total = 0; RGBApixel pixelTop; RGBApixel pixelBottom; for (int i = 0; i < rowSize; i++) { pixelTop = UseTop.GetPixel(i, 0); pixelBottom = UseBottom.GetPixel(i, rowSize - 1); total += abs(pixelTop.Red - pixelBottom.Red) + abs(pixelTop.Green - pixelBottom.Green) + abs(pixelTop.Blue - pixelBottom.Blue); } return total; }
void copy(BMP & InImg, BMP & OutImg, int xPos, int yPos) { // copy image to larger final picture so that the InImg is placed in row i, column j of OutImg int width = InImg.TellWidth(); RGBApixel curPixel; for (int i = 0; i < width; i++) { for (int j = 0; j < width; j++) { curPixel = InImg.GetPixel(i, j); OutImg.SetPixel(xPos * width + i, yPos * width + j, curPixel); } } }
int columnMatch ( BMP& UseLeft, BMP& UseRight ) { // Compares the left edge of UseLeft to the right edge of UseRight. // Assumes UseRight and UseLeft are squares of same size // score obtained by adding the difference between color components // similar to the rowMatch int columnSize = UseLeft.TellWidth(); int total = 0; RGBApixel pixelLeft; RGBApixel pixelRight; for (int i = 0; i < columnSize; i++) { pixelLeft = UseLeft.GetPixel(0,i); pixelRight = UseRight.GetPixel(columnSize - 1, i); total += abs(pixelLeft.Red - pixelRight.Red) + abs(pixelLeft.Green - pixelRight.Green) + abs(pixelLeft.Blue - pixelRight.Blue); } return total; }
void BMP2graydata(BMP& bmp, unsigned char* data){ int k=0; int width =bmp.TellWidth(); int height=bmp.TellHeight(); for (int i=0; i<height; i++){ for (int j=0; j<width; j++){ RGBApixel pix=bmp.GetPixel(j,i ); data[k++]=pix.Blue; //src[k++]= 0.2126 * pix.Red + 0.7152 * pix.Green + 0.0722 * pix.Blue; } } }
void CBarBitmapWin32::DrawDigit(int left, int top, char num) { BMP eBmp; LoadFont(IDB_FONT_NUM, eBmp); int leftMargin=8*(num-'0'); for (int i=0; i<8; i++) for (int j=0; j<12; j++) m_bmp->SetPixel(left+i, top+j, eBmp.GetPixel(leftMargin+i, j)); }
static cell AMX_NATIVE_CALL n_FSetPixelRGBA( AMX* amx, cell* params ){ posx = params[1]; posy = params[2]; RGBApixel value; value.Red = (ebmpBYTE)params[4]; value.Green = (ebmpBYTE)params[5]; value.Blue = (ebmpBYTE)params[6]; value.Alpha = (ebmpBYTE)params[7]; GlobalImage.SetBitDepth(24); GlobalImage.GetPixel(posx,posy); GlobalImage.SetPixel(posx,posy,value); return 1; }
static cell AMX_NATIVE_CALL n_SetPixelRGBA( AMX* amx, cell* params ){ amx_StrParam(amx,params[1],tmp); BMP Image; posx = params[2]; posy = params[3]; Image.ReadFromFile(tmp); RGBApixel value; value.Red = (ebmpBYTE)params[4]; value.Green = (ebmpBYTE)params[5]; value.Blue = (ebmpBYTE)params[6]; value.Alpha = (ebmpBYTE)params[7]; Image.SetBitDepth(24); Image.GetPixel(posx,posy); Image.SetPixel(posx,posy,value); return Image.WriteToFile(tmp); }
QImage fromBMP(QString &file) { QImage errImg; BMP tarBMP; if(!tarBMP.ReadFromFile( file.toLocal8Bit().data() )){ //WriteToLog(QtCriticalMsg, QString("Error: File does not exsist")); return errImg; //Check if empty with errImg.isNull(); } QImage bmpImg(tarBMP.TellWidth(),tarBMP.TellHeight(),QImage::Format_RGB666); for(int x = 0; x < tarBMP.TellWidth(); x++){ for(int y = 0; y < tarBMP.TellHeight(); y++){ RGBApixel pixAt = tarBMP.GetPixel(x,y); bmpImg.setPixel(x,y,qRgb(pixAt.Red, pixAt.Green, pixAt.Blue)); } } return bmpImg; }
int main(int argc, char** argv){ #ifdef __APPLE__ // Needed in OSX to force use of OpenGL3.2 glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2); glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #endif // Set up pathtracer stuff bool loadedScene = false; finishedRender = false; targetFrame = 0; singleFrameMode = false; // Load scene file for(int i=1; i<argc; i++){ string header; string data; istringstream liness(argv[i]); getline(liness, header, '='); getline(liness, data, '='); if(strcmp(header.c_str(), "scene")==0){ renderScene = new scene(data); loadedScene = true; }else if(strcmp(header.c_str(), "frame")==0){ targetFrame = atoi(data.c_str()); singleFrameMode = true; } } if(!loadedScene){ cout << "Error: scene file needed!" << endl; return 0; } // Set up camera stuff from loaded pathtracer settings iterations = 0; renderCam = &renderScene->renderCam; parameterSet = &renderScene->parameterSet; width = renderCam->resolution[0]; height = renderCam->resolution[1]; textures=new m_BMP[renderScene->bmps.size()]; int i,j,k; for(i=0;i<renderScene->bmps.size();i++) { //int w=renderScene->bmps[i]->Width; //int h=renderScene->bmps[i]->Height; BMP now; now.ReadFromFile(renderScene->bmps[i].c_str()); int h=now.TellHeight();int w=now.TellWidth(); textures[i].resolution=glm::vec2(w,h); textures[i].colors=new glm::vec3[w*h]; for(j=0;j<w;j++)for(k=0;k<h;k++) { RGBApixel current=now.GetPixel(j,k); textures[i].colors[j*h+k]=glm::vec3(current.Red,current.Green,current.Blue)*(1.0f/255.0f); } } if(targetFrame>=renderCam->frames){ cout << "Warning: Specified target frame is out of range, defaulting to frame 0." << endl; targetFrame = 0; } // Launch CUDA/GL #ifdef __APPLE__ init(); #else init(argc, argv); #endif initCuda(); initVAO(); initTextures(); GLuint passthroughProgram; passthroughProgram = initShader("shaders/passthroughVS.glsl", "shaders/passthroughFS.glsl"); glUseProgram(passthroughProgram); glActiveTexture(GL_TEXTURE0); starttime=clock(); #ifdef __APPLE__ // send into GLFW main loop while(1){ display(); if (glfwGetKey(GLFW_KEY_ESC) == GLFW_PRESS || !glfwGetWindowParam( GLFW_OPENED )){ exit(0); } } glfwTerminate(); #else glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMainLoop(); #endif return 0; }
SbXipImage* SoXipLoadBMP::loadBMP(const char *fileName) { try { BMP bmp; bmp.ReadFromFile(fileName); int numBits = bmp.TellBitDepth(); int width = bmp.TellWidth(); int height = bmp.TellHeight(); int bitsStored = 8; int samplesPerPixel = 0; SbXipImage::ComponentType compType = SbXipImage::INTERLEAVED; SbXipImage::ComponentLayoutType compLayoutType = SbXipImage::RGB; if(numBits<=24) { samplesPerPixel = 3; compLayoutType = SbXipImage::RGB; } else if(numBits == 32) { samplesPerPixel = 4; compLayoutType = SbXipImage::RGBA; } SbVec3f pos(0, 0, 0); SbVec3f scale(width, height, 1); SbMatrix rotMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1); SbMatrix modelMatrix; modelMatrix.setScale(scale); //modelMatrix.setTransform(pos, SbRotation(rotMatrix), scale); SbXipImage *image = new SbXipImage(SbXipImageDimensions(width, height, 1), SbXipImageDimensions(width, height, 1), SbXipImage::UNSIGNED_BYTE, bitsStored, samplesPerPixel, compType, compLayoutType, modelMatrix); unsigned char *buffer = (unsigned char *) image->refBufferPtr(); if(numBits<=24) { for(int i = 0; i < height; i++) { for(int j = 0; j < width; j++) { RGBApixel pixel = bmp.GetPixel(j,(height -1) - i ); buffer[3*i*width+3*j] = pixel.Red; buffer[3*i*width+3*j+1] = pixel.Green; buffer[3*i*width+3*j+2] = pixel.Blue; } } } else if(numBits == 32) { for(int i=0; i<height; i++) { for(int j=0; j<width; j++) { RGBApixel pixel = bmp.GetPixel(j, height-i); buffer[4*i*width+4*j] = pixel.Red; buffer[4*i*width+4*j+1] = pixel.Green; buffer[4*i*width+4*j+2] = pixel.Blue; buffer[4*i*width+4*j+3] = pixel.Alpha; } } } image->unrefBufferPtr(); return image; } catch(...) { SoDebugError::postInfo(__FILE__, "Exception loadBMP"); // Fix me need to delete allocated memory! return 0; } }
/** @function toGrayScale utilizes SSE to realize fast approach to convert RGBA image to grayscale. It is faster than toGrayScaleSSE, but not so precise @param [in] in_input is an input image. @param [out] out_mat is an output image. Each pixel is represented by a single unsigned char value. */ void toGrayScaleSSE_16BIT(BMP &in_input, MyMat<uchar> &out_mat) { // pointer to the processed row of the result image uchar *row_ptr = out_mat.data; // pointer to the processed element of the result image uchar *elem_ptr; // number of elements to process at a time const int block_size = 8; // number of elements that will not be processed block-wise const int left_cols = out_mat.cols % block_size; // number of elements that will be processed block-wise const int block_cols = out_mat.cols - left_cols; for (size_t row_idx = 0; row_idx < out_mat.rows; ++row_idx) { elem_ptr = row_ptr; // process block_size elements at a time for (int col_idx = 0; col_idx < block_cols; col_idx += block_size) { // read four pixels __m128i BG1; __m128i RA1; Get4Pixels16Bit(in_input, row_idx, col_idx, &BG1, &RA1); // read another four pixels __m128i BG2; __m128i RA2; Get4Pixels16Bit(in_input, row_idx, col_idx + 4, &BG2, &RA2); // extract channels __m128i blue = _mm_unpacklo_epi64(BG1, BG2); __m128i green = _mm_unpackhi_epi64(BG1, BG2); __m128i red = _mm_unpacklo_epi64(RA1, RA2); // multiply channels by weights blue = _mm_mullo_epi16(blue, CONST_BLUE_16_INT); green = _mm_mullo_epi16(green, CONST_GREEN_16_INT); red = _mm_mullo_epi16(red, CONST_RED_16_INT); // sum up channels __m128i color = _mm_add_epi16(red, green); color = _mm_add_epi16(color, blue); // divide by 256 color = _mm_srli_epi16(color, 8); // convert to 8bit color = _mm_packus_epi16(color, _mm_setzero_si128()); // write results to the output image _mm_storel_epi64(reinterpret_cast<__m128i*>(elem_ptr), color); elem_ptr += block_size; } // process left elements in the row for (size_t col_idx = block_cols; col_idx < out_mat.cols; ++col_idx) { RGBApixel pixel = in_input.GetPixel(col_idx, row_idx); short red = 0.2125f * 256, green = 0.7154f * 256, blue = 0.0721f * 256; int carry =(red * pixel.Red + green * pixel.Green + blue * pixel.Blue) / 256; *elem_ptr = static_cast<uchar>(carry); ++elem_ptr; } // go to next row row_ptr += out_mat.step; } }
void CBarBitmapWin32::DrawLetter(int left, int top, char ch) { if (ch==' ') return; BMP eBmp; int topMargin; int width=0; if (ch>='A' && ch<='Z') { LoadFont(IDB_FONT_UPPER, eBmp); topMargin=(ch-'A')*13; switch (ch) { case 69: width=10; break; case 70: width=9; break; case 73: width=6; break; case 74: width=8; break; case 76: width=10; break; case 77: width=16; break; case 80: width=9; break; case 83: width=9; break; case 84: width=10; break; case 87: width=15; break; case 89: width=10; break; case 90: width=9; break; default: width=12; } } else if (ch>='a' && ch<='z') { LoadFont(IDB_FONT_LOWER, eBmp); topMargin=(ch-'a')*13; switch (ch) { case 102: width=5; break; case 105: width=4; break; case 106: width=4; break; case 107: width=9; break; case 108: width=4; break; case 109: width=12; break; case 114: width=6; break; case 115: width=7; break; case 116: width=5; break; case 119: width=10; break; case 122: width=6; break; default: width=8; } } else throw CBarBitmapException("Letter not supported"); for (int i=0; i<width; i++) for (int j=0; j<13; j++) m_bmp->SetPixel(left+i, top+j, eBmp.GetPixel(i, topMargin+j)); }
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; }