00001 // ======================================================================== // 00002 // // 00003 // File : Bmp.h // 00004 // Purpose : // 00005 // Time-stamp: <Thu Nov/14/2002 09:34 MET Coder@ReallySoft.de> // 00006 // // 00007 // (C) February 2002 by Ralf Westram // 00008 // // 00009 // Permission to use, copy, modify, distribute and sell this software // 00010 // and its documentation for any purpose is hereby granted without fee, // 00011 // provided that the above copyright notice appear in all copies and // 00012 // that both that copyright notice and this permission notice appear // 00013 // in supporting documentation. // 00014 // // 00015 // Ralf Westram makes no representations about the suitability of this // 00016 // software for any purpose. It is provided "as is" without express or // 00017 // implied warranty. // 00018 // // 00019 // ======================================================================== // 00020 00021 #ifndef BMP_H 00022 #define BMP_H 00023 00024 #ifndef STRING 00025 #include <string> 00026 #endif 00027 00028 #ifndef BOOST_UTIL_H 00029 #include <boost_util.h> 00030 #endif 00031 00032 namespace rs { 00033 00034 typedef unsigned int UINT32; 00035 typedef unsigned short UINT16; 00036 00037 const long max_distance = 255L*255L; 00038 00040 class Pixel { 00041 private: 00042 unsigned char *pix; // pointer to pixel 00043 00044 static unsigned char transparent_red, transparent_green, transparent_blue; // the transparent color 00045 static bool use_transparent_color; 00046 00047 public: 00050 Pixel() : pix(0) {} 00055 Pixel(unsigned char *pixPtr) : pix(pixPtr) {} 00056 virtual ~Pixel() {} 00057 00059 unsigned char *getPixPointer() { return pix; } 00061 const unsigned char *getPixPointer() const { return pix; } 00062 00067 int color(int rgb) const { assert(rgb >= 0 && rgb <= 2); return pix[rgb]; } 00068 00073 void set_color(int rgb, unsigned char value) { assert(rgb >= 0 && rgb <= 2); pix[rgb] = value; } 00074 00079 bool hasTransparentColor() const { 00080 return use_transparent_color && 00081 color(0) == transparent_red && 00082 color(1) == transparent_green && 00083 color(2) == transparent_blue; 00084 } 00085 00091 static void defineTransparentColor(unsigned char red, unsigned char green, unsigned char blue); 00092 00096 static void useTransparentColor(bool enabled) { 00097 use_transparent_color = enabled; 00098 } 00099 00109 void countMisMatches(const Pixel& other, long& matchCounter, long& mismatchCounter, int max_dist) { 00110 if (!hasTransparentColor() && !other.hasTransparentColor()) { 00111 long rdist = labs(color(0)-other.color(0)); 00112 long gdist = labs(color(1)-other.color(1)); 00113 long bdist = labs(color(2)-other.color(2)); 00114 00115 if (rdist>max_dist || gdist>max_dist || bdist>max_dist) { 00116 ++mismatchCounter; 00117 } 00118 else { 00119 ++matchCounter; 00120 } 00121 } 00122 } 00123 00128 long distance(const Pixel& other) const { 00129 if (hasTransparentColor() || other.hasTransparentColor()) return 0; 00130 00131 long rdist = color(0)-other.color(0); 00132 long gdist = color(1)-other.color(1); 00133 long bdist = color(2)-other.color(2); 00134 00135 return rdist*rdist + gdist*gdist + bdist*bdist; 00136 } 00137 00141 Pixel& operator++() { 00142 pix += 3; 00143 return *this; 00144 } 00145 00146 bool operator == (const Pixel& other) const { 00147 return 00148 color(0) == other.color(0) && 00149 color(1) == other.color(1) && 00150 color(2) == other.color(2); 00151 } 00152 00153 bool operator != (const Pixel& other) const { return !(*this == other); } 00154 }; 00155 00156 00157 00158 00160 class Bmp { 00161 private: 00162 std::string loaded_from_file; 00163 00164 UINT32 xsize; 00165 UINT32 ysize; 00166 00167 unsigned char *data; 00168 size_t offset_per_line; 00169 00170 static void throw_wrong_pix_pos(); 00171 00172 unsigned char *pixelPointer(UINT32 xpos, UINT32 ypos) { 00173 if (xpos >= xsize || ypos >= ysize) throw_wrong_pix_pos(); 00174 return data + ypos*offset_per_line + xpos*3; 00175 } 00176 00177 void getPositions(const Pixel& pixel, UINT32& xpos_result, UINT32& ypos_result) const { 00178 long distance = pixel.getPixPointer()-data; 00179 long ypos = distance/long(offset_per_line); 00180 long xpos = (distance - ypos*offset_per_line)/3; 00181 00182 xpos_result = xpos; 00183 ypos_result = ypos; 00184 00185 if (xpos_result >= xsize || ypos_result >= ysize) throw_wrong_pix_pos(); 00186 } 00187 00188 public: 00192 Bmp(const std::string& filename); 00198 Bmp(size_t xsize_, size_t ysize_); 00199 00200 Bmp(const Bmp& other); 00201 Bmp& operator=(const Bmp& other); 00202 00203 virtual ~Bmp() { delete data; } 00204 00206 UINT32 Xsize() const { return xsize; } 00207 00209 UINT32 Ysize() const { return ysize; } 00210 00216 Pixel getPixel(UINT32 xpos, UINT32 ypos) { return Pixel(pixelPointer(xpos, ypos)); } 00217 00219 const Pixel getPixel(UINT32 xpos, UINT32 ypos) const { return Pixel(const_cast<Bmp*>(this)->pixelPointer(xpos, ypos)); } 00220 00228 void setPixel(UINT32 xpos, UINT32 ypos, unsigned char red, unsigned char green, unsigned char blue) { 00229 unsigned char *d = const_cast<unsigned char *>(pixelPointer(xpos, ypos)); 00230 00231 d[0] = red; 00232 d[1] = green; 00233 d[2] = blue; 00234 } 00235 00239 void saveAs(const std::string& filename) const; 00240 00244 const std::string& originalFilename() const { return loaded_from_file; } 00245 00247 void left(Pixel& curr, size_t dist = 1) { 00248 UINT32 xpos, ypos; 00249 getPositions(curr, xpos, ypos); 00250 curr = getPixel(xpos-dist, ypos); 00251 } 00252 00254 void right(Pixel& curr, size_t dist = 1) { 00255 UINT32 xpos, ypos; 00256 getPositions(curr, xpos, ypos); 00257 curr = getPixel(xpos+dist, ypos); 00258 } 00259 00261 void up(Pixel& curr, size_t dist = 1) { 00262 UINT32 xpos, ypos; 00263 getPositions(curr, xpos, ypos); 00264 curr = getPixel(xpos, ypos-dist); 00265 } 00266 00268 void down(Pixel& curr, size_t dist = 1) { 00269 UINT32 xpos, ypos; 00270 getPositions(curr, xpos, ypos); 00271 curr = getPixel(xpos, ypos+dist); 00272 } 00273 }; 00274 00275 // create a new BMP with half width and height 00276 Bmp *halfBmp(const Bmp& bmp); 00277 00278 00279 00280 }; // end of namespace rs 00281 00282 #else 00283 #error Bmp.h included twice 00284 #endif // BMP_H 00285
Contact me in case of errors or questions. This documentation is powered by ![]() |
(C) 2000-2002 ![]() |