[723] | 1 | //////////////////////////////////////////////////////////////////////////////////////// |
---|
| 2 | // File : vld.c |
---|
| 3 | // Date : octobre 2015 |
---|
| 4 | // author : Alain Greiner |
---|
| 5 | //////////////////////////////////////////////////////////////////////////////////////// |
---|
| 6 | // This file define the code of the VLD (Variable Length Decoder) thread for the MJPEG |
---|
| 7 | // application. This function makes the analysis of the variable length bit stream, |
---|
| 8 | // resulting from the Huffman entropy coder. |
---|
| 9 | // For each image: |
---|
| 10 | // - It read the Huffman Table parameters from the <in_huff> MWMR channel. |
---|
| 11 | // - It read the bit stream from the <in_data> MWMR channel. |
---|
| 12 | // - It write output pixels (two bytes per pixel) to the <out> MWMR channel. |
---|
| 13 | // It uses MWMR_BUFIO buffers for the input channels, but not for the output channel. |
---|
| 14 | //////////////////////////////////////////////////////////////////////////////////////// |
---|
| 15 | |
---|
| 16 | #include <stdio.h> |
---|
| 17 | #include <stdint.h> |
---|
| 18 | #include <mwmr_channel.h> |
---|
| 19 | #include "mjpeg.h" |
---|
| 20 | |
---|
| 21 | #define HUFF_EOB 0x00 |
---|
| 22 | #define HUFF_ZRL 0xF0 |
---|
| 23 | |
---|
| 24 | // macro to use a shared TTY |
---|
| 25 | #define PRINTF(...) lock_acquire( &tty_lock ); \ |
---|
| 26 | giet_tty_printf(__VA_ARGS__); \ |
---|
| 27 | lock_release( &tty_lock ); |
---|
| 28 | |
---|
| 29 | //////////////////////////////////////////////////////////////////////////////////////// |
---|
| 30 | // bitreader_t : data structure and access functions to analyse a bit-stream. |
---|
| 31 | //////////////////////////////////////////////////////////////////////////////////////// |
---|
| 32 | |
---|
| 33 | typedef struct |
---|
| 34 | { |
---|
| 35 | mwmr_bufio_t* bufio; // associated bufio |
---|
| 36 | uint8_t current; // temporary buffer of one byte |
---|
| 37 | uint8_t available; // number of bits to read in current byte |
---|
| 38 | } bitreader_t; |
---|
| 39 | |
---|
| 40 | //////////////////////////////////////////////////// |
---|
| 41 | // returns <number> bits from the associated bufio. |
---|
| 42 | //////////////////////////////////////////////////// |
---|
| 43 | uint32_t bitreader_get( bitreader_t* stream, |
---|
| 44 | uint32_t number ) |
---|
| 45 | { |
---|
| 46 | uint32_t ret = 0; |
---|
| 47 | |
---|
| 48 | giet_pthread_assert( (number <= 16) , |
---|
| 49 | "ERROR in bitreader_get() : illegal number argument"); |
---|
| 50 | |
---|
| 51 | if (stream->available) |
---|
| 52 | { |
---|
| 53 | stream->current &= (1<<stream->available)-1; |
---|
| 54 | } |
---|
| 55 | |
---|
| 56 | while (number) |
---|
| 57 | { |
---|
| 58 | if ( stream->available == 0 ) // current buffer empty => refill |
---|
| 59 | { |
---|
| 60 | stream->current = mwmr_bufio_read_byte( stream->bufio ); |
---|
| 61 | stream->available = 8; |
---|
| 62 | } |
---|
| 63 | if ( number == stream->available ) |
---|
| 64 | { |
---|
| 65 | stream->available = 0; |
---|
| 66 | ret = (ret<<number) | stream->current; |
---|
| 67 | break; |
---|
| 68 | } |
---|
| 69 | if ( number < stream->available ) |
---|
| 70 | { |
---|
| 71 | ret = (ret<<number) | (stream->current>>(stream->available-number)); |
---|
| 72 | stream->available -= number; |
---|
| 73 | break; |
---|
| 74 | } |
---|
| 75 | if ( number > stream->available ) |
---|
| 76 | { |
---|
| 77 | ret = (ret<<stream->available) | stream->current; |
---|
| 78 | number -= stream->available; |
---|
| 79 | stream->available = 0; |
---|
| 80 | } |
---|
| 81 | } |
---|
| 82 | |
---|
| 83 | return ret; |
---|
| 84 | } |
---|
| 85 | |
---|
| 86 | /////////////////////////////////////////////// |
---|
| 87 | // returns one bit from the associated bufio. |
---|
| 88 | /////////////////////////////////////////////// |
---|
| 89 | uint8_t bitreader_get_one( bitreader_t* stream ) |
---|
| 90 | { |
---|
| 91 | if ( stream->available == 0 ) // current buffer empty => refill |
---|
| 92 | { |
---|
| 93 | stream->current = mwmr_bufio_read_byte( stream->bufio ); |
---|
| 94 | stream->available = 7; |
---|
| 95 | } |
---|
| 96 | else |
---|
| 97 | { |
---|
| 98 | --(stream->available); |
---|
| 99 | } |
---|
| 100 | |
---|
| 101 | uint32_t tmp = 1<<(stream->available); |
---|
| 102 | |
---|
| 103 | return ( !!(stream->current & tmp) ); |
---|
| 104 | } |
---|
| 105 | |
---|
| 106 | ///////////////////////////////////////// |
---|
| 107 | void bitreader_init( bitreader_t* stream, |
---|
| 108 | mwmr_bufio_t* bufio ) |
---|
| 109 | { |
---|
| 110 | stream->available = 0; |
---|
| 111 | stream->current = 0; |
---|
| 112 | stream->bufio = bufio; |
---|
| 113 | } |
---|
| 114 | |
---|
| 115 | ////////////////////////////////////////////////////////////////////////////////////////// |
---|
| 116 | // data structures and access functions for the Huffman tables |
---|
| 117 | // - We have two tables (DC and AC), and 16 possible code lengths (from 1 to 16). |
---|
| 118 | // - DC_Table[12] : 12 possible symbol values for the DC Table. |
---|
| 119 | // - AC_Table[162] : 162 possible symbol values for the AC Table. |
---|
| 120 | // - ValPtr[t][l] : index in Table <t> for the first code of length <l> |
---|
| 121 | // - MinCode[t][l] : min value for codes of length <l> |
---|
| 122 | // - MaxCode[t][l] : max value for codes of length <l> / (-1) if no code of length <l> |
---|
| 123 | ////////////////////////////////////////////////////////////////////////////////////////// |
---|
| 124 | |
---|
| 125 | typedef struct |
---|
| 126 | { |
---|
| 127 | uint8_t* HT[2]; // HT[0] == DC_Table / HT[1] == AC_Table |
---|
| 128 | int32_t MinCode[2][16]; // two types of tables / 16 code lengths |
---|
| 129 | int32_t MaxCode[2][16]; // two types of tables / 16 code lengths |
---|
| 130 | int32_t ValPtr[2][16]; // two types of tables / 16 code lengths |
---|
| 131 | uint8_t DC_Table[12]; // at most 12 values |
---|
| 132 | uint8_t AC_Table[162]; // at most 162 values |
---|
| 133 | } huff_tables_t; |
---|
| 134 | |
---|
| 135 | ///////////////////////////////////////////// |
---|
| 136 | void huff_tables_init( huff_tables_t* huff ) |
---|
| 137 | { |
---|
| 138 | int32_t i, j; |
---|
| 139 | |
---|
| 140 | for ( j=0; j<16; ++j ) |
---|
| 141 | { |
---|
| 142 | for ( i=0; i<2; ++i ) |
---|
| 143 | { |
---|
| 144 | huff->MinCode[i][j] = 0; |
---|
| 145 | huff->MaxCode[i][j] = 0; |
---|
| 146 | huff->ValPtr[i][j] = 0; |
---|
| 147 | } |
---|
| 148 | } |
---|
| 149 | |
---|
| 150 | for ( i=0; i<14; ++i ) huff->DC_Table[i] = 0; |
---|
| 151 | |
---|
| 152 | for ( i=0; i<162; ++i ) huff->AC_Table[i] = 0; |
---|
| 153 | |
---|
| 154 | huff->HT[0] = huff->DC_Table; |
---|
| 155 | huff->HT[1] = huff->AC_Table; |
---|
| 156 | } |
---|
| 157 | |
---|
| 158 | //////////////////////////////////////////// |
---|
| 159 | void huff_tables_dump( huff_tables_t* huff, |
---|
| 160 | uint32_t is_ac ) |
---|
| 161 | { |
---|
| 162 | uint32_t j; |
---|
| 163 | int32_t code; |
---|
| 164 | |
---|
| 165 | uint32_t max = ( is_ac ) ? 162 : 12; |
---|
| 166 | uint32_t type = ( is_ac ) ? 1 : 0; |
---|
| 167 | |
---|
| 168 | if ( is_ac ) { PRINTF("\n AC Huffman Table\n\n") } |
---|
| 169 | else { PRINTF("\n DC Huffman Table\n\n") } |
---|
| 170 | |
---|
| 171 | for ( j = 0; j < 16; j++ ) // j = code_length - 1 |
---|
| 172 | { |
---|
| 173 | PRINTF(" length = %d / mincode = %x / maxcode = %x / valptr = %d\n", |
---|
| 174 | j+1 , huff->MinCode[type][j] , huff->MaxCode[type][j] , huff->ValPtr[type][j] ) |
---|
| 175 | } |
---|
| 176 | |
---|
| 177 | PRINTF("\n") |
---|
| 178 | |
---|
| 179 | for ( j = 0 ; j < 16 ; j++ ) // j == code_length - 1 |
---|
| 180 | { |
---|
| 181 | for ( code = huff->MinCode[type][j] ; code <= huff->MaxCode[type][j] ; code++ ) |
---|
| 182 | { |
---|
| 183 | uint32_t index = huff->ValPtr[type][j] + code - huff->MinCode[type][j]; |
---|
| 184 | |
---|
| 185 | giet_pthread_assert( (index<max) , "ERROR in huff_tables_dump() : overflow"); |
---|
| 186 | |
---|
| 187 | PRINTF(" Symbol[%d] = %x / code[%d] = %x\n", |
---|
| 188 | index , huff->HT[type][index] , index , code ) |
---|
| 189 | } |
---|
| 190 | } |
---|
| 191 | |
---|
| 192 | PRINTF("\n") |
---|
| 193 | } |
---|
| 194 | |
---|
| 195 | //////////////////////////////////////////// |
---|
| 196 | void huff_tables_load( huff_tables_t* huff, |
---|
| 197 | mwmr_bufio_t* bufio ) |
---|
| 198 | { |
---|
| 199 | uint8_t byte; |
---|
| 200 | uint32_t is_ac; // AC Table if non zero |
---|
| 201 | |
---|
| 202 | uint8_t LeavesN; // number of codes of length N (from 1 to 16) |
---|
| 203 | uint8_t LeavesT; // cumulated total number of codes |
---|
| 204 | uint32_t AuxCode; // used to compute code values |
---|
| 205 | |
---|
| 206 | // read length (2 bytes) from bufio |
---|
| 207 | uint32_t length = (uint32_t)mwmr_bufio_read_byte( bufio ); |
---|
| 208 | length = (length<<8) | mwmr_bufio_read_byte( bufio ); |
---|
| 209 | |
---|
| 210 | // read Tc/Th (1 byte) from bufio |
---|
| 211 | // Th must be null, Tc must be 0 or 1 |
---|
| 212 | byte = mwmr_bufio_read_byte( bufio ); |
---|
| 213 | |
---|
| 214 | giet_pthread_assert( ((byte & 0xEF) == 0) , |
---|
| 215 | "ERROR in huff_load_table() : non supported HT header"); |
---|
| 216 | |
---|
| 217 | if (byte == 0) is_ac = 0; |
---|
| 218 | else is_ac = 1; |
---|
| 219 | |
---|
| 220 | uint32_t max_size = ( is_ac ) ? 162 : 12; |
---|
| 221 | |
---|
| 222 | // get the 16 LeavesN values from bufio |
---|
| 223 | uint32_t i; |
---|
| 224 | LeavesT = 0; |
---|
| 225 | AuxCode = 0; |
---|
| 226 | for ( i=0; i<16; i++ ) |
---|
| 227 | { |
---|
| 228 | // read one byte from bufio |
---|
| 229 | LeavesN = mwmr_bufio_read_byte( bufio ); |
---|
| 230 | |
---|
| 231 | huff->ValPtr[is_ac][i] = LeavesT; |
---|
| 232 | huff->MinCode[is_ac][i] = AuxCode<<1; |
---|
| 233 | AuxCode = huff->MinCode[is_ac][i] + LeavesN; |
---|
| 234 | huff->MaxCode[is_ac][i] = (LeavesN) ? (AuxCode - 1) : (-1); |
---|
| 235 | LeavesT += LeavesN; |
---|
| 236 | } |
---|
| 237 | |
---|
| 238 | giet_pthread_assert( (length == 19 + LeavesT) , |
---|
| 239 | "ERROR in huff_load_table() : illegal HT length"); |
---|
| 240 | |
---|
| 241 | giet_pthread_assert( (LeavesT <= max_size) , |
---|
| 242 | "ERROR in huff_load_table() : too much symbols"); |
---|
| 243 | |
---|
| 244 | // get the symbol values from bufio (one byte per symbol) |
---|
| 245 | // complete table with zero values if LeavesT < max_size |
---|
| 246 | for ( i=0 ; i<max_size ; ++i ) |
---|
| 247 | { |
---|
| 248 | if ( i < LeavesT ) huff->HT[is_ac][i] = mwmr_bufio_read_byte( bufio ); |
---|
| 249 | else huff->HT[is_ac][i] = 0; |
---|
| 250 | } |
---|
| 251 | |
---|
| 252 | // align bufio pointer on next item |
---|
| 253 | mwmr_bufio_align( bufio ); |
---|
| 254 | |
---|
| 255 | #if (DEBUG_VLD > 2) |
---|
| 256 | huff_tables_dump( huff , is_ac ); |
---|
| 257 | #endif |
---|
| 258 | |
---|
| 259 | } // end huff_tables_load() |
---|
| 260 | |
---|
| 261 | ////////////////////////////////////////////////////////// |
---|
| 262 | // extract a symbol (8 bits) from an Huffman encoded |
---|
| 263 | // bit-stream, using the specified huffman table |
---|
| 264 | ///////////////////////////////////////////////////////// |
---|
| 265 | int8_t huff_get_symbol( bitreader_t* stream, |
---|
| 266 | huff_tables_t* huff, |
---|
| 267 | int32_t select ) // DC if zero / AC if non zero |
---|
| 268 | { |
---|
| 269 | uint32_t length; |
---|
| 270 | int32_t code = 0; |
---|
| 271 | |
---|
| 272 | uint32_t is_ac = (select) ? 1 : 0; |
---|
| 273 | uint32_t max_size = (select) ? 162 : 12; |
---|
| 274 | |
---|
| 275 | for ( length = 0 ; length < 16 ; ++length ) |
---|
| 276 | { |
---|
| 277 | code = (code<<1) | bitreader_get_one( stream ); |
---|
| 278 | if ( code <= huff->MaxCode[select][length] ) break; |
---|
| 279 | } |
---|
| 280 | |
---|
| 281 | uint32_t index = huff->ValPtr[is_ac][length] + code - huff->MinCode[is_ac][length]; |
---|
| 282 | |
---|
| 283 | giet_pthread_assert( (index <= max_size) , |
---|
| 284 | "ERROR in huff_get_symbol() : Huffman table overflow"); |
---|
| 285 | |
---|
| 286 | return huff->HT[is_ac][index]; |
---|
| 287 | } |
---|
| 288 | |
---|
| 289 | /////////////////////////////////////////////////////////////////////////// |
---|
| 290 | // transform JPEG encoded positive/negative value coded as ( S , nbits ) |
---|
| 291 | // to a standard 16 bits 2's complement number (int16_t). |
---|
| 292 | // - nbits is the magnitude (number of significant bits in S |
---|
| 293 | // - most significant bit in S is 0 for positive / 1 for negative |
---|
| 294 | // - other bits in S define the value in 2**(nbits-1) possible values |
---|
| 295 | /////////////////////////////////////////////////////////////////////////// |
---|
| 296 | static int16_t reformat( uint32_t S , int32_t nbits ) |
---|
| 297 | { |
---|
| 298 | uint32_t ext; |
---|
| 299 | uint32_t sign; |
---|
| 300 | int16_t value; |
---|
| 301 | |
---|
| 302 | if ( nbits == 0 ) return 0; |
---|
| 303 | |
---|
| 304 | sign = !( (1 << (nbits - 1)) & S ); |
---|
| 305 | ext = 0 - (sign << nbits); |
---|
| 306 | value = (S | ext) + sign; |
---|
| 307 | |
---|
| 308 | return value; |
---|
| 309 | } |
---|
| 310 | |
---|
| 311 | //////////////////////////////////////////////////////// |
---|
| 312 | // unpack a 8*8 pixels block with 2 bytes per pixel |
---|
| 313 | ////////////////////////////////////////////////////////// |
---|
| 314 | static int16_t vld_unpack_block( bitreader_t* stream, |
---|
| 315 | mwmr_channel_t* mwmr_out, |
---|
| 316 | huff_tables_t* huff, |
---|
| 317 | int16_t prev_dc ) |
---|
| 318 | { |
---|
| 319 | uint32_t temp; |
---|
| 320 | uint32_t i; |
---|
| 321 | uint32_t run; |
---|
| 322 | uint32_t cat; |
---|
| 323 | int32_t value; |
---|
| 324 | uint8_t symbol; |
---|
| 325 | int16_t buf[64]; // buffer for the 64 resulting pixels (2 bytes per pixel) |
---|
| 326 | |
---|
| 327 | // set default values |
---|
| 328 | for (i = 0; i < 64; i++) buf[i] = 0; |
---|
| 329 | |
---|
| 330 | // compute the DC coefficient |
---|
| 331 | symbol = huff_get_symbol( stream , huff , 0 ); // use DC Huffman Table |
---|
| 332 | |
---|
| 333 | temp = bitreader_get( stream , symbol ); |
---|
| 334 | value = reformat( temp , symbol ); |
---|
| 335 | buf[0] = value + prev_dc; |
---|
| 336 | |
---|
| 337 | #if (DEBUG_VLD > 1) |
---|
| 338 | PRINTF("\nDC[0] = %d / reformat( %x , %d ) = %d\n", buf[0], temp , symbol , value ) |
---|
| 339 | #endif |
---|
| 340 | |
---|
| 341 | // compute the 63 AC coefficients |
---|
| 342 | for (i = 1; i < 64; i++) |
---|
| 343 | { |
---|
| 344 | symbol = huff_get_symbol( stream , huff , 1 ); // use AC Huffman Table |
---|
| 345 | |
---|
| 346 | // in case of HUFF_EOB symbol, all other pixels are zero |
---|
| 347 | if ( symbol == HUFF_EOB ) |
---|
| 348 | { |
---|
| 349 | |
---|
| 350 | #if (DEBUG_VLD > 1) |
---|
| 351 | PRINTF("EOB found at i = %d\n", i ); |
---|
| 352 | #endif |
---|
| 353 | break; |
---|
| 354 | } |
---|
| 355 | |
---|
| 356 | // in case of HUFF_ZRL symbol (0xF0) , 15 next pixels are zero |
---|
| 357 | if (symbol == HUFF_ZRL) |
---|
| 358 | { |
---|
| 359 | i += 15; |
---|
| 360 | continue; |
---|
| 361 | } |
---|
| 362 | |
---|
| 363 | cat = symbol & 0xf; |
---|
| 364 | run = symbol >> 4; |
---|
| 365 | i += run; |
---|
| 366 | |
---|
| 367 | temp = bitreader_get (stream , cat ); |
---|
| 368 | value = reformat( temp , cat ); |
---|
| 369 | buf[i] = value; |
---|
| 370 | |
---|
| 371 | #if (DEBUG_VLD > 2) |
---|
| 372 | PRINTF("AC[%d] = %d / reformat( %x , %d ) = %d\n", i , buf[i] , temp , cat , value ) |
---|
| 373 | #endif |
---|
| 374 | |
---|
| 375 | } |
---|
| 376 | |
---|
| 377 | // write one block to mwmr_out channel ( 2 bytes per pixel) |
---|
| 378 | mwmr_write( mwmr_out, (uint32_t*)buf , 32 ); |
---|
| 379 | |
---|
| 380 | #if (DEBUG_VLD > 1 ) |
---|
| 381 | PRINTF(" %d %d %d %d %d %d %d %d\n" |
---|
| 382 | " %d %d %d %d %d %d %d %d\n" |
---|
| 383 | " %d %d %d %d %d %d %d %d\n" |
---|
| 384 | " %d %d %d %d %d %d %d %d\n" |
---|
| 385 | " %d %d %d %d %d %d %d %d\n" |
---|
| 386 | " %d %d %d %d %d %d %d %d\n" |
---|
| 387 | " %d %d %d %d %d %d %d %d\n" |
---|
| 388 | " %d %d %d %d %d %d %d %d\n", |
---|
| 389 | buf[0] , buf[1] , buf[2] , buf[3] , buf[4] , buf[5] , buf[6] , buf[7] , |
---|
| 390 | buf[8] , buf[9] , buf[10], buf[11], buf[12], buf[13], buf[14], buf[15], |
---|
| 391 | buf[16], buf[17], buf[18], buf[19], buf[20], buf[21], buf[22], buf[23], |
---|
| 392 | buf[24], buf[25], buf[26], buf[27], buf[28], buf[29], buf[30], buf[31], |
---|
| 393 | buf[32], buf[33], buf[34], buf[35], buf[36], buf[37], buf[38], buf[39], |
---|
| 394 | buf[40], buf[41], buf[42], buf[43], buf[44], buf[45], buf[46], buf[47], |
---|
| 395 | buf[48], buf[49], buf[50], buf[51], buf[52], buf[53], buf[54], buf[55], |
---|
| 396 | buf[56], buf[57], buf[58], buf[59], buf[60], buf[61], buf[62], buf[63]) |
---|
| 397 | #endif |
---|
| 398 | |
---|
| 399 | return buf[0]; |
---|
| 400 | |
---|
| 401 | } // end vld_unpack_block() |
---|
| 402 | |
---|
| 403 | |
---|
| 404 | ////////////////////////////////////////////////////////////// |
---|
| 405 | __attribute__ ((constructor)) void vld( uint32_t index ) |
---|
| 406 | ////////////////////////////////////////////////////////////// |
---|
| 407 | { |
---|
| 408 | mwmr_channel_t* mwmr_in_data = demux_2_vld_data[index]; |
---|
| 409 | mwmr_channel_t* mwmr_in_huff = demux_2_vld_huff[index]; |
---|
| 410 | mwmr_channel_t* mwmr_out = vld_2_iqzz[index]; |
---|
| 411 | |
---|
| 412 | huff_tables_t huff; // huffman tables |
---|
| 413 | bitreader_t stream; // bit stream buffer |
---|
| 414 | int16_t prev_dc; // previous block DC value |
---|
| 415 | uint32_t block; // block index |
---|
| 416 | |
---|
| 417 | // get platform parameters |
---|
| 418 | uint32_t x_size; |
---|
| 419 | uint32_t y_size; |
---|
| 420 | uint32_t nprocs; |
---|
| 421 | giet_procs_number( &x_size , &y_size , &nprocs ); |
---|
| 422 | |
---|
| 423 | // get processor coordinates |
---|
| 424 | uint32_t x, y, p; |
---|
| 425 | giet_proc_xyp( &x , &y , &p ); |
---|
| 426 | |
---|
| 427 | // private TTY allocation |
---|
| 428 | // giet_tty_alloc( 0 ); |
---|
| 429 | |
---|
| 430 | PRINTF("\n[MJPEG] thread VLD[%d] starts on P[%d,%d,%d]\n" , index, x, y ,p ) |
---|
| 431 | |
---|
| 432 | // initialise BUFIO for MWMR channel <in_data> |
---|
| 433 | uint8_t in_data_buffer[64]; |
---|
| 434 | mwmr_bufio_t bufio_in_data; |
---|
| 435 | mwmr_bufio_init( &bufio_in_data , in_data_buffer , 64 , 1 , mwmr_in_data ); |
---|
| 436 | |
---|
| 437 | #if (DEBUG_VLD > 1) |
---|
| 438 | PRINTF("\nVLD[%d] <in_data> : &mwmr = %x / &bufio = %x\n", |
---|
| 439 | index , mwmr_in_data , &bufio_in_data ) |
---|
| 440 | #endif |
---|
| 441 | |
---|
| 442 | // initialise BUFIO for MWMR channel <in_huff> |
---|
| 443 | uint8_t in_huff_buffer[64]; |
---|
| 444 | mwmr_bufio_t bufio_in_huff; |
---|
| 445 | mwmr_bufio_init( &bufio_in_huff , in_huff_buffer , 64 , 1 , mwmr_in_huff ); |
---|
| 446 | |
---|
| 447 | #if (DEBUG_VLD > 1) |
---|
| 448 | PRINTF("\nVLD[%d] <in_huff> : &mwmr = %x / &bufio = %x\n", |
---|
| 449 | index , mwmr_in_huff , &bufio_in_huff ) |
---|
| 450 | #endif |
---|
| 451 | |
---|
| 452 | // initialise Huffman Tables |
---|
| 453 | huff_tables_init( &huff ); |
---|
| 454 | |
---|
| 455 | uint32_t image = index; |
---|
| 456 | uint32_t nblocks = nblocks_h * nblocks_w; |
---|
| 457 | |
---|
| 458 | while ( image < MAX_IMAGES ) // one image per iteration |
---|
| 459 | { |
---|
| 460 | // load first Huffman Table from bufio_in_huff |
---|
| 461 | huff_tables_load( &huff , &bufio_in_huff ); |
---|
| 462 | |
---|
| 463 | // load second Huffman Table from bufio_in_huff |
---|
| 464 | huff_tables_load( &huff , &bufio_in_huff ); |
---|
| 465 | |
---|
| 466 | #if (DEBUG_VLD > 1) |
---|
| 467 | PRINTF("\nVLD[%d] load Huffman tables for image %d\n", index , image ) |
---|
| 468 | #endif |
---|
| 469 | |
---|
| 470 | // (re)initializes DC value for each image |
---|
| 471 | prev_dc = 0; |
---|
| 472 | |
---|
| 473 | // (re)align data bufio for each image |
---|
| 474 | mwmr_bufio_align( &bufio_in_data ); |
---|
| 475 | |
---|
| 476 | // (re)initializes bit-stream for each image |
---|
| 477 | bitreader_init( &stream, &bufio_in_data ); |
---|
| 478 | |
---|
| 479 | // loop on the blocks in current image |
---|
| 480 | for ( block = 0 ; block < nblocks ; block++ ) |
---|
| 481 | { |
---|
| 482 | |
---|
| 483 | #if (DEBUG_VLD > 1) |
---|
| 484 | PRINTF("\nVLD[%d] uncompress block %d/%d in image %d\n", index, block, nblocks, image ) |
---|
| 485 | #endif |
---|
| 486 | prev_dc = vld_unpack_block( &stream , mwmr_out, &huff , prev_dc ); |
---|
| 487 | } // end for blocks |
---|
| 488 | |
---|
| 489 | #if DEBUG_VLD |
---|
| 490 | PRINTF("\nVLD[%d] completes image %d at cycle %d\n", index , image , giet_proctime() ) |
---|
| 491 | #endif |
---|
| 492 | image = image + x_size*y_size; |
---|
| 493 | |
---|
| 494 | } // end while on images |
---|
| 495 | |
---|
| 496 | giet_pthread_exit( "vld completed" ); |
---|
| 497 | |
---|
| 498 | } // end vld() |
---|
| 499 | |
---|