00001
00002
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
00020 char sig[2];
00021 ulong filesize;
00022 ulong reserved;
00023 ulong dataoffset;
00024
00025
00026 ulong infoheadersize;
00027 ulong width;
00028 ulong height;
00029 ushort depth;
00030 ushort bitsperpixel;
00031 ulong compression;
00032 ulong imagesize;
00033 ulong xpixperm;
00034 ulong ypixperm;
00035 ulong colorsused;
00036 ulong colorsimportant;
00037
00038
00039 struct colorentry { uchar r,g,b,a; };
00040 colorentry* colortable;
00041
00042
00043
00044
00045 uchar* imagedata;
00046
00047
00048 uchar get_uchar(FILE* fp);
00049 ushort get_ushort(FILE* fp);
00050 ulong get_ulong(FILE* fp);
00051
00052
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
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
00100 if (colortable) { delete colortable; colortable = NULL; }
00101 if (imagedata) { delete imagedata; imagedata = NULL; }
00102
00103
00104 FILE* fp = fopen(filename, "rb");
00105 if (!fp) { cerr << "can't open [" << filename << "]\n"; return(-1); }
00106
00107
00108 sig[0] = get_uchar(fp);
00109 sig[1] = get_uchar(fp);
00110 filesize = get_ulong(fp);
00111 reserved = get_ulong(fp);
00112 dataoffset = get_ulong(fp);
00113
00114
00115 if ((sig[0] != 'B') || (sig[1] != 'M')) {
00116 cerr << "not a BMP file\n";
00117 fclose(fp);
00118 return(-1); }
00119
00120
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
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
00146 cerr << "sig= " << sig
00147 << ", compression = " << compression
00148 << ", depth = " << depth
00149 << ", bitsperpixel = " << bitsperpixel
00150 << "\n width = " << width << ", height = " << height
00151 << endl;
00152
00153
00154
00155 colortable = NULL;
00156
00157
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
00171 fclose(fp);
00172 return(0);
00173 }
00174
00175 #endif