/////////////////////////////////////////////////////////////////////////////////////// // file : kleenex.c // date : november 2019 // author : Alain Greiner /////////////////////////////////////////////////////////////////////////////////////// // This file describes the single thread "kleenex" application. // That makes a copy of a file from one input file to another output file. // - the first implementation uses the read / write syscalls. // - the second implementation uses the mmap / munmap syscalls. /////////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #define IN_FILENAME "misc/philips_1024.raw" #define OUT_FILENAME "misc/philips_1024.new" #define FBF_TYPE 420 #define NPIXELS 1024 #define NLINES 1024 //////////////// int main( void ) { int fd_in; int fd_out; int fbf_width; int fbf_height; int fbf_type; int line; int pixel; int error; unsigned long long start_cycle; unsigned char buf_in[NPIXELS * NLINES]; unsigned char buf_out[NPIXELS * NLINES]; struct stat st; int size_in = NPIXELS * NLINES; int size_out = NPIXELS * NLINES; // get start cycle get_cycle( &start_cycle ); printf("\n[kleenex] starts at cycle %d\n", (unsigned int)start_cycle ); // check frame buffer size fbf_get_config( &fbf_width , &fbf_height , &fbf_type ); if( (NPIXELS != fbf_width) || (NLINES != fbf_height) ) { printf("\n[kleenex error] FBF size [%d,%d] does not fit image size[%d,%d]\n", fbf_width, fbf_height, NPIXELS, NLINES ); exit( 0 ); } if( fbf_type != FBF_TYPE ) { printf("\n[kleenex error] FBF type [%d] does not fit image type [%d]\n", fbf_type, FBF_TYPE); exit( 0 ); } ////////// open input file fd_in = open( IN_FILENAME , O_RDONLY , 0 ); if( fd_in < 0 ) { printf("\n[kleenex error] Cannot open file <%s>\n", IN_FILENAME ); exit( 0 ); } printf("\n[kleenex] open file <%s>\n", IN_FILENAME ); ////////// open output file fd_out = open( OUT_FILENAME , O_CREAT , 0 ); if( fd_out < 0 ) { printf("\n[kleenex error] Cannot open file <%s>\n", OUT_FILENAME ); exit( 0 ); } printf("\n[kleenex] open file <%s>\n", OUT_FILENAME ); ////////// copy input image file to buf_in if( read( fd_in , buf_in , size_in ) != size_in ) { printf("\n[kleenex error] Cannot read file <%s>\n", IN_FILENAME ); exit( 0 ); } printf("\n[kleenex] copied file <%s> to buf_in\n", IN_FILENAME ); ////////// copy buf_in to buf_out for( line = 0 ; line < NLINES ; line++ ) { for( pixel = 0 ; pixel < NPIXELS ; pixel++ ) { unsigned int index = (line*NPIXELS) + pixel; buf_out[index] = buf_in[index]; } } printf("\n[kleenex] moved buf_in to buf_out\n" ); ////////// display output image error = fbf_write( buf_out , size_out , 0 ); if(error) { printf("\n[kleenex error] cannot display buf_out\n"); exit( 0 ); } ////////// copy buf_out to to output image file if( write( fd_out , buf_out , size_out ) != size_out ) { printf("\n[kleenex error] Cannot write file <%s>\n", OUT_FILENAME ); exit( 0 ); } printf("\n[kleenex] copied buf_out to file <%s>\n", OUT_FILENAME ); ///////// check output file size if ( stat( OUT_FILENAME , &st ) == -1) { printf(" error: cannot stat <%s>\n", OUT_FILENAME ); } else { printf("\n[kleenex] size = %x for file <%s>\n", st.st_size , OUT_FILENAME ); } ///////// close input file close( fd_in ); printf("\n[kleenex] closed file <%s>\n", IN_FILENAME ); //////// close output file close( fd_out ); printf("\n[kleenex] closed file <%s>\n", OUT_FILENAME ); exit(0); return 0; } /* Another implementation using using the mmap / munmap syscalls int main( void ) { int fd_in; int fd_out; unsigned int fbf_width; unsigned int fbf_height; unsigned int fbf_type; int line; int pixel; int error; unsigned long long start_cycle; unsigned short * buf_in; unsigned char * buf_out; struct stat st; int size_in = NPIXELS * NLINES; int size_out = NPIXELS * NLINES; // get start cycle get_cycle( &start_cycle ); printf("\n[kleenex] starts at cycle %d\n", (unsigned int)start_cycle ); // check frame buffer size fbf_get_config( &fbf_width , &fbf_height , &fbf_type ); if( (NPIXELS != fbf_width) || (NLINES != fbf_height) ) { printf("\n[kleenex error] FBF size [%d,%d] does not fit image size[%d,%d]\n", fbf_width, fbf_height, NPIXELS, NLINES ); exit( 0 ); } if( fbf_type != FBF_TYPE ) { printf("\n[kleenex error] FBF type [%d] does not fit image type [%d]\n", fbf_type, FBF_TYPE); exit( 0 ); } // open input file fd_in = open( IN_FILENAME , O_RDONLY , 0 ); if( fd_in < 0 ) { printf("\n[kleenex error] Cannot open file <%s>\n", IN_FILENAME ); exit( 0 ); } printf("\n[kleenex] open file <%s>\n", IN_FILENAME ); // open output file fd_out = open( OUT_FILENAME , O_CREAT , 0 ); if( fd_out < 0 ) { printf("\n[kleenex error] Cannot open file <%s>\n", OUT_FILENAME ); exit( 0 ); } printf("\n[kleenex] open file <%s>\n", OUT_FILENAME ); // TODO we must write one byte at the end of the output file // to set the size of this file, and make the mmap() successful // check output file size if ( stat( OUT_FILENAME , &st ) == -1) { printf(" error: cannot stat <%s>\n", OUT_FILENAME ); } else { printf("\n[kleenex] size = %x for file <%s>\n", st.st_size , OUT_FILENAME ); } // map buf_in to input file buf_in = (unsigned short *)mmap( NULL, NPIXELS * NLINES * 2, PROT_READ, MAP_FILE | MAP_SHARED, fd_in, 0 ); // offset if ( buf_in == NULL ) { printf("\n[kleenex error] cannot map buf_in to file %s\n", IN_FILENAME ); exit( 0 ); } printf("\n[kleenex] map buf_in to file <%s>\n", IN_FILENAME ); // map buf_out to output file buf_out = (unsigned char *)mmap( NULL, NPIXELS * NLINES, PROT_WRITE, MAP_FILE | MAP_SHARED, fd_out, 0 ); // offset if ( buf_out == NULL ) { printf("\n[kleenex error] cannot map buf_out to file %s\n", OUT_FILENAME ); exit( 0 ); } printf("\n[kleenex] map buf_out to file <%s>\n", OUT_FILENAME ); // copy buf_in to buf_out for( line = 0 ; line < NLINES ; line++ ) { for( pixel = 0 ; pixel < NPIXELS ; pixel++ ) { unsigned int index = (line*NPIXELS) + pixel; buf_out[index] = buf_in[index]; } } printf("\n[kleenex] moved buf_in to buf_out\n" ); // display output image error = fbf_write( buf_out , size_out , 0 ); if(error) { printf("\n[kleenex error] cannot display buf_out\n"); exit( 0 ); } // unmap buf_in munmap( buf_in , NPIXELS * NLINES * 2 ); // printf("\n[kleenex] unmap buf_in\n" ); // close input file close( fd_in ); printf("\n[kleenex] closed file <%s>\n", IN_FILENAME ); // unmap buf_out munmap( buf_out , NPIXELS * NLINES ); // printf("\n[kleenex] unmap buf_out\n" ); // close output file close( fd_out ); printf("\n[kleenex] closed file <%s>\n", OUT_FILENAME ); exit(0); return 0; } */