00001
00002
00003
00004
00005
00006
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;
00020 int t,b;
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
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 bool isEmpty(void) const {return ((l>=r) || (t>=b));}
00043 bool inbounds(int x,int y) const {
00044 if (x<l || x>=r) return false;
00045 if (y<t || y>=b) return false;
00046 return true;
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
00066
00071 class CkImage {
00072 public:
00073
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
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
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
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
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
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
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
00167
00168 void clear(void);
00169
00170
00171
00172
00173 void put(int sx,int sy,const CkImage &src);
00174
00175
00176
00177
00178 void add(int sx,int sy,const CkImage &src);
00179
00180
00181
00182
00183 void addClip(int sx,int sy,const CkImage &src,const channel_t *clip);
00184
00185
00186 static channel_t *newClip(void);
00187
00188
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
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
00209 void allocate(void) {
00210 int len=getRect().area()*getColors();
00211 allocData=new channel_t[len];
00212 setData(allocData);
00213 }
00214
00215
00216 void deallocate(void) {
00217 delete[] allocData; allocData=0;
00218 setData(allocData);
00219 }
00220
00221
00222 void pup(PUP::er &p);
00223 };
00224 PUPmarshall(CkAllocImage)
00225
00226
00227 #endif
00228