/Users/craigcornelius/Projects/SPRING Mac Release 0.2/imagebmp.h

Go to the documentation of this file.
00001 //
00002 // ImageBMP - class for reading in a Windows BMP file
00003 //
00004 
00005 #ifndef ImageBMP_Header
00006 #define ImageBMP_Header
00007 
00008 #include <stdlib.h>
00009 #include <stdio.h>
00010 #include <fstream>
00011 #include <iostream>
00012 
00013 typedef unsigned long ulong;
00014 typedef unsigned short ushort;
00015 typedef unsigned char uchar;
00016 
00017 class ImageBMP {
00018 public:
00019     // header
00020     char sig[2];
00021     ulong filesize;
00022     ulong reserved;
00023     ulong dataoffset;
00024     
00025     // info header
00026     ulong infoheadersize;
00027     ulong width;
00028     ulong height;
00029     ushort depth;
00030     ushort bitsperpixel;
00031     ulong compression; // 0=none, 1=8bit RLE, 2=4bit RLE
00032     ulong imagesize;    // 0=no compression
00033     ulong xpixperm;     // xpixels per meter
00034     ulong ypixperm;     // ypixels per meter
00035     ulong colorsused;  // actually used colors
00036     ulong colorsimportant; // num important colors (0=all)
00037     
00038     // color table (4 * numcolors if bitsperpixel<=8)
00039     struct colorentry { uchar r,g,b,a; };
00040     colorentry* colortable;  //  numcolors entries
00041     
00042     // pixeldata: 
00043     //  bottom up, left-to-right, RGBA
00044     //  lines padded to fill 4-byte word
00045     uchar* imagedata;
00046     
00047     // functions
00048     uchar get_uchar(FILE* fp);
00049     ushort get_ushort(FILE* fp);
00050     ulong  get_ulong(FILE* fp);
00051     
00052     // public functions
00053     ImageBMP();
00054     ~ImageBMP();
00055     int Read(char* filename);
00056 };
00057 
00058 inline ImageBMP::ImageBMP() 
00059 { filesize = reserved = dataoffset = width = height = 0; 
00060 colortable = NULL; imagedata = NULL; }
00061 
00062 inline ImageBMP::~ImageBMP()
00063 { 
00064     if (colortable) { delete colortable; colortable = NULL; }
00065     if (imagedata) { delete imagedata; imagedata = NULL; }
00066 }
00067 
00068 inline uchar ImageBMP::get_uchar(FILE* fp)
00069 {
00070     uchar val;
00071     fread(&val, 1, sizeof(uchar), fp);
00072     return(val);
00073 }
00074 
00075 inline ushort ImageBMP::get_ushort(FILE* fp)
00076 {
00077     ushort val;
00078     fread(&val, 1, sizeof(ushort), fp);
00079 #ifdef _WIN32
00080     return(val);
00081 #else
00082     // swab bytes (little endian-big endian thing)
00083     return( ((val & 0x00ff) << 8) | ((val & 0xff00) >> 8) );
00084 #endif
00085 }
00086 
00087 inline ulong ImageBMP::get_ulong(FILE* fp)
00088 {
00089     ushort val1 = get_ushort(fp); 
00090     ushort val2 = get_ushort(fp);
00091     ulong val = (val2 << 16) | val1;
00092     return( val );
00093 }
00094 
00095 inline int ImageBMP::Read(char* filename) 
00096 {
00097         using namespace std;
00098 
00099     // if there's already old data, get rid of it
00100     if (colortable) { delete colortable; colortable = NULL; }
00101     if (imagedata) { delete imagedata; imagedata = NULL; }
00102     
00103     // open the given file
00104     FILE* fp = fopen(filename, "rb");
00105     if (!fp) { cerr << "can't open [" << filename << "]\n"; return(-1); }
00106     
00107     // header
00108     sig[0] = get_uchar(fp);
00109     sig[1] = get_uchar(fp);
00110     filesize = get_ulong(fp);   // filesize
00111     reserved = get_ulong(fp);   // reserved
00112     dataoffset = get_ulong(fp); // dataoffset
00113     
00114     // sanity check
00115     if ((sig[0] != 'B') || (sig[1] != 'M')) { 
00116         cerr << "not a BMP file\n"; 
00117         fclose(fp);
00118         return(-1); }
00119     
00120     // info header
00121     infoheadersize = get_ulong(fp);
00122     width = get_ulong(fp);
00123     height = get_ulong(fp);
00124     depth = get_ushort(fp);
00125     bitsperpixel = get_ushort(fp);
00126     compression = get_ulong(fp);
00127     imagesize = get_ulong(fp);
00128     xpixperm = get_ulong(fp);
00129     ypixperm = get_ulong(fp);
00130     colorsused = get_ulong(fp);
00131     colorsimportant = get_ulong(fp);
00132     
00133     // sanity checks
00134     if (compression != 0) { 
00135         cerr << "can't do compression=" << compression << endl; 
00136         fclose(fp);
00137         return(-1); 
00138     }
00139     if (bitsperpixel != 24) {
00140         cerr << "can't do bitsperpixel=" << bitsperpixel << endl; 
00141         fclose(fp);
00142         return(-1); 
00143     }
00144     
00145     // debugging
00146     cerr << "sig= " << sig 
00147         << ", compression = " << compression
00148         << ", depth = " << depth
00149         << ", bitsperpixel = " << bitsperpixel
00150         << "\n width = " << width << ", height = " << height 
00151         << endl;
00152     
00153     // read in the colortable
00154     // there is none for compression=0, bitsperpixel=24!
00155     colortable = NULL;
00156     
00157     // read in the pixels
00158     imagedata = new uchar[width * height * 4];
00159     for (ushort y=0; y<height; y++) {
00160         for (ushort x=0; x<width; x++) {
00161             uchar r,g,b;
00162             r = get_uchar(fp); g = get_uchar(fp); b = get_uchar(fp); 
00163             imagedata[y*width*3 + x*3 + 0] = b;
00164             imagedata[y*width*3 + x*3 + 1] = g;
00165             imagedata[y*width*3 + x*3 + 2] = r;
00166             imagedata[y*width*3 + x*3 + 3] = 255;
00167         }
00168     }
00169     
00170     // finish up
00171     fclose(fp);
00172     return(0);  // success
00173 }
00174 
00175 #endif

Generated on Thu Aug 30 11:03:14 2007 for SPRING Mac by  doxygen 1.5.3