a new build option --enable-tracing-commthread
[charm.git] / src / util / ckimage.h
blob8e9b993640e2041ee885d82c5f1e2a6a388a943a
1 /*
2 2D flat image class:
3 This class represents a 2D raster image; a rectangular 2D
4 array of pixels.
6 Orion Sky Lawlor, olawlor@acm.org, 5/15/2002
7 */
8 #ifndef __CK_IMAGE_H
9 #define __CK_IMAGE_H
11 #include "pup.h"
13 #undef min
14 #undef max
15 inline int min(int a,int b) {return (a<b)?a:b;}
16 inline int max(int a,int b) {return (a>b)?a:b;}
17 class CkRect {
18 public:
19 int l,r; //X boundaries of rectangle
20 int t,b; //Y boundaries of rectangle
21 CkRect() {l=r=t=b=-1;}
22 CkRect(int l_,int t_,int r_,int b_)
23 :l(l_), r(r_), t(t_), b(b_) {}
24 CkRect(int w,int h)
25 :l(0), r(w), t(0), b(h) {}
26 //Default copy constructor, assignment operator
27 int wid(void) const {return r-l;}
28 int ht(void) const {return b-t;}
29 int getWidth(void) const {return r-l;}
30 int getHeight(void) const {return b-t;}
31 inline int operator==(const CkRect &a)
32 {return l==a.l && r==a.r && t==a.t && b==a.b;}
33 CkRect getUnion(const CkRect &a) {
34 return CkRect(min(l,a.l),min(t,a.t), max(r,a.r),max(b,a.b));
36 CkRect getIntersect(const CkRect &a) {
37 return CkRect(max(l,a.l),max(t,a.t), min(r,a.r),min(b,a.b));
39 CkRect getShift(int dx,int dy) {
40 return CkRect(l+dx,t+dy,r+dx,b+dy);
42 CmiBool isEmpty(void) const {return (CmiBool)((l>=r) || (t>=b));}
43 CmiBool inbounds(int x,int y) const {
44 if (x<l || x>=r) return CmiFalse;
45 if (y<t || y>=b) return CmiFalse;
46 return CmiTrue;
48 void makeEmpty(void) {l=t=1000000000; b=r=-1000000000;}
49 void empty(void) {makeEmpty();}
50 void add(int x,int y) {
51 l=min(x,l); r=max(x,r);
52 t=min(y,t); b=max(y,b);
54 void enlarge(int dx,int dy) {
55 l-=dx; r+=dx; t-=dy; b+=dy;
57 void zero(void) {l=r=t=b=0;}
58 int area(void) const {return (r-l)*(b-t);}
60 void pup(PUP::er &p) {
61 p|l; p|r; p|t; p|b;
64 PUPmarshall(CkRect)
66 /**
67 This class describes an image, represented as a flat byte array.
68 Pixels are stored first by color (e.g., r,g,b), then by row in the usual
69 raster order.
71 class CkImage {
72 public:
73 //This is the data type of a color channel, such as the red channel.
74 typedef unsigned char channel_t;
75 /// This is the maximum value of a color channel
76 enum {channel_max=255};
78 /// This describes the various data layouts used by image pixels:
79 typedef enum {
80 /**
81 The default layout: ARGB.
82 With one color, pure luminance.
83 With 3 colors, [0]=R, [1]=G, [2]=B.
84 With 4 colors, [0]=A, [1]=R, [2]=G, [3]=B.
86 layout_default=0,
87 /**
88 The "reversed" layout: BGRA.
89 With one color, pure luminance.
90 With 3 colors, [0]=B, [1]=G, [2]=R.
91 With 4 colors, [0]=B, [1]=G, [2]=R, [3]=A.
93 layout_reversed=1
94 } layout_t;
95 private:
96 int row,colors; ///< channel_ts per line, channel_ts per pixel
97 int layout; ///< Image pixel format.
98 int wid,ht; ///< Image size: cols and rows
99 channel_t *data; ///< Image pixel data
101 CkImage(const CkImage &im) ; ///< DO NOT USE
102 void operator=(const CkImage &im);
103 public:
104 CkImage() {row=colors=wid=ht=-1; setLayout(layout_default); data=NULL;}
105 CkImage(int w_,int h_,int colors_,channel_t *data_)
106 :row(w_*colors_), colors(colors_),
107 wid(w_), ht(h_), data(data_) { setLayout(layout_default); }
109 /// Get/set the whole image's data
110 channel_t *getData(void) {return data;}
111 void setData(channel_t *d) {data=d;}
113 CkRect getRect(void) const {return CkRect(0,0,wid,ht);}
114 /// Return the number of channel_t's per row of the image
115 int getRow(void) const {return row;}
116 /// Return the number of colors (channel_t's) per pixel
117 int getColors(void) const {return colors;}
119 /// Get/set the pixel format.
120 layout_t getLayout(void) const {return (layout_t)layout;}
121 void setLayout(layout_t a) {layout=(layout_t)a;}
123 /// Return the number of pixels per row of the image
124 int getWidth(void) const {return wid;}
125 /// Return the number of pixels per column of the image
126 int getHeight(void) const {return ht;}
128 //Copy the pixel at src onto the one at dest
129 inline void copyPixel(const channel_t *src,channel_t *dest) {
130 for (int i=0;i<colors;i++)
131 dest[i]=src[i];
133 //Set this pixel to this value
134 inline void setPixel(const channel_t src,channel_t *dest) {
135 for (int i=0;i<colors;i++)
136 dest[i]=src;
138 //Add the pixel at src to the one at dest, ignoring overflow
139 inline void addPixel(const channel_t *src,channel_t *dest) {
140 for (int i=0;i<colors;i++)
141 dest[i]+=src[i];
143 //Add the pixel at src to the one at dest, clipping instead of overflowing
144 inline void addPixelClip(const channel_t *src,channel_t *dest,
145 const channel_t *clip)
147 for (int i=0;i<colors;i++)
148 dest[i]=clip[(int)dest[i]+(int)src[i]];
152 //Get a pixel
153 inline channel_t *getPixel(int x,int y) {return data+x*colors+y*row;}
154 inline const channel_t *getPixel(int x,int y) const {return data+x*colors+y*row;}
158 Clip out this subregion of this image-- make us a subregion
160 void window(const CkRect &src) {
161 data+=src.t*row+src.l*colors;
162 wid=src.wid(); ht=src.ht();
166 Zero out this image-- make it all black.
168 void clear(void);
171 Copy all of src onto this image starting at (x,y).
173 void put(int sx,int sy,const CkImage &src);
176 Add all of src onto this image starting at (x,y).
178 void add(int sx,int sy,const CkImage &src);
180 Add all of src onto this image starting at (x,y), clipping
181 values instead of overflowing.
183 void addClip(int sx,int sy,const CkImage &src,const channel_t *clip);
185 //Allocate clipping array for above routine
186 static channel_t *newClip(void);
188 //Pup only the image *size*, not the image *data*.
189 void pup(PUP::er &p) {
190 p|wid; p|ht; p|colors; p|layout; p|row;
193 PUPmarshall(CkImage)
196 //A heap-allocated image
197 class CkAllocImage : public CkImage {
198 channel_t *allocData;
199 public:
200 CkAllocImage() {allocData=NULL;}
201 CkAllocImage(int w,int h,int c)
202 :CkImage(w,h,c,new channel_t[w*h*c])
204 allocData=getData();
206 ~CkAllocImage() {delete[] allocData;}
208 // Allocate the image with its current size.
209 void allocate(void) {
210 int len=getRect().area()*getColors();
211 allocData=new channel_t[len];
212 setData(allocData);
215 // Deallocate the image data (does not change size).
216 void deallocate(void) {
217 delete[] allocData; allocData=0;
218 setData(allocData);
221 //Pup both image size as well as image data.
222 void pup(PUP::er &p);
224 PUPmarshall(CkAllocImage)
227 #endif