/* * Copyright (c) 2004, 2005. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Image.h" #include "BmpFile.h" #include #include // -------------------- all includes must go before these lines ------------------ #if defined(DEBUG) && defined(WIN32) && !defined(NO_MFC) #include #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif // -------------------- all code must go after these lines ----------------------- // ================> begin local functions (available only to this translation unit) namespace { using namespace blepo; /** Returns the number of bytes needed to hold an image with the given width, height, and bit depth, assuming that the rows are double-word aligned. @param width Width of image @param height Height of image @param nbits Number of bits per pixel */ size_t dwAlignSize(int width, int height, int nbits) { assert(width>=0 && height>=0 && nbits>=0); return (height * ((((width*nbits) + 0x1F) & ~0x1F)>>3)); } //LoadBMP will NOT work for compressed BMP imgaes!! void LoadBmp(const char* fname, ImgBgr* out) { unsigned int width, height; BYTE* data_ptr = BMPFile::LoadBMP(fname,&width,&height); //Memory for data_ptr is cretaed in this function. We must clean up memory later!! assert(data_ptr); BYTE* data_ptr_temp = data_ptr; out->Reset(width, height); ImgBgr::Iterator imgbgr_ptr; //Converting from RGB to BGR format for (imgbgr_ptr = out->Begin() ; imgbgr_ptr != out->End() ; imgbgr_ptr++) { imgbgr_ptr->r = *data_ptr++; imgbgr_ptr->g = *data_ptr++; imgbgr_ptr->b = *data_ptr++; } delete[] data_ptr_temp; } }; // ================< end local functions namespace blepo { // ImgBgr const int ImgBgr::NBITS_PER_PIXEL = 24; const int ImgBgr::NCHANNELS = 3; const ImgBgr::PixelType ImgBgr::MIN_VAL = Bgr(0,0,0); const ImgBgr::PixelType ImgBgr::MAX_VAL = Bgr(0xFF, 0xFF, 0xFF); /** Load/Save functions. @author Prashant Oswal */ void Load(const char* fname, ImgBgr* out) { const char char_bmp[] = "BM"; char data[5]; { // Determine file type FILE* fp; long result; fp = fopen(fname,"rb"); if (fp==NULL) { assert(0); // BLEPO_ERROR(StringEx("Unable to open file '%s'", fname)); } result=fread(data,1,4,fp); //read magic characters if (result==0) { assert(0); // BLEPO_ERROR("Error reading file"); } data[4]='\0'; fclose(fp); } if(strnicmp(data,char_bmp,strlen(char_bmp))==0) { LoadBmp(fname,out); } else { assert(0); // BLEPO_ERROR("Filetype not supported"); } } void Draw(const ImgBgr& img, CDC& dc, int x, int y) { Draw(img, dc.m_hDC, x, y); } void Draw(const ImgBgr& img, CDC& dc, const CRect& src, const CRect& dst) { Draw(img, dc.m_hDC, src, dst); } void Draw(const ImgBgr& img, HDC hdc, int x, int y) { Draw(img, hdc, CRect(0, 0, img.Width(), img.Height()), CRect(x, y, x+img.Width(), y+img.Height())); } void Draw(const ImgBgr& img, HDC hdc, const CRect& src, const CRect& dst) { int width = img.Width(); int height = img.Height(); int nbits_per_pixel = ImgBgr::NBITS_PER_PIXEL; int nbytes = dwAlignSize(width, height, nbits_per_pixel); BITMAPINFO bmi; BITMAPINFOHEADER* bh = &(bmi.bmiHeader); bh->biSize = sizeof(BITMAPINFOHEADER); bh->biWidth = width; bh->biHeight = -height; // negative sign indicates top-down (right-side-up) bh->biPlanes = 1; bh->biBitCount = (WORD) nbits_per_pixel; bh->biCompression = BI_RGB; bh->biSizeImage = nbytes; bh->biXPelsPerMeter = 0; bh->biYPelsPerMeter = 0; bh->biClrUsed = 0; bh->biClrImportant = 0; const unsigned char* data_ptr; std::vector data; if (nbytes == width * height * 3) { data_ptr = reinterpret_cast(img.Begin()); } else { // align data to match expectations of StretchDIBBits data.resize(nbytes); ImgBgr::ConstIterator pi = img.Begin(); for (int y=0 ; y