Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

vuFixelMap.cpp

Go to the documentation of this file.
00001 #include "vuFixelMap.h"
00002 #include <stddef.h>
00003 #include <fstream.h>
00004 #include <GL/gl.h>
00005 #include "vuFixelType.h"
00006 #include "math.h"
00007 
00008 template <int S, class T>
00009 vuFixelMap<S,T>::vuFixelMap()
00010 {
00011   m_buffer        = NULL;
00012   m_width         = 0;
00013   m_height        = 0;
00014   m_isBufferNewed = true;
00015 }
00016 
00017 template <int S, class T>
00018 vuFixelMap<S,T>::vuFixelMap(dword width, dword height)
00019 {
00020   m_buffer        = NULL;
00021   m_width         = 0;
00022   m_height        = 0;
00023   m_isBufferNewed = true;
00024   _ensureBuffer(width, height);
00025 }
00026 
00027 template <int S, class T>
00028 vuFixelMap<S,T>::~vuFixelMap()
00029 {
00030   if((m_buffer != NULL) && m_isBufferNewed) delete m_buffer;
00031   m_isBufferNewed = true;
00032   m_buffer        = NULL;
00033 }
00034 
00035 template <int S, class T>
00036 vuFixelMap<S,T>::vuFixelMap(const vuFixelMap &other)
00037 {
00038   // cerr << "+++ fixelMap copy constructor" << endl;
00039   m_buffer        = NULL;
00040   m_width         = 0;
00041   m_height        = 0;
00042   m_isBufferNewed = true;
00043 
00044   _ensureBuffer(other.m_width, other.m_height, other.getBuffer());
00045 }
00046 
00047 template <int S, class T>
00048 void vuFixelMap<S,T>::setWidthAndHeight(const dword sizx, const dword sizy)
00049 {
00050   _ensureBuffer(sizx, sizy);
00051 }
00052 
00053 template <int S, class T>
00054 dword vuFixelMap<S,T>::getWidth() const
00055 {
00056   return m_width;
00057 }
00058 
00059 template <int S, class T>
00060 dword vuFixelMap<S,T>::getHeight() const
00061 {
00062   return m_height;
00063 }
00064 
00065 template <int S, class T>
00066 void vuFixelMap<S,T>::setFixel(dword x, dword y, const vuFixel<S,T> &fixel)
00067 {
00068   T *pix = &m_buffer[(m_width*y+x)*S];
00069   for (dword i=0; i<S; i++) pix[i] = fixel[i];
00070 }
00071 
00072 template <int S, class T>
00073 vuFixel<S,T> vuFixelMap<S,T>::getFixel(dword x, dword y)
00074 {
00075   T *ptr = m_buffer+((m_width*y+x)*S);
00076   return vuFixel<S,T>(ptr);
00077 }
00078 
00079 template <int S, class T>
00080 const T* vuFixelMap<S,T>::getBuffer() const
00081 {
00082   return m_buffer;
00083 }
00084 
00085 template <int S, class T>
00086 T* vuFixelMap<S,T>::getBuffer()
00087 {
00088   return m_buffer;
00089 }
00090 
00091 /* ----------------------------------------------------------------------- */
00092 /* --- some Open Gl related things --------------------------------------- */
00093 /* ----------------------------------------------------------------------- */
00094 
00095 template <int S, class T>
00096 void vuFixelMap<S,T>::initOpenGL(void)
00097 {
00098   glDisable(GL_LIGHTING);
00099 }
00100 
00101 template <int S, class T>
00102 void vuFixelMap<S,T>::glResize(dword width, dword height)
00103 {
00104   if (m_width == 0 || m_height == 0)
00105     cerr << "WARNING: vuFixelMap.glResize(): width or height is 0." << endl;
00106   glPixelZoom((float)width/m_width,(float)height/m_height);
00107 }
00108 
00109 template <int S, class T>
00110 void vuFixelMap<S,T>::glRender()
00111 {
00112   if (vuFixelType<T>::isByte()) {
00113     if (S == 1) {
00114       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00115       glPixelStorei(GL_UNPACK_ROW_LENGTH, m_width);
00116       //glRasterPos2i(0,0);
00117       glDrawPixels(m_width,m_height,GL_LUMINANCE,GL_UNSIGNED_BYTE,m_buffer);
00118     }
00119     else if (S == 2) {
00120       glDrawPixels(m_width, m_height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, m_buffer);
00121     }
00122     else if (S == 3) {
00123       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00124       glPixelStorei(GL_UNPACK_ROW_LENGTH, m_width);
00125       glDrawPixels(m_width, m_height, GL_RGB, GL_UNSIGNED_BYTE, m_buffer);
00126     }
00127     else {
00128       cerr << "WARNING: vuFixelMap.glRender():: case not implemented yet";
00129       cerr << " (S=" << S << ")" << endl;
00130     }
00131   }
00132   else if (vuFixelType<T>::isFloat()) {
00133     if (S == 1) {
00134       glDrawPixels(m_width, m_height, GL_LUMINANCE, GL_FLOAT, m_buffer);
00135     }
00136     else if (S == 2) {
00137       glDrawPixels(m_width, m_height, GL_LUMINANCE_ALPHA, GL_FLOAT, m_buffer);
00138     }
00139     else if (S == 3) {
00140       glDrawPixels(m_width, m_height, GL_RGB, GL_FLOAT, m_buffer);
00141     }
00142     else {
00143       cerr << "WARNING: vuFixelMap.glRender():: case not implemented yet";
00144       cerr << " (S=" << S << ")" << endl;
00145     }
00146   }
00147   else {
00148     cerr << "WARNING: vuFixelMap.glRender():: case not implemented yet";
00149     cerr << " (T unknown)" << endl;
00150   }
00151 }
00152 
00153 template <int S, class T>
00154 vuFixelMap<S,T> &vuFixelMap<S,T>::operator=(const vuFixelMap<S,T> &other)
00155 {
00156   if (this == &other) return *this;
00157   _ensureBuffer(other.m_width, other.m_height, other.getBuffer());
00158   return *this;
00159 }
00160 
00161 template <int S, class T>
00162 vuFixelMap<S,T> &vuFixelMap<S,T>::operator=(const vuFixel<S,T> &fixel)
00163 {
00164   dword   len = getWidth() * getHeight();
00165   T *ptr = getBuffer();
00166 
00167   for (;len>0;len--) {
00168     for (dword i=0; i<S; i++,ptr++) *ptr = fixel[i];
00169   }
00170 
00171   return *this;
00172 }
00173 
00174 template <int S, class T>
00175 vuFixelMap<S,T> &vuFixelMap<S,T>::operator+=(vuFixelMap<S,T> &other)
00176 {
00177   if (m_width != other.getWidth() || m_height != other.getHeight()) {
00178     cerr << "Warning: vuFixelMap::operator+= width or height are not equal!";
00179     cerr << endl;
00180     return *this;
00181   }
00182 
00183   dword   len  = getWidth() * getHeight() * S;
00184   T *dest = getBuffer();
00185   T *src  = other.getBuffer();
00186 
00187   for (;len>0;len--) *(dest++) += *(src++);
00188 
00189   return *this;
00190 }
00191 
00192 template <int S, class T>
00193 vuFixelMap<S,T> &vuFixelMap<S,T>::operator+=(float bias)
00194 {
00195   dword   len  = getWidth() * getHeight() * S;
00196   T *dest = getBuffer();
00197 
00198   float minValue = vuFixelType<T>::getMinValue();
00199   float maxValue = vuFixelType<T>::getMaxValue();
00200 
00201   for (;len>0;len--) {
00202     register float tmp = (*dest + bias);
00203     
00204     if (tmp > maxValue) 
00205       tmp = maxValue;
00206     else if (tmp < minValue)
00207       tmp = minValue;
00208 
00209     *dest = (T)tmp;
00210   }
00211 
00212   return *this;
00213 }
00214 
00215 template <int S, class T>
00216 vuFixelMap<S,T> &vuFixelMap<S,T>::operator-=(float bias)
00217 {
00218   dword   len  = getWidth() * getHeight() * S;
00219   T *dest = getBuffer();
00220 
00221   float minValue = vuFixelType<T>::getMinValue();
00222   float maxValue = vuFixelType<T>::getMaxValue();
00223 
00224   for (;len>0;len--) {
00225     register float tmp = (*dest - bias);
00226     
00227     if (tmp > maxValue) 
00228       tmp = maxValue;
00229     else if (tmp < minValue)
00230       tmp = minValue;
00231 
00232     *(dest++) = (T)tmp;
00233   }
00234 
00235   return *this;
00236 }
00237 
00238 
00239 
00240 template <int S, class T>
00241 vuFixelMap<S,T> &vuFixelMap<S,T>::operator-=(vuFixelMap<S,T> &other)
00242 {
00243   if (m_width != other.getWidth() || m_height != other.getHeight()) {
00244     cerr << "Warning: vuFixelMap::operator-= width or height are not equal!";
00245     cerr << endl;
00246     return *this;
00247   }
00248 
00249   dword   len  = getWidth() * getHeight() * S;
00250   T *dest = getBuffer();
00251   T *src  = other.getBuffer();
00252 
00253   for (;len>0;len--) *(dest++) -= *(src++);
00254 
00255   return *this;
00256 }
00257 
00258 
00259 template <int S, class T>
00260 vuFixelMap<S,T> &vuFixelMap<S,T>::operator*=(float scale)
00261 {
00262   T  *ptr = getBuffer();
00263   dword  len = getWidth() * getHeight() * S;
00264 
00265   float minValue = vuFixelType<T>::getMinValue();
00266   float maxValue = vuFixelType<T>::getMaxValue();
00267 
00268   for (;len>0;len--,ptr++) {
00269     register float tmp = (*ptr * scale);
00270     
00271     if (tmp > maxValue) 
00272       tmp = maxValue;
00273     else if (tmp < minValue)
00274       tmp = minValue;
00275 
00276     *ptr = (T)tmp;
00277   }
00278 
00279   return *this;
00280 }
00281 
00282 template <int S, class T>
00283 vuFixelMap<S,T> &vuFixelMap<S,T>::operator/=(float scale)
00284 {
00285   T  *ptr = getBuffer();
00286   dword  len = getWidth() * getHeight() * S;
00287 
00288   float minValue = vuFixelType<T>::getMinValue();
00289   float maxValue = vuFixelType<T>::getMaxValue();
00290 
00291   for (;len>0;len--,ptr++) {
00292     register float tmp = (*ptr / scale);
00293     
00294     if (tmp > maxValue) 
00295       tmp = maxValue;
00296     else if (tmp < minValue)
00297       tmp = minValue;
00298 
00299     *ptr = (T)tmp;
00300   }
00301 
00302   return *this;
00303 }
00304 
00305 template <int S, class T>
00306 bool vuFixelMap<S,T>::writeToFileStream(ostream *out)
00307 {
00308   dword size = m_width * m_height * S;
00309 
00310   if (out && (size > 0) && m_buffer) {
00311     out->write((const char *)m_buffer, size * sizeof(T));
00312     return !out->bad();
00313   }
00314   return false;
00315 }
00316 
00317 template <int S, class T>
00318 bool vuFixelMap<S,T>::readFromFileStream(istream *in, dword width, dword height)
00319 {
00320   dword size = width * height * S;
00321 
00322   if (in && (size > 0)) {
00323     if (m_isBufferNewed) CHECKNDELETE (m_buffer);
00324 
00325     T *buffer = new T[size];
00326     in->read((char *)buffer, size * sizeof(T));
00327     if (in->bad()) return false;
00328     _ensureBuffer(width, height, buffer);
00329     return true;
00330   }
00331   return false;
00332 }
00333 
00334 template <int S, class T>
00335 void vuFixelMap<S,T>::assignBuffer(T *buffer, dword width, dword height)
00336 {
00337   if (buffer != NULL) {
00338     if ((m_buffer != NULL) && m_isBufferNewed) delete m_buffer;
00339     m_buffer = buffer; // this is NOT "new"ed!!!
00340     m_isBufferNewed = false;
00341     m_width  = width;
00342     m_height = height;
00343   }
00344 }
00345 
00346 template <int S, class T>
00347 void vuFixelMap<S,T>::writeBufferToFile(FILE *file)
00348 {
00349   fwrite(m_buffer, sizeof(T), S * m_width * m_height, file);
00350 }
00351 
00352 // ------------------------------------------------------------------------
00353 // --- finding min and max value ------------------------------------------
00354 // ------------------------------------------------------------------------
00355 
00356 template <int S, class T>
00357 void vuFixelMap<S,T>::getMinAndMaxValue(T &minValue, T &maxValue)
00358 {
00359   T minVal, maxVal;
00360 
00361   minValue = vuFixelType<T>::getPosInfinity();
00362   maxValue = vuFixelType<T>::getNegInfinity();
00363 
00364   for (int i=0; i<S; i++) {
00365 
00366     getMinAndMaxValue(minVal, maxVal, i);
00367 
00368     if (minValue > minVal) minValue = minVal;
00369     if (maxValue < maxVal) maxValue = maxVal;
00370   }
00371 }
00372 
00373 template <int S, class T>
00374 void vuFixelMap<S,T>::getMinAndMaxValue(T &minValue, T &maxValue, word channel)
00375 {
00376   T     *ptr = getBuffer();
00377   dword cnt  = getWidth() * getHeight();
00378 
00379   // ??? WARNING: might NOT work for unsigned types... ???
00380   minValue = vuFixelType<T>::getPosInfinity();
00381   maxValue = vuFixelType<T>::getNegInfinity();
00382 
00383   for (dword i=0; i<cnt; i++) {
00384     register T tmp = ptr[channel];
00385     
00386     if (minValue > tmp) minValue = tmp;
00387     if (maxValue < tmp) maxValue = tmp;
00388     ptr += S;
00389   }
00390 }
00391 
00392 // ------------------------------------------------------------------------
00393 // --- scale and bias -----------------------------------------------------
00394 // ------------------------------------------------------------------------
00395 
00396 template <int S, class T>
00397 void vuFixelMap<S,T>::scaleAndBias(float scale, T bias)
00398 {
00399   T  *ptr = getBuffer();
00400   dword  len = getWidth() * getHeight() * S;
00401   float minValue = vuFixelType<T>::getMinValue();
00402   float maxValue = vuFixelType<T>::getMaxValue();
00403 
00404   for (;len>0;len--,ptr++) {
00405     register float tmp = (float)(*ptr * scale) + (float)bias;
00406     if (tmp < minValue)
00407       tmp = (T)minValue;
00408     else if (tmp > maxValue)
00409       tmp = (T)maxValue;
00410     *ptr = (T)tmp;
00411   }
00412 }
00413 
00414 template <int S, class T>
00415 void vuFixelMap<S,T>::copyMapToChannel(vuFixelMap<1,T> *map, word channel)
00416 {
00417   if (channel>=S) {
00418     cerr << "Warning: vuFixelMap::copyMapToChannel: channel>= SIZE" << endl;
00419     return;
00420   }
00421   T     *dest = getBuffer();
00422   T     *src  = map->getBuffer();
00423   dword cnt   = getWidth() * getHeight();
00424 
00425   for (dword i=0; i<cnt; i++) {
00426     dest[channel] = *(src++);
00427     dest += S;
00428   }
00429 }
00430 
00431 template <int S, class T>
00432 void vuFixelMap<S,T>::getChannel(vuFixelMap<1,T>* &map, word channel)
00433 {
00434   if (channel>=S) {
00435     cerr << "Warning: vuFixelMap::getChannel: channel>= SIZE" << endl;
00436     return;
00437   }
00438 
00439   if (map == NULL) map = new vuFixelMap<1,T>(getWidth(), getHeight());
00440 
00441   T     *dest = map->getBuffer();
00442   T     *src  = getBuffer();
00443   dword cnt   = getWidth() * getHeight();
00444 
00445   for (dword i=0; i<cnt; i++) {
00446     *(dest++) = src[channel];
00447     src += S;
00448   }
00449 }
00450 
00451 template <int S, class T>
00452 void vuFixelMap<S,T>::clear(vuFixel<S,T> clearColour)
00453 {
00454   T     *ptr = getBuffer();
00455   dword  len = getWidth() * getHeight();
00456 
00457   for (;len>0;len--,ptr++) {
00458     for (int i=0; i<S; i++) {
00459       ptr[i] = clearColour[i];
00460     }
00461   }
00462 }
00463 
00464 template <int S, class T>
00465 bool vuFixelMap<S,T>::hasSameDimensions(vuFixelMap_ST *other)
00466 {
00467   if (other == NULL)
00468     return false;
00469   else if (this->getWidth() != other->getWidth())
00470     return false;
00471   else if (this->getHeight() != other->getHeight())
00472     return false;
00473 
00474   return true;
00475 }
00476 
00477 
00478 
00479 // ------------------------------------------------------------------------
00480 // --- STREAM I/O ---------------------------------------------------------
00481 // ------------------------------------------------------------------------
00482 
00483 template <int S, class T>
00484 ostream &vuFixelMap<S,T>::write(ostream& os)
00485 {
00486   T *ptr = getBuffer();
00487   dword   len = getWidth() * getHeight() * S;
00488 
00489   for (;len>0;len--,ptr++) {
00490     os << (*ptr) << " ";
00491   }
00492   return os;
00493 }
00494 
00495 template <int S, class T>
00496 istream &vuFixelMap<S,T>::read(istream& is)
00497 {
00498   T *ptr = getBuffer();
00499   dword   len = getWidth() * getHeight() * S;
00500 
00501   for (;len>0;len--,ptr++) {
00502     is >> *ptr;
00503   }
00504   return is;
00505 }
00506 
00507 template <int S, class T>
00508 void vuFixelMap<S,T>::_ensureBuffer(dword sizx, dword sizy, const T* source)
00509 {
00510   if (m_buffer == NULL) m_isBufferNewed = true;
00511     
00512   if (!m_isBufferNewed && (sizx != m_width || sizy != m_height)) {
00513     cerr << "ERROR: vuFixelMap._ensureBuffer(): can't change buffer size";
00514     cerr << " , since an external buffer is used" << endl;
00515     throw "vuFixelMap._ensureBuffer(): can't change buffer size, since"
00516       "an external buffer is used";
00517     return;
00518   }
00519 
00520   if ((sizx != m_width) || (sizy != m_height)) {
00521     m_width=sizx;
00522     m_height=sizy;
00523     if ((m_buffer != NULL) && m_isBufferNewed) {
00524       delete m_buffer;
00525       m_buffer = NULL;
00526     }
00527   }
00528 
00529   if ((m_width == 0) || (m_height == 0)) return;
00530 
00531   if(m_buffer == NULL) {
00532     m_buffer        = new T[m_width*m_height*S];
00533     m_isBufferNewed = true;
00534   }
00535 
00536   if (source == NULL) {
00537     T *ptr = m_buffer;
00538     dword  len = m_width*m_height*S;
00539 
00540     for(;len>0;len--,ptr++) *ptr = 0;
00541   }
00542   else {
00543     T        *dest = m_buffer;
00544     const  T *src  = source;
00545     dword    len   = m_width*m_height*S;
00546 
00547     for(;len>0;len--,dest++,src++) *dest= *src;
00548   }
00549 }
00550 
00551 
00552 /* ************************************************************************* */
00553 /* *** rotation ************************************************************ */
00554 /* ************************************************************************* */
00555 
00556 template <int S,class T>
00557 void vuFixelMap<S,T>::_shearX(float shear, vuFixelMap<S,T>* inMap,
00558                               vuFixelMap<S,T>* &outMap)
00559 {
00560   if (inMap == NULL) return;
00561   
00562   dword inHeight  = inMap->getHeight();
00563   dword inWidth   = inMap->getWidth();
00564   dword outHeight = inHeight;
00565   dword outWidth  = (dword)(inHeight * fabs(shear)) + inWidth;
00566 
00567   if (outMap == NULL) {
00568     outMap = new vuFixelMap<S,T>(outWidth, outHeight);
00569   }
00570   else if (outMap->getWidth()!=outWidth || outMap->getHeight()!=outHeight) {
00571     CHECKNDELETE(outMap);
00572     outMap = new vuFixelMap<S,T>(outWidth, outHeight);
00573   }
00574   *outMap = (T)0;
00575 
00576   T left[S];
00577   T oldLeft[S];
00578   T *inBuffer  = inMap->getBuffer();
00579   
00580   for (dword j=0; j<inHeight; j++) { // inHeight
00581     float skew    = shear * j;
00582     int   skewi   = (int)(skew);   // floor
00583     float skewf   = skew - skewi;  // fract
00584     
00585     for (int k=0; k<S; k++) oldLeft[k] = 0;
00586 
00587     dword idx        = (shear >= 0) ? skewi : outWidth + skewi - inWidth;
00588     T     *outBuffer = outMap->getBuffer();
00589 
00590     outBuffer += (j*outWidth + idx) * S;
00591     for (dword i=0; i<inWidth; i++) { //inWidth
00592       for (int k=0; k<S; k++) {
00593         register T     fixel = *(inBuffer++);
00594         register float tmp   = fixel * skewf;
00595 
00596         if (tmp < 0.0f)        tmp = 0.0f;
00597         else if (tmp > 255.0f) tmp = 255.0f;
00598         
00599         left[k]        = (T)tmp;
00600         fixel          = fixel - left[k] + oldLeft[k];
00601         *(outBuffer++) = fixel;
00602         oldLeft[k]     = left[k];
00603       }
00604     }
00605   }
00606 }
00607 
00608 template <int S, class T>
00609 void vuFixelMap<S,T>::_shearY(float shear, vuFixelMap<S,T>* inMap,
00610                               vuFixelMap<S,T>* &outMap)
00611 {
00612   if (inMap == NULL) return;
00613   
00614   dword inHeight  = inMap->getHeight();
00615   dword inWidth   = inMap->getWidth();
00616   dword outHeight = (dword)(inWidth * fabs(shear)) + inHeight;
00617   dword outWidth  = inWidth;
00618 
00619   if (outMap == NULL) {
00620     outMap = new vuFixelMap<S,T>(outWidth, outHeight);
00621   }
00622   else if (outMap->getWidth() != outWidth || outMap->getHeight() != outHeight){
00623     CHECKNDELETE(outMap);
00624     outMap = new vuFixelMap<S,T>(outWidth, outHeight);
00625   }
00626   *outMap = (T)0;
00627 
00628   T old[S];
00629   T *inBuffer  = inMap->getBuffer();
00630   T *outBuffer = outMap->getBuffer();
00631   
00632   for (dword j=0; j<inWidth; j++) { // j<inWidth
00633     float skew    = shear * j;
00634     int   skewi   = (int)(skew);   // floor
00635     float skewf   = skew - skewi;  // fract
00636 
00637     for (int k=0; k<S; k++) old[k] = 0;
00638 
00639     dword idx = (shear >= 0) ? skewi : outHeight + skewi - inHeight;
00640     for (dword i=0; i<inHeight; i++) { // i<inHeight
00641       dword idx1 = (j+(i*inWidth)) * S;
00642       dword idx2 = (j+(idx+i)*outWidth) * S;
00643 
00644       for (int k=0; k<S; k++) { 
00645         register T     fixel = inBuffer[idx1];
00646         register float valF  = fixel * skewf;
00647 
00648         if (valF < 0.0f)        valF = 0.0f;
00649         else if (valF > 255.0f) valF = 255.0f;
00650 
00651         register T     valT  = (T)valF;
00652 
00653         fixel           = fixel - valT + old[k];
00654         outBuffer[idx2] = fixel;
00655         old[k]          = valT;
00656         idx1++;
00657         idx2++;
00658       }
00659     }
00660   }
00661 }
00662 
00663 template <int S, class T>
00664 void vuFixelMap<S,T>::rotate90() 
00665 {
00666   if (m_width != m_height) {
00667     cerr << "rotate90(): width != height, case not implemented!!!" << endl;
00668     throw "rotate90(): width != height, case not implemented!!!";
00669   }
00670   
00671   dword y_step  = m_width * S;
00672   T     *buffer = getBuffer();
00673 
00674   vuFixelMap<S,T> *myMap = new vuFixelMap<S,T>(m_width, m_height);
00675   *myMap = *this; // copy image to myMap
00676   T *ptr = myMap->getBuffer();
00677   *this  = (T)0; // clear image;
00678 
00679   for (dword j=0; j<m_height; j++) {
00680     T *s_ptr = ptr;
00681     T *d_ptr = buffer + (m_width - j) * S;
00682     for (dword i=0; i<m_width; i++) {
00683       for (int k=0; k<S; k++) {
00684         *(d_ptr++) = *(s_ptr++);
00685       }
00686       d_ptr += y_step - S;
00687     }
00688     ptr +=  y_step;
00689   }
00690   CHECKNDELETE(myMap);
00691 }
00692 
00693 template <int S, class T>
00694 void vuFixelMap<S,T>::rotate180() 
00695 {
00696   dword count  = m_width * m_height;
00697   T     *d_ptr = getBuffer();
00698   T     *s_ptr = getBuffer();
00699   d_ptr += (count - 1) * S;
00700 
00701   count = count / 2;
00702   
00703   for (dword i=0; i<count; i++) {
00704     for (dword j=0; j<S; j++) {
00705       T tmp = *s_ptr;
00706       *(s_ptr++) = *d_ptr;
00707       *(d_ptr++) = tmp;
00708     }
00709     d_ptr -= S+S;
00710   }
00711 }
00712 
00713 template <int S, class T>
00714 void vuFixelMap<S,T>::rotate270()
00715 {
00716   rotate180();
00717   rotate90();
00718 }
00719 
00720 
00721 template <int S, class T>
00722 void vuFixelMap<S,T>::rotate(float angle)
00723 {
00724   if (angle == 0) return;
00725   
00726   vuFixelMap<S,T> *map1 = NULL;
00727   vuFixelMap<S,T> *map2 = NULL;
00728 
00729   while (angle > 360) angle -= 360;
00730   while (angle < 0)   angle += 360;
00731 
00732   if (angle >= 315)
00733     angle -= 360;
00734   else if (angle >= 225) {
00735     angle -= 270;
00736     rotate270();
00737   }
00738   else if (angle >= 135) {
00739     angle -= 180;
00740     rotate180();
00741   }
00742   else if (angle >= 45) {
00743     angle -= 90;
00744     rotate90();
00745   }
00746 
00747   angle *= M_PI / 180;
00748   
00749   float alpha = -tan(angle/2);
00750   float beta  = sin(angle);
00751     
00752   // do the three shear steps
00753   _shearX(alpha, this, map1);
00754   _shearY(beta,  map1, map2);
00755   CHECKNDELETE(map1);
00756   _shearX(alpha, map2, map1);
00757   CHECKNDELETE(map2);
00758 
00759   // reduce resulting image to original image size
00760   dword outWidth  = map1->getWidth();
00761   dword outHeight = map1->getHeight();
00762   dword deltaX    = (outWidth  - m_width)  / 2;
00763   dword deltaY    = (outHeight - m_height) / 2;
00764   dword y_step    = outWidth * S;
00765 
00766   T *s_ptr = map1->getBuffer() + y_step * deltaY + deltaX * S;
00767   T *d_ptr = getBuffer();
00768 
00769   for (dword j=0; j<m_height; j++) {
00770     T *ptr = s_ptr;
00771     for (dword i=0; i<m_width; i++) {
00772       for (int k=0; k<S; k++) {
00773         *(d_ptr++) = *(ptr++);
00774       }
00775     }
00776     s_ptr += y_step;
00777   }
00778   CHECKNDELETE(map1);
00779 }

Generated on Wed Dec 15 21:20:34 2004 for vuVolume by  doxygen 1.3.9.1