Advertisement
Guest User

BMP.cpp

a guest
Jul 5th, 2012
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. #include "stdio.h"
  3. #include "sys/stat.h"//required for setting file permissions
  4. #include "fcntl.h"//required for setting create/readwrite/read only etc.
  5. #include <cstring>
  6. #include <stdlib.h>
  7. #include <stdint.h>
  8. #include <iostream>
  9. using namespace std;
  10. #include "BMP.h" ///// note for other viewers: doesn't have anything other than function prototypes
  11.  
  12.  
  13. void saveBMP(const char *filepath, OGL_Surface *Surface, int bpp, uint8_t compression)
  14. {
  15.     if (bpp==32 || bpp==4){bpp=24;}//do not support 32bit
  16.     if (bpp==3){bpp=24;}
  17.     int palettecols =0;// (should be included as function arg)
  18.     uint32_t imgbytes = (Surface->w*Surface->h*bpp)/8;
  19.     int padding = (Surface->w*3)%4;
  20.     if (padding != 0){padding=4-padding; imgbytes += Surface->h*padding;}
  21.     uint32_t data = 0;
  22.  
  23.     int file = open(filepath, O_CREAT | O_RDWR, S_IRWXU);
  24.     if (file < 0 ){perror("ERROR CREATING/OPENING BMP FILE");exit(1);}
  25.     lseek(file, 0, SEEK_SET);
  26.  
  27.     /// file header (14 bytes)
  28.     //BitMap declaraction
  29.     write(file, "BM", 2);
  30.     //complete file size in bytes. 14+40 + num bytes for image data  + (palette)
  31.     if (bpp>8){data = imgbytes + 54;}
  32.     else{data = imgbytes + 54 + palettecols*4;}
  33.     write(file, &data, 4);
  34.     //reserved nulls
  35.     data=0;
  36.     write(file, &data, 4);
  37.     //offset to actual pixel data (again 14+40) + (palette)
  38.     if (bpp>8){data=54;}
  39.     else{data = 54 + palettecols*4;}
  40.     write(file, &data, 4);
  41.  
  42.     /// file info (40 bytes)
  43.     //size of info data
  44.     data=40;
  45.     write(file, &data, 4);
  46.     //image width, height
  47.     data=Surface->w;
  48.     write(file, &data, 4);
  49.     data=Surface->h;
  50.     write(file, &data, 4);
  51.     //must be set to 1
  52.     data=1;
  53.     write(file, &data, 2);
  54.     //bits per pixel (MAX 24!)
  55.     data= min(bpp,24);
  56.     write(file, &data, 2);
  57.     //compression, compression notes: http://netghost.narod.ru/gff/vendspec/micbmp/bmp.txt
  58.     data=0;
  59.     write(file, &data, 4);
  60.     //image size in bytes
  61.     data=imgbytes;
  62.     write(file, &data, 4);
  63.     //x,y pixels per meter (set to 0)
  64.     data=0;
  65.     write(file, &data, 4);
  66.     write(file, &data, 4);
  67.  
  68.     /// palette (only for 1,4 and 8 bit images, 4 bytes per colour, min 8 bytes)
  69.     //colours used (0=autodetect from bpp, for 8bpp or less palette will only use the amount of colours)
  70.     write(file, &data, 4);
  71.     //important colours (0=all are important)
  72.     write(file, &data, 4);
  73.     //palette (should be included as function arg)
  74.     uint32_t *palette = NULL;
  75.     uint8_t r,g,b;
  76.     if (bpp<24){
  77.         for (uint8_t i = 0; i<palettecols; i++){
  78.             r=(palette[i]&0x000000FF);
  79.             g=(palette[i]&0x0000FF00)>>8;
  80.             b=(palette[i]&0x00FF0000)>>16;
  81.             write(file, &b, 1);//b
  82.             write(file, &g, 1);//g
  83.             write(file, &r, 1);//r
  84.             write(file, 0, 1);//null
  85.         }
  86.     }
  87.     /// pixeldata
  88.     uint8_t *buffer =  new uint8_t[imgbytes];
  89.     memset(buffer, 0, imgbytes);
  90.     int datawidth = (Surface->w*3)+padding;
  91.     int pos = 0;
  92.     int buf_pos = imgbytes-datawidth;
  93.     for (uint32_t y = 0; y<Surface->h; y++){
  94.         for (uint32_t x = 0; x<Surface->w; x++){
  95.             buffer[buf_pos]  = Surface->PixData[pos];
  96.             buffer[buf_pos+1]= Surface->PixData[pos+1];
  97.             buffer[buf_pos+2]= Surface->PixData[pos+2];
  98.             buf_pos+=3;
  99.             pos+=Surface->bpp;
  100.         }
  101.         //return buffer to start of line then up one line
  102.         buf_pos += padding;
  103.         buf_pos -= datawidth+datawidth;
  104.     }
  105.     write(file, buffer, imgbytes);
  106.     close(file);
  107.     delete [] buffer;
  108. }
  109.  
  110. void loadBMP(const char *filepath, OGL_Surface *Surface)
  111. {
  112.  
  113.     char BMP[3]= {0,0};
  114.     int dataoffset=0;
  115.     int imgbytes=0;
  116.     int compression=0;
  117.     char bpp= 0;
  118.     int file = open(filepath, O_RDONLY, S_IRWXU);
  119.     if (file < 0 ){perror("ERROR LOADING BMP FILE");exit(1);}
  120.  
  121.     /// file header
  122.     //BitMap declaraction
  123.     lseek(file, 0, SEEK_SET);
  124.     read(file, BMP, 2);
  125.     if (BMP[0] != 'B' || BMP[1] != 'M'){printf("UNSUPPORTED FILE TYPE (not BMP)");exit(1);}
  126.     //skip file size, 4
  127.     //skip reserved nulls, 4
  128.     //offset to actual pixel data
  129.     lseek(file, 10, SEEK_SET);
  130.     read(file, &dataoffset, 4);
  131.     //skip headersize, 4
  132.     //width & height
  133.     lseek(file, 18, SEEK_SET);
  134.     read(file, &Surface->w, 4);
  135.     read(file, &Surface->h, 4);
  136.     //skip "planes", 2
  137.     //bits per pixel
  138.     lseek(file, 28, SEEK_SET);
  139.     read(file, &bpp, 2);
  140.     //compression
  141.     read(file, &compression, 4);
  142.     if (compression != 0){printf("FILE USING UNSUPPORTED COMPRESSION");exit(1);}
  143.     //size of image data in bytes
  144.     read(file, &imgbytes, 4);
  145.     //skip hres, 4
  146.     //skip vres, 4
  147.  
  148.     /// palette (only for 1,4 and 8 bit images)
  149.     uint32_t *palette;
  150.     if (bpp<24){
  151.         //colours used
  152.         lseek(file, 46, SEEK_SET);
  153.         int palettecols;
  154.         read(file, &palettecols, 4);
  155.         //skip important colours, 4
  156.         if (palettecols != 0){
  157.             palette = new uint32_t[palettecols];
  158.             memset(palette, 0, palettecols*4);
  159.         }
  160.         for (int i = 0; i<palettecols; i++){
  161.             read(file, &palette[i], 4);
  162.         }
  163.     }
  164.  
  165.     /// pixeldata
  166.     lseek(file, dataoffset, SEEK_SET);
  167.     uint8_t *buffer =  new uint8_t[imgbytes];
  168.     memset(buffer, 0, imgbytes);
  169.     read(file, buffer, imgbytes);
  170.     close(file);
  171.  
  172.     /// convert data to rgb format
  173.     if (Surface->PixData != NULL){delete [] Surface->PixData;}
  174.     Surface->PixData = new uint8_t[Surface->w*Surface->h*Surface->bpp];
  175.     memset(Surface->PixData, 255, Surface->w*Surface->h*Surface->bpp);
  176.     int padding = (Surface->w*3)%4;
  177.     if (padding != 0){padding=4-padding;}
  178.     int datawidth = (Surface->w*3)+padding;
  179.     int pos = 0;
  180.     int buf_pos = imgbytes-datawidth;
  181.     for (uint32_t y = 0; y<Surface->h; y++){
  182.         for (uint32_t x = 0; x<Surface->w; x++){
  183.             Surface->PixData[pos]  = buffer[buf_pos];
  184.             Surface->PixData[pos+1]= buffer[buf_pos+1];
  185.             Surface->PixData[pos+2]= buffer[buf_pos+2];
  186.             //if supporting alpha, set 255,0,255 to transparent
  187.             if(Surface->bpp==4 && buffer[buf_pos] == 255 && buffer[buf_pos+1] == 0 && buffer[buf_pos+2] == 255){Surface->PixData[pos+3]= 0;}
  188.             buf_pos+=3;
  189.             pos+=Surface->bpp;
  190.         }
  191.         //return buffer to start of line then up one line
  192.         buf_pos += padding;
  193.         buf_pos -= datawidth+datawidth;
  194.     }
  195.     delete [] buffer;
  196. }
  197.  
  198. void loadBMP(const char *filepath, OGL_Texture *Texture)
  199. {
  200.     OGL_Surface *Surface = new OGL_Surface;
  201.     Surface->Create_Surface(1,1,4);
  202.     loadBMP(filepath, Surface);
  203.     Texture->gen_texture(Surface->w, Surface->h, Surface->PixData);
  204.     delete Surface;
  205. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement