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

FrameBuf16.h

Go to the documentation of this file.
00001 #ifndef _FRAMEBUF16_H_
00002 #define _FRAMEBUF16_H_
00003 
00004 #include <stdio.h>
00005 #include <string.h>
00006 
00007 #include "vuSimpleTypes.h"
00008 #include "Colour.h"
00009 
00010 #define P2_16   65536   // 2^16
00011 #define P2_16_1 65535   // 2^16 - 1
00012 #define FB_WORD
00013 
00014 typedef word fbtype;
00015 
00020 template <int N>
00021 class FrameBuffer
00022 {
00023   friend class Colour<N>;
00024 public:
00025 
00027     FrameBuffer() {m_Buffer = 0; }
00028 
00030     FrameBuffer(int width, int height)
00031     {
00032         m_Buffer = 0;
00033         setSize(width, height);
00034     }
00035 
00037     ~FrameBuffer()
00038     {
00039         freeBuffer();
00040     }
00041 
00043     int getNumberOfChannels() { return N; }
00045     int getHeight() { return m_Height; }
00047     int getWidth() { return m_Width; }
00049     word* getData() { return m_Buffer; }
00050 
00054     bool setSize(int width, int height)
00055     {
00056         freeBuffer();
00057         m_Buffer = new word[ width * height * N];
00058         if(!m_Buffer) return false;
00059         m_Width = width;
00060         m_Height = height;
00061         return true;
00062     }
00063 
00065     bool freeBuffer()
00066     {
00067         if(m_Buffer) delete [] m_Buffer;
00068         m_Buffer = 0;
00069         m_Width = 0;
00070         m_Height = 0;
00071         return true;
00072     }
00073 
00079     bool copy(FrameBuffer<N>& fb, int x, int y)
00080     {
00081         if ((!fb.m_Buffer) ||
00082             (N != fb.getNumberOfChannels()) ||
00083             (x < 0 || y < 0) ||
00084             (x + fb.m_Width>m_Width)||
00085             (y + fb.m_Height>m_Height)) return false;
00086 
00087         int h = m_Height;
00088         int incdst = m_Width * N;
00089         int incsrc = fb.m_Width * N;
00090         word* src = fb.m_Buffer;
00091         word* dst = m_Buffer[y*m_Width + x];
00092         for(h=m_Height; h!=0; h--)
00093           {
00094             memcpy(dst,src,len);
00095             dst += incdst;
00096             src += incsrc;
00097           }
00098 
00099         return true;
00100     }
00101 
00106     bool add(FrameBuffer<N>& fb, int x, int y)
00107     {
00108       if ((!fb.m_Buffer) ||
00109           (x < 0 || y < 0) ||
00110           (x + fb.m_Width>m_Width)||
00111           (y + fb.m_Height>m_Height)) return false;
00112 
00113       int incdst = (m_Width-fb.m_Width) * N;
00114       register word* src = fb.m_Buffer;
00115       register word* dst = &m_Buffer[y*m_Width + x];
00116       for(register int h=m_Height; h!=0; h--)
00117         {
00118           for(register int len = fb.m_Width * N;len!=0;len--)
00119             *(dst++) += *(src++);
00120           dst += incdst;
00121         }
00122         return true;
00123     }
00124 
00125 
00130     bool addColourWithMask(FrameBuffer<1>& fb, Colour<N>& colour, int x, int y)
00131     {
00132         if ((!fb.getData()) ||
00133             (x < 0 || y < 0) ||
00134             (x + fb.getWidth()>m_Width)||
00135             (y + fb.getHeight()>m_Height)) return false;
00136 
00137         word col[] = {word(colour[0]*P2_16_1),
00138                       word(colour[1]*P2_16_1),
00139                       word(colour[2]*P2_16_1),
00140                       word(colour[3]*P2_16_1)};
00141         int cpyh = fb.getHeight();
00142         int cpyw = fb.getWidth();
00143         int incdst = (m_Width-fb.getWidth()) * N;
00144         register word* src = fb.getData();
00145         register word* dst = &m_Buffer[(y*m_Width + x)*N];
00146         for(int h=cpyh; h!=0; h--) {
00147           for(register int len = cpyw; len!=0; len--) {
00148             register word *colval = col;
00149             register word alpha = (dword(*src)*col[3])>>16;
00150             for(register int comp = N-1; comp!=0; comp--, colval++) {
00151               *(dst++) += dword(alpha*(*colval))>>16;           //add weighted colour
00152             }
00153             *(dst++) += word(dword(*(src++))*(*colval)>>16);                    //add alpha
00154           }
00155           dst += incdst;
00156         }
00157         return true;
00158     }
00159 
00164     bool subColourWithMask(FrameBuffer<1>& fb, Colour<N>& colour, int x, int y)
00165     {
00166         if ((!fb.getData()) ||
00167             (x < 0 || y < 0) ||
00168             (x + fb.getWidth()>m_Width)||
00169             (y + fb.getHeight()>m_Height)) return false;
00170 
00171         word col[] = {word(colour[0]*P2_16_1),
00172                       word(colour[1]*P2_16_1),
00173                       word(colour[2]*P2_16_1),
00174                       word(colour[3]*P2_16_1)};
00175         int cpyh = fb.getHeight();
00176         int cpyw = fb.getWidth();
00177         int incdst = (m_Width-fb.getWidth()) * N;
00178         register word* src = fb.getData();
00179         register word* dst = &m_Buffer[(y*m_Width + x)*N];
00180         for(int h=cpyh; h!=0; h--) {
00181           for(register int len = cpyw; len!=0; len--) {
00182             register word *colval = col;
00183             for(register int comp = N-1; comp!=0; comp--, colval++) {
00184               *(dst++) -= word((dword(*src)*(*colval))>>16);            //sub weighted colour
00185             }
00186             *(dst++) -= (dword(*(src++))*(*colval))>>16;                        //sub alpha
00187           }
00188           dst += incdst;
00189         }
00190         return true;
00191     }
00192 
00197     bool addColourWithM1subM2(FrameBuffer<1>& m1, FrameBuffer<1>& m2,
00198                               Colour<N>& colour, const int x, const int y)
00199     {
00200         if ((!m1.getData()) ||
00201             (!m2.getData()) ||
00202             ( m1.getWidth()!=m2.getWidth()) ||
00203             ( m1.getHeight()!=m2.getHeight()) ||
00204             (x < 0 || y < 0) ||
00205             (x + m1.getWidth()>m_Width)||
00206             (y + m1.getHeight()>m_Height)) return false;
00207 
00208         word col[] = {word(colour[0]*P2_16_1),
00209                       word(colour[1]*P2_16_1),
00210                       word(colour[2]*P2_16_1),
00211                       word(colour[3]*P2_16_1)};
00212 
00213         if(N != 4) {
00214           int cpyh = m1.getHeight();
00215           int cpyw = m1.getWidth();
00216           int incdst = (m_Width-m1.getWidth()) * N;
00217           register word* datm1 = m1.getData();
00218           register word* datm2 = m2.getData();
00219           register word* dst = &m_Buffer[(y*m_Width + x)*N];
00220           for(int h=cpyh; h!=0; h--) {
00221             for(register int len = cpyw; len!=0; len--) {
00222               dword a = (dword((*datm1)-(*datm2))*col[N-1])>>16;
00223               for(int comp = 0; comp<N-1; comp++) {
00224                 *(dst++) += (dword(a)*col[comp])>>16;           //add weighted colour
00225               }
00226               *(dst++) += a;                    //add alpha
00227               datm1++; datm2++;
00228             }
00229             dst += incdst;
00230           }
00231         } else {        // N == 4
00232           int cpyh = m1.getHeight();
00233           int cpyw = m1.getWidth();
00234           int incdst = (m_Width-m1.getWidth()) * N;
00235           register word* datm1 = m1.getData();
00236           register word* datm2 = m2.getData();
00237           register word* dst = &m_Buffer[(y*m_Width + x)*N];
00238           for(int h=cpyh; h!=0; h--) {
00239             for(register int len = cpyw; len!=0; len--) {
00240               register dword a = (dword((*datm1)-(*datm2))*col[N-1])>>16;
00241               register word * colcomp = col;
00242               *(dst++) += word((a*(*(colcomp++)))>>16);       //add weighted colour R
00243               *(dst++) += word((a*(*(colcomp++)))>>16);       // G
00244               *(dst++) += word((a*(*(colcomp++)))>>16);       // B
00245               *(dst++) += a;                    //add alpha
00246               datm1++; datm2++;
00247             }
00248             dst += incdst;
00249           }
00250         }
00251         return true;
00252     }
00253 
00255     bool blendOver(FrameBuffer<N>& fb, int x, int y)
00256     {
00257         if ((!fb.getData()) ||
00258             (x < 0 || y < 0) ||
00259             (x + fb.getWidth()>m_Width)||
00260             (y + fb.getHeight()>m_Height)) return false;
00261 
00262         int cpyh = fb.getHeight();
00263         int cpyw = fb.getWidth();
00264         int incdst = (m_Width-fb.getWidth()) * N;
00265         register word* src = fb.getData();
00266         register word* dst = &m_Buffer[(y*m_Width + x)*N];
00267         for(int h=cpyh; h!=0; h--) {
00268           for(register int len = cpyw; len!=0; len--) {
00269             word a2 = P2_16_1-src[N-1];
00270             for(register int comp = 0;
00271                 comp<N-1;
00272                 comp++, dst++, src++) {
00273               *(dst) = word(((dword(*dst)*a2)>>16) + (*src));
00274             }
00275             dst++;      // do nothing with the alpha value.
00276             src++;
00277           }
00278           dst += incdst;
00279         }
00280         return true;
00281     }
00282 
00284     bool blendOver(FrameBuffer<N>& fb)
00285     {
00286         if ((!fb.getData()) ||
00287             (fb.getWidth()!=m_Width)||
00288             (fb.getHeight()!=m_Height)) return false;
00289         if(N!=4) {
00290           int cpylen = fb.getHeight()*fb.getWidth();
00291           register word* src = fb.getData();
00292           register word* dst = m_Buffer;
00293           for(register int len = cpylen; len!=0; len--) {
00294             word a2 = P2_16_1-src[N-1];
00295             for(register int comp = 0;
00296                 comp<N-1;
00297                 comp++, dst++, src++) {
00298               *(dst) = word(((dword(*dst)*a2)>>16) + (*src));
00299             }
00300             dst++;      // do nothing with the alpha value.
00301             src++;
00302           }
00303         } else {
00304           int cpylen = fb.getHeight()*fb.getWidth();
00305           register word* src = fb.getData();
00306           register word* dst = m_Buffer;
00307           for(register int len = cpylen; len!=0; len--) {
00308             register word a2 = ~src[N-1];       //1-x
00309 
00310             *(dst++) = word((dword(dword(*dst)*a2)>>16) + (*src++));    //RGB...
00311             *(dst++) = word((dword(dword(*dst)*a2)>>16) + (*src++));
00312             *(dst++) = word((dword(dword(*dst)*a2)>>16) + (*src++));
00313 
00314             dst++;      // do nothing with the alpha value.
00315             src++;
00316           }
00317         }
00318         return true;
00319     }
00320 
00324     bool blendUnder(FrameBuffer<N>& fb, int x, int y)
00325     {
00326         if ((!fb.getData()) ||
00327             (x < 0 || y < 0) ||
00328             (x + fb.getWidth()>m_Width)||
00329             (y + fb.getHeight()>m_Height)) return false;
00330 
00331         int cpyh = fb.getHeight();
00332         int cpyw = fb.getWidth();
00333         int incdst = (m_Width-fb.getWidth()) * N;
00334         register word* src = fb.getData();
00335         register word* dst = &m_Buffer[(y*m_Width + x)*N];
00336         for(int h=cpyh; h!=0; h--) {
00337           for(register int len = cpyw; len!=0; len--) {
00338             word a = word((dword(src[N-1])*dst[N-1])>>16);
00339             word t = P2_16_1-dst[N-1];
00340             for(register int comp = 0;
00341                 comp<N-1;
00342                 comp++, dst++, src++) {
00343               *(dst) = word((dword(*dst)*t + dword(*src)*a)>>16);
00344             }
00345             *(dst++) *= P2_16_1-(*(src++));     // modify transmittance of layer
00346           }
00347           dst += incdst;
00348         }
00349         return true;
00350     }
00351 
00353     bool blendUnder(FrameBuffer<N>& fb)
00354     {
00355         if ((!fb.getData()) ||
00356             (fb.getWidth()!=m_Width)||
00357             (fb.getHeight()!=m_Height)) return false;
00358         if(N!=4) {
00359           int cpylen = fb.getHeight()*fb.getWidth();
00360           register word* src = fb.getData();
00361           register word* dst = m_Buffer;
00362           for(register int len = cpylen; len!=0; len--) {
00363             register dword t = dword(word(~dst[N-1]));
00364             for(register int comp = 0;
00365                 comp<N-1;comp++) {
00366               *(dst++) += word(dword(*(src++))*t>>16);
00367             }
00368             dst++;      // do nothing with the alpha value.
00369             src++;
00370           }
00371         } else {        // N==4
00372           int cpylen = fb.getHeight()*fb.getWidth();
00373           register word* src = fb.getData();
00374           register word* dst = m_Buffer;
00375           for(register int len = cpylen; len!=0; len--) {
00376             register dword t = dword(word(~dst[N-1]));
00377             if(t == dword(~0) || src[N-1]==0) {
00378               dst += 4;
00379               src += 4;
00380             } else {
00381               *(dst++) += word(dword(*(src++))*t>>16);
00382               *(dst++) += word(dword(*(src++))*t>>16);
00383               *(dst++) += word(dword(*(src++))*t>>16);
00384 
00385               *(dst++) += word(dword(*(src++))*t>>16);
00386             }
00387           }
00388         }
00389         return true;
00390     }
00391 
00393     bool clear(const Colour<N> colour)
00394     {
00395         if(m_Buffer == 0) return false;
00396         word col[] = {word(colour[0]*P2_16_1),
00397                       word(colour[1]*P2_16_1),
00398                       word(colour[2]*P2_16_1),
00399                       word(colour[3]*P2_16_1)};
00400         if(col[0]==0 && col[0]==col[1] && col[0]==col[2] && col[0]==col[3]) {
00401           memset(m_Buffer,0,sizeof(word)*N*m_Width*m_Height);
00402         } else {
00403           word *dst = m_Buffer;
00404           for(register int i = m_Width*m_Height; i!=0; i--) {
00405             memcpy(dst,col,sizeof(word)*N);
00406             dst += N;
00407           }
00408         }
00409         return true;
00410     }
00411 
00413     bool print()
00414     {
00415         if(m_Buffer == 0) return false;
00416         word *buf = m_Buffer;
00417         for(int i = 0; i<m_Height; i++) {
00418             for(int j = 0;j<m_Width; j++) {
00419                 printf("[%3i,%3i] = (%i", j, i, *(buf++));
00420                 for(int c = 1; c<N; c++, buf++){
00421                     printf(", %i", *buf);
00422                 }
00423                 printf(")\n");
00424             }
00425             putchar('\n');
00426         }
00427         return true;
00428     }
00429 
00430 protected:
00431     int m_Width, m_Height; 
00432     word *m_Buffer;     
00433 };
00434 
00435 
00437 typedef FrameBuffer<1> AlphaMask;
00441 typedef FrameBuffer<4> RGBABuffer;
00442 
00443 #endif

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