#ifndef __CTexture_H__ #define __CTexture_H__ #include "txs_globals.h" namespace TXS { /* * normalized pixel. each r/g/b value is in [0,1] */ struct NormRGB { TXS_REAL r, g, b; NormRGB() { this->r = 0.0; this->g = 0.0; this->b = 0.0; } NormRGB(TXS_REAL r, TXS_REAL g, TXS_REAL b) { this->r = r; this->g = g; this->b = b; } NormRGB plus(const NormRGB &b) { return NormRGB(this->r + b.r, this->g + b.g, this->b + b.b); } /* * Helper func */ static NormRGB averageColors(list &clrs) { NormRGB total(0,0,0); list::iterator clr_iter; for(clr_iter = clrs.begin(); clr_iter != clrs.end(); ++clr_iter) { NormRGB clr = *clr_iter; total = total.plus(clr); } TXS_REAL n = (TXS_REAL)clrs.size(); return NormRGB( total.r / n, total.g / n, total.b / n); } }; struct UVs { TXS_REAL u, v; UVs() { this->u = 0.0; this->v = 0.0; } UVs(TXS_REAL u, TXS_REAL v) : u(u), v(v) { } UVs& trans(const UVs &x) { this->u += x.u; this->v += x.v; return *this; } }; struct UVBox_s { UVs a, b, c, d; UVBox_s& trans(const UVs &x) { this->a.trans(x); this->b.trans(x); this->c.trans(x); this->d.trans(x); return *this; } }; /* a normalized array of pixels, using lib tiff */ class TiffImage { public: TiffImage( char *filename ); TiffImage(int width, int height); ~TiffImage(); int getWidth() { return width; } int getHeight() { return height; } NormRGB getRgbAtUV(UVs uv); NormRGB getRgbAtUVNoWrap(UVs uv); void readFromTiff(char *filename); bool writeToTiff(char *filename); void fill(const NormRGB &c) { int n = this->width * this->height; for(int i = 0; i < n; ++i) { this->rgb[i] = c; } } /* * (0,0) is the BOTTOM left of the image, not the TOP left */ void setRGB(int x, int y, const NormRGB &rgb) { int i = this->getIndexForXY(x,y); this->rgb[i] = rgb; } /* * This doesn't exactly draw a diagonal cross. * like, the cross will only be diagonal if w == h * but it's useful for debugging. */ void drawDiagonalCross(const NormRGB &rgb) { for(int i = 0; i < this->height; ++i) { this->setRGB(i, i, rgb); this->setRGB(this->width - i - 1, i, rgb); } } NormRGB &getRGB(int i) { return this->rgb[i]; } NormRGB &getRGB(int x, int y) { if(x < 0 || y < 0 || x >= width || y >= height) { __ERROR__("bad x,y pixel coords: " << x << " " << y); } int i = this->getIndexForXY(x,y); return this->rgb[i]; } TXS_REAL calcRegionSSD(TiffImage &that, int x, int y, int midOfs = -1); void getBestMatchingRegion(TiffImage &img, int &xOut, int &yOut, int midOfs); int getIndexForXY(int x, int y) { return y * this->width + x; } /* * returns the UV-coords of the negative corner * of the given pixel */ UVs getNegCornerUV(int x, int y) { assert(x >= 0); assert(x < this->width); assert(y >= 0); assert(y < this->height); return UVs( (TXS_REAL)x / (TXS_REAL)this->width, (TXS_REAL)y / (TXS_REAL)this->height); } UVs getCenterUV(int x, int y) { UVs neg = this->getNegCornerUV(x,y); UVs pos = this->getNegCornerUV(x+1,y+1); return UVs( (neg.u + pos.u) * 0.5, (neg.v + pos.v) * 0.5); } UVBox_s getUvBox(int x, int y) { UVBox_s box; box.a = this->getNegCornerUV(x,y); box.b = this->getNegCornerUV(x+1,y); box.c = this->getNegCornerUV(x+1,y+1); box.d = this->getNegCornerUV(x,y+1); return box; } private: NormRGB *rgb; int width, height; }; } ostream& operator<<(ostream &s, TXS::NormRGB &p); ostream& operator<<(ostream &s, TXS::UVs &x); #endif