// imageLoader.cpp : Defines the entry point for the console application. // #include #include #include #include #include #include using namespace std; class RGBpixel { public: unsigned char r,g,b; RGBpixel() { r = g = b = 255; } RGBpixel(unsigned char r, unsigned char g, unsigned char b) { this->r = r; this->g = g; this->b = b; } friend bool operator==(const RGBpixel &left, const RGBpixel &right) { return left.r == right.r && left.g == right.g && left.b == right.b; } friend const RGBpixel operator+(const RGBpixel &left, const RGBpixel &right) { int c[3] = { left.r + right.r, left.g + right.g, left.b + right.b }; for (int i = 0; i < 3; i++) { if (c[i] > 255) c[i] = 255; } RGBpixel sum(c[0], c[1], c[2]); return sum; } friend const RGBpixel operator-(const RGBpixel &left, const RGBpixel &right) { int c[3] = { left.r - right.r, left.g - right.g, left.b - right.b }; for (int i = 0; i < 3; i++) { if (c[i] < 0) c[i] = 0; } RGBpixel sum(c[0], c[1], c[2]); return sum; } }; class RGBimage { private: public: RGBpixel **map; char *data; int w; int h; RGBimage(int w, int h) { this->w = w; this->h = h; map = new RGBpixel*[h]; for (int i = 0; i < h; i++) { map[i] = new RGBpixel[w]; } } virtual ~RGBimage(); void fill_data(); void draw(); }; RGBimage::~RGBimage() { for (int i = 0; i < h; i++) { delete [] map[i]; } delete [] map; delete [] data; } void RGBimage::fill_data() { int k = 0; while ((w + k)%4) k++; data = new char[h*(w + k)*3]; for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { int index = (i + j*(w + k))*3; data[index + 0] = map[j][i].r; data[index + 1] = map[j][i].g; data[index + 2] = map[j][i].b; } } } void RGBimage::draw() { fill_data(); glDrawPixels(w, h, GL_RGB, GL_UNSIGNED_BYTE, data); //for (int i = 0; i < k; i++) data[h*(w + k)] } typedef unsigned short ushort; typedef unsigned long ulong; typedef unsigned short WORD; typedef unsigned long DWORD; #pragma pack(push, 1) typedef struct bmpFileHeader { WORD bfType; // смещение 0 байт от начала файла DWORD bfSize; // смещение 2 байта от начала файла, длина 4 байта WORD bfReserved1; WORD bfReserved2; DWORD bfOffBits; // смещение 10 байт от начала файла, длина 4 байта } BMPFILEHEADER; typedef struct bmpInfoHeader { DWORD biSize; int biWidth; int biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; } BMPINFOHEADER; #pragma pack(pop) class BMPimage { private: void form_image(); public: string name; bmpFileHeader file_header; bmpInfoHeader info_header; RGBpixel *map; char *char_map; RGBimage *image; BMPimage() { name = ""; } virtual ~BMPimage(); BMPimage(string fname) { loadBmp(fname); } void loadBmp(string fname); }; BMPimage::~BMPimage() { delete [] map; delete [] char_map; delete image; } void BMPimage::form_image() { int w = info_header.biWidth; int h = info_header.biHeight; int k = 0; while ((w + k)%4) k++; image = new RGBimage(w, h); for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { int index = (i + j*(w + k))*3; image->map[j][i].b = char_map[index]; image->map[j][i].g = char_map[index + 1]; image->map[j][i].r = char_map[index + 2]; } } } void BMPimage::loadBmp(string fname) { FILE *pFile; pFile = fopen (fname.c_str(), "r"); if (pFile!=NULL) { fread((void*)&file_header, sizeof(bmpFileHeader), 1, pFile); fread((void*)&info_header, sizeof(bmpInfoHeader), 1, pFile); int w = info_header.biWidth; int h = info_header.biHeight; int offset = file_header.bfOffBits - sizeof(bmpFileHeader) - sizeof(bmpInfoHeader); char dummy; for (int i = 0; i < offset; i++) fread((void*)&dummy, sizeof(char), 1, pFile); //printf("ptr = %d\n", ptr); map = new RGBpixel[w*h]; for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { fread((void*)&map[i+j*w], sizeof(RGBpixel), 1, pFile); char t = map[i+j*w].r; map[i+j*w].r = map[i+j*w].b, map[i+j*w].b = t; for (int k = 0; k < (4 - (w*3)%4)%4; k++) fread((void*)&dummy, sizeof(char), 1, pFile); } } fseek ( pFile , file_header.bfOffBits , SEEK_SET ); while (w % 4 != 0) w++; char_map = new char[w*h*3]; //for (int i = 0; i < w*h*3; i++) { fread((void*)char_map, sizeof(char), w*h*3+4, pFile); //} fclose (pFile); form_image(); } else { cout << "cannot open file for reading!" << endl; } }