util/ckimage.h

Go to the documentation of this file.
00001 /*
00002 2D flat image class:
00003 This class represents a 2D raster image; a rectangular 2D
00004 array of pixels.
00005 
00006 Orion Sky Lawlor, olawlor@acm.org, 5/15/2002
00007 */
00008 #ifndef __CK_IMAGE_H
00009 #define __CK_IMAGE_H
00010 
00011 #include "pup.h"
00012 
00013 #undef min
00014 #undef max
00015 inline int min(int a,int b) {return (a<b)?a:b;}
00016 inline int max(int a,int b) {return (a>b)?a:b;}
00017 class CkRect {
00018 public:
00019         int l,r; //X boundaries of rectangle
00020         int t,b; //Y boundaries of rectangle
00021         CkRect() {l=r=t=b=-1;}
00022         CkRect(int l_,int t_,int r_,int b_) 
00023                 :l(l_), r(r_), t(t_), b(b_) {}
00024         CkRect(int w,int h)
00025                 :l(0), r(w), t(0), b(h) {}
00026         //Default copy constructor, assignment operator
00027         int wid(void) const {return r-l;}
00028         int ht(void) const {return b-t;}
00029         int getWidth(void) const {return r-l;}
00030         int getHeight(void) const {return b-t;}
00031         inline int operator==(const CkRect &a) 
00032                 {return l==a.l && r==a.r && t==a.t && b==a.b;}
00033         CkRect getUnion(const CkRect &a) {
00034                 return CkRect(min(l,a.l),min(t,a.t), max(r,a.r),max(b,a.b));
00035         }
00036         CkRect getIntersect(const CkRect &a) {
00037                 return CkRect(max(l,a.l),max(t,a.t), min(r,a.r),min(b,a.b));
00038         }
00039         CkRect getShift(int dx,int dy) {
00040                 return CkRect(l+dx,t+dy,r+dx,b+dy);
00041         }
00042         CmiBool isEmpty(void) const {return (CmiBool)((l>=r) || (t>=b));}
00043         CmiBool inbounds(int x,int y) const {
00044                 if (x<l || x>=r) return CmiFalse;
00045                 if (y<t || y>=b) return CmiFalse;
00046                 return CmiTrue;
00047         }
00048         void makeEmpty(void) {l=t=1000000000; b=r=-1000000000;}
00049         void empty(void) {makeEmpty();}
00050         void add(int x,int y) {
00051                 l=min(x,l); r=max(x,r);
00052                 t=min(y,t); b=max(y,b);
00053         }
00054         void enlarge(int dx,int dy) {
00055                 l-=dx; r+=dx; t-=dy; b+=dy;
00056         }
00057         void zero(void) {l=r=t=b=0;}
00058         int area(void) const {return (r-l)*(b-t);}
00059         
00060         void pup(PUP::er &p) {
00061                 p|l; p|r; p|t; p|b;
00062         }
00063 };
00064 PUPmarshall(CkRect);
00065 
00071 class CkImage {
00072 public:
00073         //This is the data type of a color channel, such as the red channel.
00074         typedef unsigned char channel_t;
00076         enum {channel_max=255};
00077         
00079         typedef enum {
00086                 layout_default=0,
00093                 layout_reversed=1
00094         } layout_t;
00095 private:
00096         int row,colors; 
00097         int layout; 
00098         int wid,ht; 
00099         channel_t *data; 
00100         
00101         CkImage(const CkImage &im) ; 
00102         void operator=(const CkImage &im);
00103 public:
00104         CkImage() {row=colors=wid=ht=-1; setLayout(layout_default); data=NULL;}
00105         CkImage(int w_,int h_,int colors_,channel_t *data_)
00106                 :row(w_*colors_), colors(colors_),
00107                 wid(w_), ht(h_), data(data_) { setLayout(layout_default); }
00108         
00110         channel_t *getData(void) {return data;}
00111         void setData(channel_t *d) {data=d;}
00112         
00113         CkRect getRect(void) const {return CkRect(0,0,wid,ht);}
00115         int getRow(void) const {return row;}
00117         int getColors(void) const {return colors;}
00118         
00120         layout_t getLayout(void) const {return (layout_t)layout;}
00121         void setLayout(layout_t a) {layout=(layout_t)a;}
00122         
00124         int getWidth(void) const {return wid;}
00126         int getHeight(void) const {return ht;}
00127         
00128         //Copy the pixel at src onto the one at dest
00129         inline void copyPixel(const channel_t *src,channel_t *dest) {
00130                 for (int i=0;i<colors;i++)
00131                         dest[i]=src[i];
00132         }
00133         //Set this pixel to this value
00134         inline void setPixel(const channel_t src,channel_t *dest) {
00135                 for (int i=0;i<colors;i++)
00136                         dest[i]=src;
00137         }
00138         //Add the pixel at src to the one at dest, ignoring overflow
00139         inline void addPixel(const channel_t *src,channel_t *dest) {
00140                 for (int i=0;i<colors;i++)
00141                         dest[i]+=src[i];
00142         }
00143         //Add the pixel at src to the one at dest, clipping instead of overflowing
00144         inline void addPixelClip(const channel_t *src,channel_t *dest,
00145                 const channel_t *clip) 
00146         {
00147                 for (int i=0;i<colors;i++)
00148                         dest[i]=clip[(int)dest[i]+(int)src[i]];
00149         }
00150         
00151         
00152         //Get a pixel
00153         inline channel_t *getPixel(int x,int y) {return data+x*colors+y*row;}
00154         inline const channel_t *getPixel(int x,int y) const {return data+x*colors+y*row;}
00155         
00156         
00157         /*
00158          Clip out this subregion of this image-- make us a subregion
00159          */
00160         void window(const CkRect &src) {
00161                 data+=src.t*row+src.l*colors;
00162                 wid=src.wid(); ht=src.ht();
00163         }
00164         
00165         /*
00166         Zero out this image-- make it all black.
00167         */
00168         void clear(void);
00169         
00170         /*
00171          Copy all of src onto this image starting at (x,y).
00172          */
00173         void put(int sx,int sy,const CkImage &src); 
00174         
00175         /*
00176          Add all of src onto this image starting at (x,y).
00177          */
00178         void add(int sx,int sy,const CkImage &src);
00179         /*
00180          Add all of src onto this image starting at (x,y), clipping
00181          values instead of overflowing.
00182          */
00183         void addClip(int sx,int sy,const CkImage &src,const channel_t *clip);
00184         
00185         //Allocate clipping array for above routine
00186         static channel_t *newClip(void);
00187         
00188         //Pup only the image *size*, not the image *data*.
00189         void pup(PUP::er &p) {
00190                 p|wid; p|ht; p|colors; p|layout; p|row;
00191         }
00192 };
00193 PUPmarshall(CkImage);
00194 
00195 
00196 //A heap-allocated image
00197 class CkAllocImage : public CkImage {
00198         channel_t *allocData;
00199 public:
00200         CkAllocImage() {allocData=NULL;}
00201         CkAllocImage(int w,int h,int c)
00202                 :CkImage(w,h,c,new channel_t[w*h*c]) 
00203         {
00204                 allocData=getData();
00205         }
00206         ~CkAllocImage() {delete[] allocData;}
00207         
00208         // Allocate the image with its current size.
00209         void allocate(void) {
00210                 int len=getRect().area()*getColors();
00211                 allocData=new channel_t[len];
00212                 setData(allocData);
00213         }
00214         
00215         // Deallocate the image data (does not change size).
00216         void deallocate(void) {
00217                 delete[] allocData; allocData=0;
00218                 setData(allocData);
00219         }
00220         
00221         //Pup both image size as well as image data.
00222         void pup(PUP::er &p);
00223 };
00224 PUPmarshall(CkAllocImage);
00225 
00226 
00227 #endif
00228 

Generated on Sun Jun 29 13:29:26 2008 for Charm++ by  doxygen 1.5.1