Advertisement
Guest User

Untitled

a guest
Jan 20th, 2019
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.94 KB | None | 0 0
  1.  
  2. #ifndef _BITMAP_H
  3. #define _BITMAP_H
  4.  
  5. #include <iostream>
  6. #include <cstdio>
  7. #include <string>
  8.  
  9. using namespace std;
  10.  
  11. const short BITMAP_MAGIC_NUMBER=19778;
  12. const int RGB_BYTE_SIZE=3;
  13.  
  14. #pragma pack(push,bitmap_data,1)
  15.  
  16. typedef struct tagRGBQuad {
  17. char rgbBlue;
  18. char rgbGreen;
  19. char rgbRed;
  20. char rgbReserved;
  21. } __attribute__ ((packed)) RGBQuad;
  22.  
  23. typedef struct tagBitmapFileHeader {
  24. unsigned short bfType;
  25. unsigned int bfSize;
  26. unsigned short bfReserved1;
  27. unsigned short bfReserved2;
  28. unsigned int bfOffBits;
  29. } __attribute__ ((packed)) BitmapFileHeader;
  30.  
  31. typedef struct tagBitmapInfoHeader {
  32. unsigned int biSize;
  33. int biWidth;
  34. int biHeight;
  35. unsigned short biPlanes;
  36. unsigned short biBitCount;
  37. unsigned int biCompression;
  38. unsigned int biSizeImage;
  39. int biXPelsPerMeter;
  40. int biYPelsPerMeter;
  41. unsigned int biClrUsed;
  42. unsigned int biClrImportant;
  43. } __attribute__ ((packed)) BitmapInfoHeader;
  44.  
  45. #pragma pack(pop,bitmap_data)
  46.  
  47. class Bitmap {
  48. public:
  49. //variables
  50. RGBQuad *colours;
  51. char *data;
  52. bool loaded;
  53. int width,height;
  54. unsigned short bpp;
  55. string error;
  56. //methods
  57. Bitmap(void);
  58. Bitmap(char *);
  59. ~Bitmap();
  60. bool loadBMP(char *);
  61. private:
  62. //variables
  63. BitmapFileHeader bmfh;
  64. BitmapInfoHeader bmih;
  65. int byteWidth; //the width in bytes of the image
  66. int padWidth; //the width in bytes of the added image
  67. unsigned int dataSize; //size of the data in the file
  68. //methods
  69. void reset(void);
  70. bool convert24(char *); //convert to 24bit RGB bottom up data
  71. bool convert8(char *); //convert to 24bit RGB bottom up data
  72. };
  73.  
  74. #endif //_BITMAP_H
  75.  
  76. //basic constructor
  77. Bitmap::Bitmap(){
  78. reset();
  79. }
  80.  
  81. //constructor loads the bitmap when it is created
  82. Bitmap::Bitmap(char *file){
  83. reset();
  84. loadBMP(file);
  85. }
  86.  
  87. //destructor
  88. Bitmap::~Bitmap(){
  89. if(colours!=0) {
  90. delete[] colours;
  91. }
  92. if(data!=0) {
  93. delete[] data;
  94. }
  95. }
  96.  
  97. //load a bitmap from a file and represent it correctly
  98. //in memory
  99. bool Bitmap::loadBMP(char *file) {
  100. FILE *in; //file stream for reading
  101. char *tempData; //temp storage for image data
  102. int numColours; //total available colours
  103.  
  104. //bitmap is not loaded yet
  105. loaded=false;
  106. //make sure memory is not lost
  107. if(colours!=0) {
  108. delete[] colours;
  109. }
  110. if(data!=0) {
  111. delete[] data;
  112. }
  113.  
  114. //open the file for reading in binary mode
  115. in=fopen(file,"rb");
  116.  
  117. //if the file does not exist return in error
  118. if(in==NULL) {
  119. error="File not found";
  120. fclose(in);
  121. return false;
  122. }
  123.  
  124. //read in the entire BITMAPFILEHEADER
  125. fread(&bmfh,sizeof(BitmapFileHeader),1,in);
  126. cout << "sizeof(BitmapFileHeader)=" << sizeof(BitmapFileHeader) << endl;
  127. //check for the magic number that says this is a bitmap
  128. if(bmfh.bfType!=BITMAP_MAGIC_NUMBER) {
  129. error="File is not in DIB format";
  130. fclose(in);
  131. return false;
  132. }
  133.  
  134. //read in the entire BITMAPINFOHEADER
  135. fread(&bmih,sizeof(BitmapInfoHeader),1,in);
  136. cout << "sizeof(BitmapInfoHeader)=" << sizeof(BitmapInfoHeader) << endl;
  137.  
  138. //save the width, height and bits per pixel for external use
  139. width=bmih.biWidth;
  140. height=bmih.biHeight;
  141. bpp=bmih.biBitCount;
  142. cout << "biBitCount =" << bmih.biBitCount << endl;
  143. cout << "biClrImportant =" << bmih.biClrImportant << endl;
  144. cout << "biClrUsed =" << bmih.biClrUsed << endl;
  145. cout << "biCompression =" << bmih.biCompression << endl;
  146. cout << "biHeight =" << bmih.biHeight << endl;
  147. cout << "biPlanes =" << bmih.biPlanes << endl;
  148. cout << "biSize =" << bmih.biSize << endl;
  149. cout << "biSizeImage =" << bmih.biSizeImage << endl;
  150. cout << "biWidth =" << bmih.biWidth << endl;
  151. cout << "biXPelsPerMeter =" << bmih.biXPelsPerMeter << endl;
  152. cout << "biYPelsPerMeter =" << bmih.biYPelsPerMeter << endl;
  153.  
  154. //calculate the size of the image data with padding
  155. dataSize=(width*height*(unsigned int)(bmih.biBitCount/8.0));
  156.  
  157. //calculate the number of available colours
  158. numColours=1<<bmih.biBitCount;
  159.  
  160. //if the bitmap is not 8 bits per pixel or more
  161. //return in error
  162. if(bpp<8) {
  163. error="File is not 8 or 24 bits per pixel";
  164. fclose(in);
  165. return false;
  166. }
  167.  
  168. //load the palette for 8 bits per pixel
  169. if(bpp==8) {
  170. colours=new RGBQuad[numColours];
  171. fread(colours,sizeof(RGBQuad),numColours,in);
  172. }
  173.  
  174. //set up the temporary buffer for the image data
  175. tempData=new char[dataSize];
  176.  
  177. //exit if there is not enough memory
  178. if(tempData==NULL) {
  179. error="Not enough memory to allocate a temporary buffer";
  180. fclose(in);
  181. return false;
  182. }
  183.  
  184. //read in the entire image
  185. fread(tempData,sizeof(char),dataSize,in);
  186.  
  187. //close the file now that we have all the info
  188. fclose(in);
  189.  
  190. //calculate the witdh of the final image in bytes
  191. byteWidth=padWidth=(int)((float)width*(float)bpp/8.0);
  192.  
  193. //adjust the width for padding as necessary
  194. while(padWidth%4!=0) {
  195. padWidth++;
  196. }
  197.  
  198. //change format from GBR to RGB
  199. if(bpp==8) {
  200. loaded=convert8(tempData);
  201. }
  202. else if(bpp==24) {
  203. loaded=convert24(tempData);
  204. }
  205.  
  206. //clean up memory
  207. delete[] tempData;
  208.  
  209. //bitmap is now loaded
  210. error="Bitmap loaded";
  211.  
  212. //return success
  213. return loaded;
  214. }
  215.  
  216. //function to set the inital values
  217. void Bitmap::reset(void) {
  218. loaded=false;
  219. colours=0;
  220. data=0;
  221. error="";
  222. }
  223.  
  224. bool Bitmap::convert24(char* tempData) {
  225. int offset,diff;
  226.  
  227. diff=width*height*RGB_BYTE_SIZE;
  228. //allocate the buffer for the final image data
  229. data=new char[diff];
  230.  
  231. //exit if there is not enough memory
  232. if(data==NULL) {
  233. error="Not enough memory to allocate an image buffer";
  234. delete[] data;
  235. return false;
  236. }
  237.  
  238. if(height>0) {
  239. offset=padWidth-byteWidth;
  240. //count backwards so you start at the front of the image
  241. for(int i=0;i<dataSize;i+=3) {
  242. //jump over the padding at the start of a new line
  243. if((i+1)%padWidth==0) {
  244. i+=offset;
  245. }
  246. //transfer the data
  247. *(data+i+2)=*(tempData+i);
  248. *(data+i+1)=*(tempData+i+1);
  249. *(data+i)=*(tempData+i+2);
  250. }
  251. }
  252.  
  253. //image parser for a forward image
  254. else {
  255. offset=padWidth-byteWidth;
  256. int j=dataSize-3;
  257. //count backwards so you start at the front of the image
  258. //here you can start from the back of the file or the front,
  259. //after the header The only problem is that some programs
  260. //will pad not only the data, but also the file size to
  261. //be divisible by 4 bytes.
  262. for(int i=0;i<dataSize;i+=3) {
  263. //jump over the padding at the start of a new line
  264. if((i+1)%padWidth==0) {
  265. i+=offset;
  266. }
  267. //transfer the data
  268. *(data+j+2)=*(tempData+i);
  269. *(data+j+1)=*(tempData+i+1);
  270. *(data+j)=*(tempData+i+2);
  271. j-=3;
  272. }
  273. }
  274.  
  275. return true;
  276. }
  277.  
  278. bool Bitmap::convert8(char* tempData) {
  279. int offset,diff;
  280.  
  281. diff=width*height*RGB_BYTE_SIZE;
  282. //allocate the buffer for the final image data
  283. data=new char[diff];
  284.  
  285. //exit if there is not enough memory
  286. if(data==NULL) {
  287. error="Not enough memory to allocate an image buffer";
  288. delete[] data;
  289. return false;
  290. }
  291.  
  292. if(height>0) {
  293. offset=padWidth-byteWidth;
  294. int j=0;
  295. //count backwards so you start at the front of the image
  296. for(int i=0;i<dataSize*RGB_BYTE_SIZE;i+=3) {
  297. //jump over the padding at the start of a new line
  298. if((i+1)%padWidth==0) {
  299. i+=offset;
  300. }
  301. //transfer the data
  302. *(data+i)=colours[*(tempData+j)].rgbRed;
  303. *(data+i+1)=colours[*(tempData+j)].rgbGreen;
  304. *(data+i+2)=colours[*(tempData+j)].rgbBlue;
  305. j++;
  306. }
  307. }
  308.  
  309. //image parser for a forward image
  310. else {
  311. offset=padWidth-byteWidth;
  312. int j=dataSize-1;
  313. //count backwards so you start at the front of the image
  314. for(int i=0;i<dataSize*RGB_BYTE_SIZE;i+=3) {
  315. //jump over the padding at the start of a new line
  316. if((i+1)%padWidth==0) {
  317. i+=offset;
  318. }
  319. //transfer the data
  320. *(data+i)=colours[*(tempData+j)].rgbRed;
  321. *(data+i+1)=colours[*(tempData+j)].rgbGreen;
  322. *(data+i+2)=colours[*(tempData+j)].rgbBlue;
  323. j--;
  324. }
  325. }
  326.  
  327. return true;
  328. }
  329.  
  330. int main()
  331. {
  332.  
  333. // Odczytanie bitmapy
  334. Bitmap *tex = new Bitmap();
  335. if (!tex->loadBMP("kot.bmp")) {
  336. printf("fukcup\n");
  337. return -1;
  338. }
  339.  
  340. return 0;
  341. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement