00001
00002
00004 #include <stddef.h>
00005 #include "vuImage.h"
00006 #include <GL/gl.h>
00007 #include <Paintlib/planybmp.h>
00008 #include <Paintlib/plbmpdec.h>
00009 #include <Paintlib/plbmpenc.h>
00010
00011
00013
00015
00016 vuImage::vuImage(dword width, dword height)
00017 {
00018 spix = NULL;
00019 maxx = 0;
00020 maxy = 0;
00021 init(width, height);
00022 }
00023
00024 vuImage::~vuImage()
00025 {
00026 if(spix) {
00027 delete [] spix;
00028 spix = NULL;
00029 }
00030 }
00031
00032 vuImage::vuImage(const vuImage &other)
00033 {
00034 operator=(other);
00035 }
00036
00037
00038 bool vuImage::init(int sizx, int sizy)
00039 {
00040 if ((sizx != maxx) || (sizy != maxy)) {
00041 maxx=sizx;
00042 maxy=sizy;
00043 if(spix) delete [] spix;
00044 if(sizx && sizy)
00045 {
00046 spix = new byte[maxx*maxy*3];
00047 int c;
00048 byte *bp = spix;
00049 for(c=maxx*maxy*3;c>0;c--,bp++) *bp=0;
00050 if(!spix) return false;
00051 } else spix = NULL;
00052 return true;
00053 } else return false;
00054 }
00055
00056 bool vuImage::set_xy(int x, int y, const vuColourRGBa& col)
00057 {
00058 if(x<0 || y<0 || x>=maxx || y>=maxy) return false;
00059 vuColourRGBa rgb(col);
00060 rgb.clampTo01();
00061 byte *pix = &spix[(maxx*y+x)*3];
00062 pix[0] = byte(255.0f * rgb[0]);
00063 pix[1] = byte(255.0f * rgb[1]);
00064 pix[2] = byte(255.0f * rgb[2]);
00065
00066
00067
00068 return true;
00069 }
00070
00071 bool vuImage::set_xy(int x, int y, unsigned char r, unsigned char g, unsigned char b)
00072 {
00073 if(x<0 || y<0 || x>=maxx || y>=maxy) return false;
00074 byte *pix = &spix[(maxx*y+x)*3];
00075 pix[0] = byte(r);
00076 pix[1] = byte(g);
00077 pix[2] = byte(b);
00078 return true;
00079 }
00080
00081 bool vuImage::get_xy(int x, int y, vuColourRGBa &col)
00082 {
00083 if(x<0 || y<0 || x>=maxx || y>=maxy) return false;
00084 col[0] = 255.0f/spix[(maxx*y+x)*3];
00085 col[1] = 255.0f/spix[(maxx*y+x)*3+1];
00086 col[2] = 255.0f/spix[(maxx*y+x)*3+2];
00087 return true;
00088 }
00089
00090 const byte* vuImage::get_rgb() const
00091 {
00092 return spix;
00093 }
00094
00095 byte* vuImage::get_buffer()
00096 {
00097 return spix;
00098 }
00099
00100 void vuImage::get_extents(int &sizx, int &sizy)
00101 {
00102 sizx=maxx;
00103 sizy=maxy;
00104 }
00105
00106 void vuImage::set_extents (int sizx, int sizy)
00107 {
00108 maxx = sizx;
00109 maxy = sizy;
00110 }
00111
00112 bool vuImage::set_rgb (byte* rgb)
00113 {
00114 memcpy(spix, rgb, 3 * maxx * maxy);
00115
00116 return true;
00117 }
00118
00119 void vuImage::set_rgb (int start, int number_copied, byte* rgb)
00120 {
00121 memcpy(&(spix [start]), rgb, number_copied);
00122 }
00123
00124 bool vuImage::set_data (byte* rgb)
00125 {
00126 delete [] spix;
00127
00128 spix = rgb;
00129
00130 return true;
00131 }
00132
00133 void vuImage::elim_data (byte* rgb)
00134 {
00135 spix = rgb;
00136 }
00137
00138 int vuImage::getWidth () const
00139 {
00140 return maxx;
00141 }
00142
00143 int vuImage::getHeight () const
00144 {
00145 return maxy;
00146 }
00147
00148 void vuImage::clear(const byte r, const byte g, const byte b)
00149 {
00150 byte* p = spix;
00151
00152 for (int i=maxx*maxy; i>0; i--) {
00153 *(p++) = r;
00154 *(p++) = g;
00155 *(p++) = b;
00156 }
00157 }
00158
00159
00160 void vuImage::blit(int x, int y)
00161 {
00162 if(maxx && maxy && spix) {
00163
00164 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00165
00166 glRasterPos2i(x,y);
00167 glDrawPixels(maxx,
00168 maxy,
00169 GL_RGB,
00170 GL_UNSIGNED_BYTE,
00171 spix);
00172 }
00173 }
00174
00175
00176
00177
00178
00179 void vuImage::initOpenGL(void)
00180 {
00181 glDisable(GL_LIGHTING);
00182 }
00183
00184 void vuImage::glResize(dword width, dword height)
00185 {
00186 if (maxx == 0 || maxy == 0)
00187 cerr << "WARNING: vuImage.glResize(): width or height is 0." << endl;
00188 glPixelZoom((float)width/maxx,(float)height/maxy);
00189 }
00190
00191 void vuImage::glRender()
00192 {
00193 if (maxx && maxy && spix)
00194 glDrawPixels(maxx, maxy, GL_RGB, GL_UNSIGNED_BYTE, spix);
00195 }
00196
00197
00198
00199
00200
00201 #if 0
00202 bool vuImage::writeToFile(const char *fileName, vuImageFormat fmt)
00203 {
00204 PLAnyBmp bmp;
00205 PLBmpEncoder encoder;
00206 PLBYTE **dest;
00207 byte *src;
00208 int bit = (fmt == vuBMP_GREY) ? 8 : 32;
00209
00210 bmp.Create(maxx, maxy, bit, false);
00211 dest = bmp.GetLineArray();
00212 src = get_buffer();
00213
00214 for (int j=0; j<maxy; j++) {
00215 for (int i=0; i<maxx; i++) {
00216 PLBYTE *tmp = dest[j];
00217
00218 if (fmt == vuBMP_GREY) {
00219 tmp[i] = (*src+*(src+1)+*(src+2)) / 3;
00220 src += 3;
00221 }
00222 else {
00223 tmp[4*i+0] = *(src++);
00224 tmp[4*i+1] = *(src++);
00225 tmp[4*i+2] = *(src++);
00226 }
00227 }
00228 }
00229
00230 try {
00231 encoder.MakeFileFromBmp(fileName, &bmp);
00232 }
00233 catch (PLTextException &excep) {
00234 cerr << "PLTextException catched..." << excep.GetCode() << endl;
00235 return false;
00236 }
00237 catch(...) {
00238 cerr << "catched...." << endl;
00239 return false;
00240 }
00241 return true;
00242 }
00243
00244 bool vuImage::readFromFile(const char *fileName, vuImageFormat fmt)
00245 {
00246 PLAnyBmp bmp;
00247 PLBmpDecoder decoder;
00248 PLBYTE **src;
00249 byte *dest;
00250
00251 try {
00252 decoder.MakeBmpFromFile(fileName, &bmp);
00253 }
00254 catch (PLTextException &excep) {
00255 cerr << "PLTextException catched..." << excep.GetCode() << endl;
00256 return false;
00257 }
00258 catch(...) {
00259 cerr << "catched...." << endl;
00260 return false;
00261 }
00262
00263 init(bmp.GetWidth(), bmp.GetHeight());
00264 src = bmp.GetLineArray();
00265 dest = get_buffer();
00266
00267 for (int j=0; j<maxy; j++) {
00268 for (int i=0; i<maxx; i++) {
00269 PLBYTE *tmp = src[j];
00270
00271 if (fmt == vuBMP_GREY) {
00272 *(dest++) = tmp[i];
00273 *(dest++) = tmp[i];
00274 *(dest++) = tmp[i];
00275 }
00276 else {
00277 *(dest++) = tmp[4*i+0];
00278 *(dest++) = tmp[4*i+1];
00279 *(dest++) = tmp[4*i+2];
00280 }
00281
00282 }
00283 }
00284
00285 return true;
00286 }
00287 #endif
00288
00289 vuImage vuImage::operator=(const vuImage &other)
00290 {
00291 if (this == &other) return other;
00292
00293 int width = other.getWidth();
00294 int height = other.getHeight();
00295
00296 init(width, height);
00297
00298 byte *dest = get_buffer();
00299 const byte *src = other.get_rgb();
00300
00301 for (int j=0; j<height; j++) {
00302 for (int i=0; i<width; i++) {
00303 *(dest++) = *(src++);
00304 *(dest++) = *(src++);
00305 *(dest++) = *(src++);
00306 }
00307 }
00308 return other;
00309 }
00310
00311 vuImage &vuImage::operator+=(vuImage &other)
00312 {
00313 int width = this->getWidth();
00314 int height = this->getHeight();
00315
00316 if (width != other.getWidth()) {
00317
00318 cerr << "can not add images: widths are different (";
00319 cerr << width << " vs. " << other.getWidth() << ")" << endl;
00320 return *this;
00321 }
00322 if (height != other.getHeight()) {
00323
00324 cerr << "can not add images: heights are different (";
00325 cerr << height << " vs. " << other.getHeight() << ")" << endl;
00326 return *this;
00327 }
00328
00329 byte *dest = get_buffer();
00330 byte *src = other.get_buffer();
00331
00332 for (int j=0; j<height; j++) {
00333 for (int i=0; i<width; i++) {
00334 *(dest++) += *(src++);
00335 *(dest++) += *(src++);
00336 *(dest++) += *(src++);
00337 }
00338 }
00339 return *this;
00340 }
00341
00342 vuImage &vuImage::operator*=(float scale)
00343 {
00344 int width = this->getWidth();
00345 int height = this->getHeight();
00346 byte *ptr = get_buffer();
00347
00348 for (int j=0; j<height; j++) {
00349 for (int i=0; i<width; i++) {
00350 byte tmp;
00351
00352 tmp = (byte)(*ptr * scale); *(ptr++) = tmp;
00353 tmp = (byte)(*ptr * scale); *(ptr++) = tmp;
00354 tmp = (byte)(*ptr * scale); *(ptr++) = tmp;
00355 }
00356 }
00357 return *this;
00358 }