[660] | 1 | /////////////////////////////////////////////////////////////////////////////////////// |
---|
| 2 | // file : kleenex.c |
---|
| 3 | // date : november 2019 |
---|
| 4 | // author : Alain Greiner |
---|
| 5 | /////////////////////////////////////////////////////////////////////////////////////// |
---|
| 6 | // This file describes the single thread "kleenex" application. |
---|
| 7 | // That makes a copy of a file from one input file to another output file. |
---|
| 8 | // - the first implementation uses the read / write syscalls. |
---|
| 9 | // - the second implementation uses the mmap / munmap syscalls. |
---|
| 10 | /////////////////////////////////////////////////////////////////////////////////////// |
---|
| 11 | |
---|
| 12 | #include <pthread.h> |
---|
| 13 | #include <sys/mman.h> |
---|
| 14 | #include <stdio.h> |
---|
| 15 | #include <stdlib.h> |
---|
| 16 | #include <fcntl.h> |
---|
| 17 | #include <sys/stat.h> |
---|
| 18 | #include <unistd.h> |
---|
| 19 | #include <almosmkh.h> |
---|
| 20 | |
---|
| 21 | #define IN_FILENAME "misc/philips_1024_2.raw" |
---|
| 22 | #define OUT_FILENAME "misc/philips_1024.raw" |
---|
| 23 | #define FBF_TYPE 420 |
---|
| 24 | #define NPIXELS 1024 |
---|
| 25 | #define NLINES 1024 |
---|
| 26 | |
---|
| 27 | //////////////// |
---|
| 28 | int main( void ) |
---|
| 29 | { |
---|
| 30 | int fd_in; |
---|
| 31 | int fd_out; |
---|
| 32 | |
---|
| 33 | unsigned int fbf_width; |
---|
| 34 | unsigned int fbf_height; |
---|
| 35 | unsigned int fbf_type; |
---|
| 36 | |
---|
| 37 | int line; |
---|
| 38 | int pixel; |
---|
| 39 | |
---|
| 40 | int error; |
---|
| 41 | |
---|
| 42 | unsigned long long start_cycle; |
---|
| 43 | |
---|
| 44 | unsigned short buf_in[NPIXELS * NLINES * 2]; |
---|
| 45 | // unsigned char buf_in[NPIXELS * NLINES]; |
---|
| 46 | unsigned char buf_out[NPIXELS * NLINES]; |
---|
| 47 | |
---|
| 48 | struct stat st; |
---|
| 49 | |
---|
| 50 | int size_in = NPIXELS * NLINES * 2; |
---|
| 51 | // int size_in = NPIXELS * NLINES; |
---|
| 52 | int size_out = NPIXELS * NLINES; |
---|
| 53 | |
---|
| 54 | // get start cycle |
---|
| 55 | get_cycle( &start_cycle ); |
---|
| 56 | |
---|
| 57 | printf("\n[kleenex] starts at cycle %d\n", (unsigned int)start_cycle ); |
---|
| 58 | |
---|
| 59 | // check frame buffer size |
---|
| 60 | fbf_get_config( &fbf_width , &fbf_height , &fbf_type ); |
---|
| 61 | |
---|
| 62 | if( (NPIXELS != fbf_width) || (NLINES != fbf_height) ) |
---|
| 63 | { |
---|
| 64 | printf("\n[kleenex error] FBF size [%d,%d] does not fit image size[%d,%d]\n", |
---|
| 65 | fbf_width, fbf_height, NPIXELS, NLINES ); |
---|
| 66 | exit( 0 ); |
---|
| 67 | } |
---|
| 68 | |
---|
| 69 | if( fbf_type != FBF_TYPE ) |
---|
| 70 | { |
---|
| 71 | printf("\n[kleenex error] FBF type [%d] does not fit image type [%d]\n", |
---|
| 72 | fbf_type, FBF_TYPE); |
---|
| 73 | exit( 0 ); |
---|
| 74 | } |
---|
| 75 | |
---|
| 76 | ////////// open input file |
---|
| 77 | fd_in = open( IN_FILENAME , O_RDONLY , 0 ); |
---|
| 78 | |
---|
| 79 | if( fd_in < 0 ) |
---|
| 80 | { |
---|
| 81 | printf("\n[kleenex error] Cannot open file <%s>\n", IN_FILENAME ); |
---|
| 82 | exit( 0 ); |
---|
| 83 | } |
---|
| 84 | |
---|
| 85 | printf("\n[kleenex] open file <%s>\n", IN_FILENAME ); |
---|
| 86 | |
---|
| 87 | ////////// open output file |
---|
| 88 | fd_out = open( OUT_FILENAME , O_CREAT , 0 ); |
---|
| 89 | |
---|
| 90 | if( fd_out < 0 ) |
---|
| 91 | { |
---|
| 92 | printf("\n[kleenex error] Cannot open file <%s>\n", OUT_FILENAME ); |
---|
| 93 | exit( 0 ); |
---|
| 94 | } |
---|
| 95 | |
---|
| 96 | printf("\n[kleenex] open file <%s>\n", OUT_FILENAME ); |
---|
| 97 | |
---|
| 98 | ////////// copy input image file to buf_in |
---|
| 99 | if( read( fd_in , buf_in , size_in ) != size_in ) |
---|
| 100 | { |
---|
| 101 | printf("\n[kleenex error] Cannot read file <%s>\n", IN_FILENAME ); |
---|
| 102 | exit( 0 ); |
---|
| 103 | } |
---|
| 104 | |
---|
| 105 | printf("\n[kleenex] copied file <%s> to buf_in\n", IN_FILENAME ); |
---|
| 106 | |
---|
| 107 | ////////// copy buf_in to buf_out |
---|
| 108 | for( line = 0 ; line < NLINES ; line++ ) |
---|
| 109 | { |
---|
| 110 | for( pixel = 0 ; pixel < NPIXELS ; pixel++ ) |
---|
| 111 | { |
---|
| 112 | unsigned int index = (line*NPIXELS) + pixel; |
---|
| 113 | buf_out[index] = (unsigned char)(buf_in[index]>>8); |
---|
| 114 | // buf_out[index] = buf_in[index]; |
---|
| 115 | } |
---|
| 116 | } |
---|
| 117 | |
---|
| 118 | printf("\n[kleenex] moved buf_in to buf_out\n" ); |
---|
| 119 | |
---|
| 120 | ////////// display output image |
---|
| 121 | error = fbf_write( buf_out , size_out , 0 ); |
---|
| 122 | |
---|
| 123 | if(error) |
---|
| 124 | { |
---|
| 125 | printf("\n[kleenex error] cannot display buf_out\n"); |
---|
| 126 | exit( 0 ); |
---|
| 127 | } |
---|
| 128 | |
---|
| 129 | ////////// copy buf_out to to output image file |
---|
| 130 | if( write( fd_out , buf_out , size_out ) != size_out ) |
---|
| 131 | { |
---|
| 132 | printf("\n[kleenex error] Cannot write file <%s>\n", OUT_FILENAME ); |
---|
| 133 | exit( 0 ); |
---|
| 134 | } |
---|
| 135 | |
---|
| 136 | printf("\n[kleenex] copied buf_out to file <%s>\n", OUT_FILENAME ); |
---|
| 137 | |
---|
| 138 | ///////// check output file size |
---|
| 139 | if ( stat( OUT_FILENAME , &st ) == -1) |
---|
| 140 | { |
---|
| 141 | printf(" error: cannot stat <%s>\n", OUT_FILENAME ); |
---|
| 142 | } |
---|
| 143 | else |
---|
| 144 | { |
---|
| 145 | printf("\n[kleenex] size = %x for file <%s>\n", st.st_size , OUT_FILENAME ); |
---|
| 146 | } |
---|
| 147 | |
---|
| 148 | ///////// close input file |
---|
| 149 | close( fd_in ); |
---|
| 150 | |
---|
| 151 | printf("\n[kleenex] closed file <%s>\n", IN_FILENAME ); |
---|
| 152 | |
---|
| 153 | //////// close output file |
---|
| 154 | close( fd_out ); |
---|
| 155 | |
---|
| 156 | printf("\n[kleenex] closed file <%s>\n", OUT_FILENAME ); |
---|
| 157 | |
---|
| 158 | exit(0); |
---|
| 159 | |
---|
| 160 | return 0; |
---|
| 161 | } |
---|
| 162 | |
---|
| 163 | |
---|
| 164 | /* Another implementation using using the mmap / munmap syscalls |
---|
| 165 | |
---|
| 166 | int main( void ) |
---|
| 167 | { |
---|
| 168 | int fd_in; |
---|
| 169 | int fd_out; |
---|
| 170 | |
---|
| 171 | unsigned int fbf_width; |
---|
| 172 | unsigned int fbf_height; |
---|
| 173 | unsigned int fbf_type; |
---|
| 174 | |
---|
| 175 | int line; |
---|
| 176 | int pixel; |
---|
| 177 | |
---|
| 178 | int error; |
---|
| 179 | |
---|
| 180 | unsigned long long start_cycle; |
---|
| 181 | |
---|
| 182 | |
---|
| 183 | unsigned short * buf_in; |
---|
| 184 | unsigned char * buf_out; |
---|
| 185 | |
---|
| 186 | struct stat st; |
---|
| 187 | |
---|
| 188 | int size_in = NPIXELS * NLINES; |
---|
| 189 | int size_out = NPIXELS * NLINES; |
---|
| 190 | |
---|
| 191 | // get start cycle |
---|
| 192 | get_cycle( &start_cycle ); |
---|
| 193 | |
---|
| 194 | printf("\n[kleenex] starts at cycle %d\n", (unsigned int)start_cycle ); |
---|
| 195 | |
---|
| 196 | // check frame buffer size |
---|
| 197 | fbf_get_config( &fbf_width , &fbf_height , &fbf_type ); |
---|
| 198 | |
---|
| 199 | if( (NPIXELS != fbf_width) || (NLINES != fbf_height) ) |
---|
| 200 | { |
---|
| 201 | printf("\n[kleenex error] FBF size [%d,%d] does not fit image size[%d,%d]\n", |
---|
| 202 | fbf_width, fbf_height, NPIXELS, NLINES ); |
---|
| 203 | exit( 0 ); |
---|
| 204 | } |
---|
| 205 | |
---|
| 206 | if( fbf_type != FBF_TYPE ) |
---|
| 207 | { |
---|
| 208 | printf("\n[kleenex error] FBF type [%d] does not fit image type [%d]\n", |
---|
| 209 | fbf_type, FBF_TYPE); |
---|
| 210 | exit( 0 ); |
---|
| 211 | } |
---|
| 212 | |
---|
| 213 | // open input file |
---|
| 214 | fd_in = open( IN_FILENAME , O_RDONLY , 0 ); |
---|
| 215 | |
---|
| 216 | if( fd_in < 0 ) |
---|
| 217 | { |
---|
| 218 | printf("\n[kleenex error] Cannot open file <%s>\n", IN_FILENAME ); |
---|
| 219 | exit( 0 ); |
---|
| 220 | } |
---|
| 221 | |
---|
| 222 | printf("\n[kleenex] open file <%s>\n", IN_FILENAME ); |
---|
| 223 | |
---|
| 224 | // open output file |
---|
| 225 | fd_out = open( OUT_FILENAME , O_CREAT , 0 ); |
---|
| 226 | |
---|
| 227 | if( fd_out < 0 ) |
---|
| 228 | { |
---|
| 229 | printf("\n[kleenex error] Cannot open file <%s>\n", OUT_FILENAME ); |
---|
| 230 | exit( 0 ); |
---|
| 231 | } |
---|
| 232 | |
---|
| 233 | printf("\n[kleenex] open file <%s>\n", OUT_FILENAME ); |
---|
| 234 | |
---|
| 235 | // TODO we must write one byte at the end of the output file |
---|
| 236 | // to set the size of this file, and make the mmap() successful |
---|
| 237 | |
---|
| 238 | // check output file size |
---|
| 239 | if ( stat( OUT_FILENAME , &st ) == -1) |
---|
| 240 | { |
---|
| 241 | printf(" error: cannot stat <%s>\n", OUT_FILENAME ); |
---|
| 242 | } |
---|
| 243 | else |
---|
| 244 | { |
---|
| 245 | printf("\n[kleenex] size = %x for file <%s>\n", st.st_size , OUT_FILENAME ); |
---|
| 246 | } |
---|
| 247 | |
---|
| 248 | // map buf_in to input file |
---|
| 249 | buf_in = (unsigned short *)mmap( NULL, |
---|
| 250 | NPIXELS * NLINES * 2, |
---|
| 251 | PROT_READ, |
---|
| 252 | MAP_FILE | MAP_SHARED, |
---|
| 253 | fd_in, |
---|
| 254 | 0 ); // offset |
---|
| 255 | if ( buf_in == NULL ) |
---|
| 256 | { |
---|
| 257 | printf("\n[kleenex error] cannot map buf_in to file %s\n", IN_FILENAME ); |
---|
| 258 | exit( 0 ); |
---|
| 259 | } |
---|
| 260 | |
---|
| 261 | printf("\n[kleenex] map buf_in to file <%s>\n", IN_FILENAME ); |
---|
| 262 | |
---|
| 263 | // map buf_out to output file |
---|
| 264 | buf_out = (unsigned char *)mmap( NULL, |
---|
| 265 | NPIXELS * NLINES, |
---|
| 266 | PROT_WRITE, |
---|
| 267 | MAP_FILE | MAP_SHARED, |
---|
| 268 | fd_out, |
---|
| 269 | 0 ); // offset |
---|
| 270 | if ( buf_out == NULL ) |
---|
| 271 | { |
---|
| 272 | printf("\n[kleenex error] cannot map buf_out to file %s\n", OUT_FILENAME ); |
---|
| 273 | exit( 0 ); |
---|
| 274 | } |
---|
| 275 | |
---|
| 276 | printf("\n[kleenex] map buf_out to file <%s>\n", OUT_FILENAME ); |
---|
| 277 | |
---|
| 278 | // copy buf_in to buf_out |
---|
| 279 | for( line = 0 ; line < NLINES ; line++ ) |
---|
| 280 | { |
---|
| 281 | for( pixel = 0 ; pixel < NPIXELS ; pixel++ ) |
---|
| 282 | { |
---|
| 283 | unsigned int index = (line*NPIXELS) + pixel; |
---|
| 284 | buf_out[index] = buf_in[index]; |
---|
| 285 | } |
---|
| 286 | } |
---|
| 287 | |
---|
| 288 | printf("\n[kleenex] moved buf_in to buf_out\n" ); |
---|
| 289 | |
---|
| 290 | // display output image |
---|
| 291 | error = fbf_write( buf_out , size_out , 0 ); |
---|
| 292 | |
---|
| 293 | if(error) |
---|
| 294 | { |
---|
| 295 | printf("\n[kleenex error] cannot display buf_out\n"); |
---|
| 296 | exit( 0 ); |
---|
| 297 | } |
---|
| 298 | |
---|
| 299 | // unmap buf_in |
---|
| 300 | munmap( buf_in , NPIXELS * NLINES * 2 ); |
---|
| 301 | |
---|
| 302 | // printf("\n[kleenex] unmap buf_in\n" ); |
---|
| 303 | |
---|
| 304 | // close input file |
---|
| 305 | close( fd_in ); |
---|
| 306 | |
---|
| 307 | printf("\n[kleenex] closed file <%s>\n", IN_FILENAME ); |
---|
| 308 | |
---|
| 309 | // unmap buf_out |
---|
| 310 | munmap( buf_out , NPIXELS * NLINES ); |
---|
| 311 | |
---|
| 312 | // printf("\n[kleenex] unmap buf_out\n" ); |
---|
| 313 | |
---|
| 314 | // close output file |
---|
| 315 | close( fd_out ); |
---|
| 316 | |
---|
| 317 | printf("\n[kleenex] closed file <%s>\n", OUT_FILENAME ); |
---|
| 318 | |
---|
| 319 | exit(0); |
---|
| 320 | |
---|
| 321 | return 0; |
---|
| 322 | } |
---|
| 323 | |
---|
| 324 | */ |
---|