// // file name: sparse_2.h // written by Ee-Chien Chang // //------------------------- // s p a r s e _ 2 . h //------------------------- // Revised on 10 April 1997 to support non-square, sparse matrix // with non-power-of-2 width and height //------------------------- // E.C.Chang //----------------------------------------------------------------------- // Refer to sparse_2.c for instruction of usage. //----------------------------------------------------------------------- //---------------------------------------------------- // P I X E L //---------------------------------------------------- #ifndef SPARSE_2_H #define SPARSE_2_H class pixel { friend ostream & operator << (ostream&, pixel ); public : pixel ( int R, int G, int B ){r=R; g=G; b=B;} pixel () {r=0; g=0; b=0;} unsigned char r; unsigned char g; unsigned char b; }; //--------------------------------------------------------- // S P A R S E - 2 // two level sparse matrix // // each entry is a 3-byte pixel; //--------------------------------------------------------- class sparse_2 { public: sparse_2( int width, int height, int padding_w, int padding_h, int unit_w, int unit_h, int byte_per_pixel ); ~sparse_2(); int get_non_padding_width () { return ( non_padding_width ); } int get_non_padding_height() { return ( non_padding_height); } pixel &s( int i, int j ); // reference with "sparseness-check". pixel &fs(int i, int j ); // fast reference, without checking. int sparseness ( int x1, int y1, int x2, int y2 ); void reduce_sparseness ( int row, int col ); void reduce_sparseness ( int row, int st_col, int en_col ); int byte_per_pixel; private: pixel **tb; int get_padding_width () { return (width ); } int get_padding_height() { return (height); } int actual_unit_size_w; int actual_unit_size_h; public: int unit_size_w; int log_unit_size_w; int unit_size_mask_w; private: int unit_size_h; int log_unit_size_h; int unit_size_mask_h; int table_size_wi; int table_size_h; int log_table_size_w; int width ; // non_padding_width + padding int height ; int non_padding_width; int non_padding_height; //-------------------------------------------------------------- // The array below should give an approximation of the // sparseness. //--------------------------------------------------------------- int * number_yet_rec ; // int isFull () { return ( total_number_element == // (unit_size*unit_size* // table_size*table_size) ); } int log (int x ); int tt( int i, int j ); int ss( int i, int j ); }; inline int sparse_2::ss ( int ii, int jj ) { return ( ( ( ((ii)&unit_size_mask_h) << log_unit_size_w ) | ((jj)&unit_size_mask_w)) ); } inline int sparse_2::tt ( int index_i, int index_j ) { return (( ( ((index_i)>>log_unit_size_h) << log_table_size_w) | ((index_j)>>log_unit_size_w ) ) ); // return ( ((index_i)/unit_size) *table_size_w + ((index_j)/unit_size) ); } inline pixel& sparse_2::s ( int iii , int jjj ) { #ifdef BOUND_CHECK if ( ( iii >= height) || ( jjj >= width ) || ( iii < 0 ) || ( jjj < 0 ) ) { cout << "s:ERROR OUT OF BOUND " << iii << " " << jjj << endl; cout << " the bound are " << height<< " " << width << endl; exit (0); pixel * P = new pixel (256,0,0); return (*P); } else { #endif if ( !tb [tt((iii),(jjj))]) { tb [tt((iii),(jjj))] = new pixel [ unit_size_h * unit_size_w ]; } return ( tb[tt((iii),(jjj))][ ss((iii),(jjj)) ] ); #ifdef BOUND_CHECK } #endif } inline pixel& sparse_2::fs ( int iii, int jjj ) { #ifdef BOUND_CHECK if ( ( iii >= height) || ( jjj >= width ) || ( iii < 0 ) || ( jjj < 0 ) ) { cout << "fs:ERROR OUT OF BOUD " << iii << " " << jjj << endl; exit(0); return ( *(new pixel (256 ,0,0 ))); } else if (!tb[tt((iii),(jjj))] ) { cout << "fs:NOT DEFINED " << iii << " " << jjj << endl; exit(0); return ( *(new pixel (256 ,0,0 ))); } else { #endif return ( tb[ tt( (iii),(jjj)) ] [ss((iii),(jjj))] ); #ifdef BOUND_CHECK } #endif } inline void sparse_2::reduce_sparseness ( int iii, int jjj ) { number_yet_rec [ tt ( (iii), (jjj) ) ] -= 4; } //---------------------------------------------------------- // C O E F F H I E R // // a hierarchy of sparse_2 // // Data are stored into the structure by two routines: // // void ihaar ( ); // and void fillin_average ( ); // // reference are as usual // //---------------------------------------------------------- class coeff_hier { public : coeff_hier (); coeff_hier ( int Nos_level, int width, int height, int unit_size, int byte_per_p ); ~coeff_hier (); void reInit ( int Nos_level, int width, int height, int unit_size, int byte_per_p ); sparse_2 & operator [] ( int index ) { return *hier[index]; } int ihaar ( item * request_list, int total, int level, int row, unsigned char * data ); void fillin_average ( unsigned char * data ); int nos_level () { return (nos_level_plus_1-1); } private: int nos_level_plus_1; sparse_2** hier; int byte_per_pixel; // redundent information. This value is also // stored in the global variable HEADER. int unit_size; // redundent. kept for fun. }; #endif