#ifndef _Image_H #define _Image_H #include #include #include #include #include #include #include #define __MODULE__ "Image object" struct yuv; struct col { unsigned char b,g,r; col(unsigned char _b, unsigned char _g, unsigned char _r) :r(_r),g(_g),b(_b){} col(yuv YUV); int CREF() const; unsigned int Y() const { int _Y=(66l * r) + (129l * g) + (25l * b); return (_Y>>8)+16; } }; struct yuv { unsigned char Y,Cr,Cb; yuv(unsigned char _Y, unsigned char _Cr, unsigned char _Cb) :Y(_Y),Cr(_Cr),Cb(_Cb){} yuv(col Col); }; struct BitmapInfo: public BITMAPINFOHEADER { int colors[3]; BitmapInfo(){} BitmapInfo(int width, int height, int bpp) { std::memset(this, 0, sizeof(BitmapInfo)); biWidth=width; biHeight=height; biSizeImage=std::abs(width*height)*((bpp+7)/8); biPlanes=1; setBits(bpp); } BitmapInfo(const BITMAPINFOHEADER& hdr) { if(hdr.biSize>sizeof(BITMAPINFOHEADER)+12) throw FATAL("Unknown format"); std::memcpy(this, &hdr, hdr.biSize); } BitmapInfo(const BitmapInfo& bi) { if(bi.biSize>sizeof(BITMAPINFOHEADER)+12) throw FATAL("Unknown format"); std::memcpy(this, &bi, bi.biSize); } BitmapInfo(const BitmapInfo* bi) { if(!bi)throw FATAL("Invalid argument"); if(bi->biSize>sizeof(BITMAPINFOHEADER)+12) throw FATAL("Unknown format"); std::memcpy(this, bi, bi->biSize); } void setBitFields16() { biSize=sizeof(BITMAPINFOHEADER)+12; biCompression=3;//BI_BITFIELDS biBitCount=16; biSizeImage=std::abs((int)(2*biWidth*biHeight)); colors[0]=0xF800; colors[1]=0x07E0; colors[2]=0x001F; } void setBitFields15() { biSize=sizeof(BITMAPINFOHEADER)+12; biCompression=3;//BI_BITFIELDS biBitCount=16; biSizeImage=std::abs((int)(2*biWidth*biHeight)); colors[0]=0x7C00; colors[1]=0x03E0; colors[2]=0x001F; } void setRGB() { biSize=sizeof(BITMAPINFOHEADER); biCompression=0;//BI_RGB } void setBits(int bits) { switch(bits) { case 15: setBitFields15(); break; case 16: setBitFields16(); break; default: setRGB(); biBitCount=bits; break; } } int bpp() const { // if(biCompression==0)return biBitCount; if(biCompression!=3)return biBitCount; if(colors[0]==0x7c00)return 15; return 16; } bool operator==(const BitmapInfo& bi) const { return (biWidth==bi.biWidth) && (biHeight==bi.biHeight) && (biCompression==bi.biCompression) && (bpp() == bi.bpp()); } bool IsRGB() const {return biCompression==0 || biCompression==3;} bool IsYUV() const {return biCompression==fccYUV;} }; /** * This class describes an uncompressed image. * Currently supported formats are 15/16/24/32-bit RGB, * 24-bit YUV ( packed, without subsampling ) and YUY2. * It allows to convert images from 'default' format * ( 24-bit RGB ) to other supported formats. */ class CImage { private: CImage& operator=(CImage& e){return *this;} CImage(const CImage& e){} protected: // std::auto_ptr _info; BitmapInfo* _info; unsigned char* _data; bool _data_owner; int _yuv; int _depth; int _width; int _height; int _bpl; int _bpp; int _bytes; int _pixels; int _refcount; static int imageCounter; static void register_image(){imageCounter++;} static void unregister_image(){imageCounter--;} void fill_members(); void convert(const unsigned char* data, const BitmapInfo* from_fmt); public: /** * Creates new image in format 'header' from specified memory area. * Either allocates its own memory area & copies src data into it, or reuses * parent data. */ CImage(const BitmapInfo* header, unsigned char* data=0, bool copy=true); CImage(unsigned char* data, int width, int height); /** * Creates new image in format 'header' from memory area in format 'from_fmt'. * Performs needed conversions. */ CImage(const BitmapInfo* header, unsigned char* data, const BitmapInfo* from_fmt); /** * Creates new image in format 'header' from image 'im'. */ CImage(const CImage* im, const BitmapInfo* header); /** * Creates new RGB image with depth 'depth' from 24-bit RGB image 'im'. */ CImage(const CImage* im, int depth=-1); void addref(){_refcount++;} void release(){_refcount--;if(!_refcount)delete this;} ~CImage(); unsigned char* data(){return _data;} const unsigned char* data() const{return _data;} unsigned char* at(int i); const unsigned char* at(int i) const; unsigned char* offset(int i); const unsigned char* offset(int i) const; unsigned char* at(int i, int j); int width() const{return _width;} int height() const{return _height;} int bpp() const{return _bpp;} int bpl() const{return _bpl;} int depth() const{return _depth;} int bytes() const{return _bytes;} int pixels() const{return _pixels;} bool direction() const{return !(_info->biHeight<0);} /** * Is it in any of YUV formats? */ int yuv() const{return _yuv;} /** * Is it in format 'hdr'? */ bool is_fmt(const BitmapInfo* hdr) const{return (*_info==*hdr);} BitmapInfo* get_fmt(); const BitmapInfo* get_fmt() const; // BitmapInfo* get_fmt(){return _info.get();} // const BitmapInfo* get_fmt() const{return _info.get();} void ToYUV(int dest_fmt=0); void ToRGB(); void Blur(int range, int from=0); void byteswap(); void *getaddr(); static bool supported(const BITMAPINFOHEADER& bi); static int UnknownColorSpace(int csp); static int BitCount(int csp); protected: void to_16(const unsigned char* from); void to_32(const unsigned char* from); }; #undef __MODULE__ #endif