// // file name: client.C // // written by Ee-Chien Chang. // In USER::USER_DECISION(), modified by Ting-jen Yen // #define COMPRESS_METHOD 2 #include #include #include #include "sparse_mask.h" // for class item #include "sparse_2.h" #include "tcpstream.h" #include "block_item.h" #include "queue.h" #include "GLOBAL_VARIABLE.h" block_item::~block_item() { if (next!=0) { delete next; } } class user_request { public: user_request () { filename =0; blocklist=0; } ~user_request () { if (!blocklist) {delete blocklist;} if (!filename) {delete [] filename; } } int request_type; int compress_type; char * filename; block_item * blocklist; }; //------------- routine in subloop.c ---------------------// int read_ihaar_fillin_data ( tcp_Stream *, block_item * ); void read_header_info ( tcp_Stream * netstream ) { // received headser information. netstream->read_int ( &HEADER.IMAGE_WIDTH ); netstream->read_int ( &HEADER.IMAGE_HEIGHT ); netstream->read_int ( &HEADER.BYTE_PER_PIXEL ); netstream->read_int ( &HEADER.NOS_LEVEL ); int w = HEADER.IMAGE_WIDTH ; int h = HEADER.IMAGE_HEIGHT; for (int i=0; i< HEADER.NOS_LEVEL; i++) { if (w%2) w++; w = w/2; if (h%2) h++; h = h/2; } HEADER.LOWEST_RESOLUTION_WIDTH = w; HEADER.LOWEST_RESOLUTION_HEIGHT= h; } void initialise_shared_data () { // mask_tree T.reInit ( HEADER.NOS_LEVEL, HEADER.IMAGE_WIDTH, HEADER.IMAGE_HEIGHT ); // coeff_hier C.reInit ( HEADER.NOS_LEVEL, HEADER.IMAGE_WIDTH, HEADER.IMAGE_HEIGHT, UNIT_SIZE, HEADER.BYTE_PER_PIXEL ); } void send_request_new ( tcp_Stream * netstream, int type_of_compression, char * filename ) { netstream -> COMPRESSION_TYPE = type_of_compression; netstream -> write_int ( VIEW_NEW_IMAGE ); netstream -> write_int ( 0 ); // version number netstream -> write_int ( netstream->COMPRESSION_TYPE ); } void read_highest_level ( tcp_Stream * netstream ) { int smallest_image = C[ C.nos_level() ] . get_non_padding_width() * C[ C.nos_level() ] . get_non_padding_height()* HEADER.BYTE_PER_PIXEL; unsigned char *ttmp = new unsigned char [ smallest_image ]; netstream->read_byte ( ttmp, (unsigned long)smallest_image ); C.fillin_average ( ttmp ); delete [] ttmp; } // The class "USER" is the method that the network thread // is using to determine user request. In this program, // I just have it get a request from the queue the display // thread keeps putting it. class USER { public: USER () { l = 4; sr = 0; er = 0; sc = 0; ec = 0; } user_request * USER_DECISION (); int first_time; int l; int sr; int er; int sc; int ec; //------- //------- the following value is indentical to the value defined in //------- the class tcpstream. //------- If the value is to be changed, the value in class tcpstream //------- M U S T be modified accordingly //------- const int COMPRESS_NON = 0; const int COMPRESS_LZW = 1; const int COMPRESS_GZ = 2; }; user_request * USER::USER_DECISION () { user_request * tmp = new user_request(); Queue_item *Q_item; Q_item = Q.dequeue(); if (Q_item == NULL) { tmp -> request_type = NO_REQUEST; } else if (Q_item->request_type == VIEW_NEW_IMAGE ) { tmp -> request_type = VIEW_NEW_IMAGE; tmp -> compress_type= COMPRESS_METHOD; tmp -> blocklist = new block_item ( 1,40,80,40,80,0); } else if ( Q_item->request_type == GET_MORE_DATA ) { int t_r; int t_c; tmp -> request_type = GET_MORE_DATA; l = Q_item->level; sr = Q_item-> st_row; t_r = Q_item -> en_row; sc = Q_item-> st_col; t_c = Q_item -> en_col; tmp -> blocklist = new block_item ( l,sr,t_r,sc,t_c,0); } else { cout << "QUIT NOW " << endl; tmp -> request_type = 3; } return tmp; } int send_request ( tcp_Stream *netstream, block_item *req) { for ( block_item * curr_req = req; curr_req != 0; curr_req = curr_req -> next ) { netstream -> write_int ( GET_MORE_DATA ); netstream -> write_int ( curr_req->level ); netstream -> write_int ( curr_req->st_row); netstream -> write_int ( curr_req->en_row); netstream -> write_int ( curr_req->st_col); netstream -> write_int ( curr_req->en_col); } } //------------------------------------------------------- // all usage of semaphore only appears in // 1) the following main program // 2) read_ihaar_fillin_data // 3) netc.c //------------------------------------------------------- void client_network ( tcp_Stream * netstream ) { //------------------ n e t w o r k i n i t i a l i z a t i o n int quit_now = 0; int first_time =1; USER * user = new USER (); while ( ! quit_now ) { //------------ c h e c k w h a t t h e u s e r w a n t user_request * choice = user -> USER_DECISION (); if (choice -> request_type == VIEW_NEW_IMAGE) { send_request_new ( netstream, choice -> compress_type, choice -> filename); if (!first_time) { sem_wait ( &DATA_READY ); } read_header_info ( netstream ); initialise_shared_data (); read_highest_level ( netstream ); //------------- tell the display module i'm already done. sem_post ( &DATA_READY ); first_time =0; //----------------------------------------- } else if (choice -> request_type == GET_MORE_DATA ) { send_request ( netstream, choice -> blocklist ); int t=read_ihaar_fillin_data ( netstream, choice -> blocklist ); // in file subloop.c } else if (choice -> request_type == CLOSE_CONNECTION) { cout << "Quit ...." << endl; quit_now = 1; netstream -> write_int ( CLOSE_CONNECTION); } delete choice; sched_yield(); } }