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( uint32_t index, |
---|
197 | huff_tables_t* huff, |
---|
198 | mwmr_bufio_t* bufio ) |
---|
199 | { |
---|
200 | uint8_t byte; |
---|
201 | uint32_t is_ac; // AC Table if non zero |
---|
202 | |
---|
203 | uint8_t LeavesN; // number of codes of length N (from 1 to 16) |
---|
204 | uint8_t LeavesT; // cumulated total number of codes |
---|
205 | uint32_t AuxCode; // used to compute code values |
---|
206 | |
---|
207 | // read length (2 bytes) from bufio |
---|
208 | uint32_t length = (uint32_t)mwmr_bufio_read_byte( bufio ); |
---|
209 | length = (length<<8) | mwmr_bufio_read_byte( bufio ); |
---|
210 | |
---|
211 | // read Tc/Th (1 byte) from bufio |
---|
212 | // Th must be null, Tc must be 0 or 1 |
---|
213 | byte = mwmr_bufio_read_byte( bufio ); |
---|
214 | |
---|
215 | giet_pthread_assert( ((byte & 0xEF) == 0) , |
---|
216 | "ERROR in huff_load_table() : non supported HT header"); |
---|
217 | |
---|
218 | if (byte == 0) is_ac = 0; |
---|
219 | else is_ac = 1; |
---|
220 | |
---|
221 | uint32_t max_size = ( is_ac ) ? 162 : 12; |
---|
222 | |
---|
223 | // get the 16 LeavesN values from bufio |
---|
224 | uint32_t i; |
---|
225 | LeavesT = 0; |
---|
226 | AuxCode = 0; |
---|
227 | for ( i=0; i<16; i++ ) |
---|
228 | { |
---|
229 | // read one byte from bufio |
---|
230 | LeavesN = mwmr_bufio_read_byte( bufio ); |
---|
231 | |
---|
232 | huff->ValPtr[is_ac][i] = LeavesT; |
---|
233 | huff->MinCode[is_ac][i] = AuxCode<<1; |
---|
234 | AuxCode = huff->MinCode[is_ac][i] + LeavesN; |
---|
235 | huff->MaxCode[is_ac][i] = (LeavesN) ? (AuxCode - 1) : (-1); |
---|
236 | LeavesT += LeavesN; |
---|
237 | } |
---|
238 | |
---|
239 | giet_pthread_assert( (length == 19 + LeavesT) , |
---|
240 | "ERROR in huff_load_table() : illegal HT length"); |
---|
241 | |
---|
242 | giet_pthread_assert( (LeavesT <= max_size) , |
---|
243 | "ERROR in huff_load_table() : too much symbols"); |
---|
244 | |
---|
245 | // get the symbol values from bufio (one byte per symbol) |
---|
246 | // complete table with zero values if LeavesT < max_size |
---|
247 | for ( i=0 ; i<max_size ; ++i ) |
---|
248 | { |
---|
249 | if ( i < LeavesT ) huff->HT[is_ac][i] = mwmr_bufio_read_byte( bufio ); |
---|
250 | else huff->HT[is_ac][i] = 0; |
---|
251 | } |
---|
252 | |
---|
253 | // align bufio pointer on next item |
---|
254 | mwmr_bufio_align( bufio ); |
---|
255 | |
---|
256 | #if (DEBUG_VLD > 3) |
---|
257 | if ( (index == DEBUG_CLUSTER_INDEX) || (DEBUG_CLUSTER_INDEX == 0XFFFFFFFF) ) |
---|
258 | huff_tables_dump( huff , is_ac ); |
---|
259 | #endif |
---|
260 | |
---|
261 | } // end huff_tables_load() |
---|
262 | |
---|
263 | ////////////////////////////////////////////////////////// |
---|
264 | // extract a symbol (8 bits) from an Huffman encoded |
---|
265 | // bit-stream, using the specified huffman table |
---|
266 | ///////////////////////////////////////////////////////// |
---|
267 | int8_t huff_get_symbol( bitreader_t* stream, |
---|
268 | huff_tables_t* huff, |
---|
269 | int32_t select ) // DC if zero / AC if non zero |
---|
270 | { |
---|
271 | uint32_t length; |
---|
272 | int32_t code = 0; |
---|
273 | |
---|
274 | uint32_t is_ac = (select) ? 1 : 0; |
---|
275 | uint32_t max_size = (select) ? 162 : 12; |
---|
276 | |
---|
277 | for ( length = 0 ; length < 16 ; ++length ) |
---|
278 | { |
---|
279 | code = (code<<1) | bitreader_get_one( stream ); |
---|
280 | if ( code <= huff->MaxCode[select][length] ) break; |
---|
281 | } |
---|
282 | |
---|
283 | uint32_t index = huff->ValPtr[is_ac][length] + code - huff->MinCode[is_ac][length]; |
---|
284 | |
---|
285 | giet_pthread_assert( (index <= max_size) , |
---|
286 | "ERROR in huff_get_symbol() : Huffman table overflow"); |
---|
287 | |
---|
288 | return huff->HT[is_ac][index]; |
---|
289 | } |
---|
290 | |
---|
291 | /////////////////////////////////////////////////////////////////////////// |
---|
292 | // transform JPEG encoded positive/negative value coded as ( S , nbits ) |
---|
293 | // to a standard 16 bits 2's complement number (int16_t). |
---|
294 | // - nbits is the magnitude (number of significant bits in S |
---|
295 | // - most significant bit in S is 0 for positive / 1 for negative |
---|
296 | // - other bits in S define the value in 2**(nbits-1) possible values |
---|
297 | /////////////////////////////////////////////////////////////////////////// |
---|
298 | static int16_t reformat( uint32_t S , int32_t nbits ) |
---|
299 | { |
---|
300 | uint32_t ext; |
---|
301 | uint32_t sign; |
---|
302 | int16_t value; |
---|
303 | |
---|
304 | if ( nbits == 0 ) return 0; |
---|
305 | |
---|
306 | sign = !( (1 << (nbits - 1)) & S ); |
---|
307 | ext = 0 - (sign << nbits); |
---|
308 | value = (S | ext) + sign; |
---|
309 | |
---|
310 | return value; |
---|
311 | } |
---|
312 | |
---|
313 | //////////////////////////////////////////////////////// |
---|
314 | // unpack a 8*8 pixels block with 2 bytes per pixel |
---|
315 | ////////////////////////////////////////////////////////// |
---|
316 | static int16_t vld_unpack_block( uint32_t index, // cluster index |
---|
317 | uint32_t image, // image index |
---|
318 | uint32_t block, // block index |
---|
319 | bitreader_t* stream, // input bit stream |
---|
320 | mwmr_channel_t* mwmr_out, // output channel |
---|
321 | huff_tables_t* huff, // Huffman Tables |
---|
322 | int16_t prev_dc ) // previous DC coef |
---|
323 | { |
---|
324 | uint32_t temp; |
---|
325 | uint32_t i; |
---|
326 | uint32_t run; |
---|
327 | uint32_t cat; |
---|
328 | int32_t value; |
---|
329 | uint8_t symbol; |
---|
330 | int16_t buf[64]; // buffer for the 64 resulting pixels (2 bytes per pixel) |
---|
331 | |
---|
332 | // set default values |
---|
333 | for (i = 0; i < 64; i++) buf[i] = 0; |
---|
334 | |
---|
335 | // compute the DC coefficient |
---|
336 | symbol = huff_get_symbol( stream , huff , 0 ); // use DC Huffman Table |
---|
337 | |
---|
338 | temp = bitreader_get( stream , symbol ); |
---|
339 | value = reformat( temp , symbol ); |
---|
340 | buf[0] = value + prev_dc; |
---|
341 | |
---|
342 | #if (DEBUG_VLD > 2) |
---|
343 | if ( (index == DEBUG_CLUSTER_INDEX) || (DEBUG_CLUSTER_INDEX == 0XFFFFFFFF) ) |
---|
344 | { PRINTF("\nVLD[%d] : DC[0] = %d / reformat( %x , %d ) = %d\n", |
---|
345 | index , buf[0], temp , symbol , value ) } |
---|
346 | #endif |
---|
347 | |
---|
348 | // compute the 63 AC coefficients |
---|
349 | for (i = 1; i < 64; i++) |
---|
350 | { |
---|
351 | symbol = huff_get_symbol( stream , huff , 1 ); // use AC Huffman Table |
---|
352 | |
---|
353 | // in case of HUFF_EOB symbol, all other pixels are zero |
---|
354 | if ( symbol == HUFF_EOB ) |
---|
355 | { |
---|
356 | |
---|
357 | #if (DEBUG_VLD > 2) |
---|
358 | if ( (index == DEBUG_CLUSTER_INDEX) || (DEBUG_CLUSTER_INDEX == 0XFFFFFFFF) ) |
---|
359 | { PRINTF("\nVLD[%d] : EOB found at i = %d\n", index , i ) } |
---|
360 | #endif |
---|
361 | break; |
---|
362 | } |
---|
363 | |
---|
364 | // in case of HUFF_ZRL symbol (0xF0) , 15 next pixels are zero |
---|
365 | if (symbol == HUFF_ZRL) |
---|
366 | { |
---|
367 | i += 15; |
---|
368 | continue; |
---|
369 | } |
---|
370 | |
---|
371 | cat = symbol & 0xf; |
---|
372 | run = symbol >> 4; |
---|
373 | i += run; |
---|
374 | |
---|
375 | temp = bitreader_get (stream , cat ); |
---|
376 | value = reformat( temp , cat ); |
---|
377 | buf[i] = value; |
---|
378 | |
---|
379 | #if (DEBUG_VLD > 2) |
---|
380 | if ( (index == DEBUG_CLUSTER_INDEX) || (DEBUG_CLUSTER_INDEX == 0XFFFFFFFF) ) |
---|
381 | { PRINTF("\nVLD[%d] : AC[%d] = %d / reformat( %x , %d ) = %d\n", |
---|
382 | index , i , buf[i] , temp , cat , value ) } |
---|
383 | #endif |
---|
384 | |
---|
385 | } |
---|
386 | |
---|
387 | // write one block to mwmr_out channel ( 2 bytes per pixel) |
---|
388 | mwmr_write( mwmr_out, (uint32_t*)buf , 32 ); |
---|
389 | |
---|
390 | #if (DEBUG_VLD > 1 ) |
---|
391 | if ( (index == DEBUG_CLUSTER_INDEX) || (DEBUG_CLUSTER_INDEX == 0XFFFFFFFF) ) |
---|
392 | { PRINTF("\nVLD[%d] completes block %d/%d in image %d\n" |
---|
393 | " %d %d %d %d %d %d %d %d\n" |
---|
394 | " %d %d %d %d %d %d %d %d\n" |
---|
395 | " %d %d %d %d %d %d %d %d\n" |
---|
396 | " %d %d %d %d %d %d %d %d\n" |
---|
397 | " %d %d %d %d %d %d %d %d\n" |
---|
398 | " %d %d %d %d %d %d %d %d\n" |
---|
399 | " %d %d %d %d %d %d %d %d\n" |
---|
400 | " %d %d %d %d %d %d %d %d\n", |
---|
401 | index , block , nblocks_w*nblocks_h , image , |
---|
402 | buf[0] , buf[1] , buf[2] , buf[3] , buf[4] , buf[5] , buf[6] , buf[7] , |
---|
403 | buf[8] , buf[9] , buf[10], buf[11], buf[12], buf[13], buf[14], buf[15], |
---|
404 | buf[16], buf[17], buf[18], buf[19], buf[20], buf[21], buf[22], buf[23], |
---|
405 | buf[24], buf[25], buf[26], buf[27], buf[28], buf[29], buf[30], buf[31], |
---|
406 | buf[32], buf[33], buf[34], buf[35], buf[36], buf[37], buf[38], buf[39], |
---|
407 | buf[40], buf[41], buf[42], buf[43], buf[44], buf[45], buf[46], buf[47], |
---|
408 | buf[48], buf[49], buf[50], buf[51], buf[52], buf[53], buf[54], buf[55], |
---|
409 | buf[56], buf[57], buf[58], buf[59], buf[60], buf[61], buf[62], buf[63]) } |
---|
410 | #endif |
---|
411 | |
---|
412 | return buf[0]; |
---|
413 | |
---|
414 | } // end vld_unpack_block() |
---|
415 | |
---|
416 | |
---|
417 | ////////////////////////////////////////////////////////////// |
---|
418 | __attribute__ ((constructor)) void vld( uint32_t index ) |
---|
419 | ////////////////////////////////////////////////////////////// |
---|
420 | { |
---|
421 | mwmr_channel_t* mwmr_in_data = demux_2_vld_data[index]; |
---|
422 | mwmr_channel_t* mwmr_in_huff = demux_2_vld_huff[index]; |
---|
423 | mwmr_channel_t* mwmr_out = vld_2_iqzz[index]; |
---|
424 | |
---|
425 | huff_tables_t huff; // huffman tables |
---|
426 | bitreader_t stream; // bit stream buffer |
---|
427 | int16_t prev_dc; // previous block DC value |
---|
428 | uint32_t block; // block index |
---|
429 | |
---|
430 | // get platform parameters |
---|
431 | uint32_t x_size; |
---|
432 | uint32_t y_size; |
---|
433 | uint32_t nprocs; |
---|
434 | giet_procs_number( &x_size , &y_size , &nprocs ); |
---|
435 | |
---|
436 | // get processor coordinates |
---|
437 | uint32_t x, y, p; |
---|
438 | giet_proc_xyp( &x , &y , &p ); |
---|
439 | |
---|
440 | // private TTY allocation |
---|
441 | // giet_tty_alloc( 0 ); |
---|
442 | |
---|
443 | PRINTF("\n[MJPEG] thread VLD[%d] starts on P[%d,%d,%d] / trdid = %x\n", |
---|
444 | index , x , y , p, (uint32_t)trdid_vld[index] ) |
---|
445 | |
---|
446 | |
---|
447 | // initialise BUFIO for MWMR channel <in_data> |
---|
448 | uint8_t in_data_buffer[64]; |
---|
449 | mwmr_bufio_t bufio_in_data; |
---|
450 | mwmr_bufio_init( &bufio_in_data , in_data_buffer , 64 , 1 , mwmr_in_data ); |
---|
451 | |
---|
452 | #if (DEBUG_VLD > 1) |
---|
453 | if ( (index == DEBUG_CLUSTER_INDEX) || (DEBUG_CLUSTER_INDEX == 0XFFFFFFFF) ) |
---|
454 | { PRINTF("\nVLD[%d] <in_data> : &mwmr = %x / &bufio = %x\n", |
---|
455 | index , mwmr_in_data , &bufio_in_data ) } |
---|
456 | #endif |
---|
457 | |
---|
458 | // initialise BUFIO for MWMR channel <in_huff> |
---|
459 | uint8_t in_huff_buffer[64]; |
---|
460 | mwmr_bufio_t bufio_in_huff; |
---|
461 | mwmr_bufio_init( &bufio_in_huff , in_huff_buffer , 64 , 1 , mwmr_in_huff ); |
---|
462 | |
---|
463 | #if (DEBUG_VLD > 1) |
---|
464 | if ( (index == DEBUG_CLUSTER_INDEX) || (DEBUG_CLUSTER_INDEX == 0XFFFFFFFF) ) |
---|
465 | { PRINTF("\nVLD[%d] <in_huff> : &mwmr = %x / &bufio = %x\n", |
---|
466 | index , mwmr_in_huff , &bufio_in_huff ) } |
---|
467 | #endif |
---|
468 | |
---|
469 | // initialise Huffman Tables |
---|
470 | huff_tables_init( &huff ); |
---|
471 | |
---|
472 | uint32_t image = index; |
---|
473 | uint32_t nblocks = nblocks_h * nblocks_w; |
---|
474 | |
---|
475 | while ( image < MAX_IMAGES ) // one image per iteration |
---|
476 | { |
---|
477 | // load first Huffman Table from bufio_in_huff |
---|
478 | huff_tables_load( index, &huff , &bufio_in_huff ); |
---|
479 | |
---|
480 | // load second Huffman Table from bufio_in_huff |
---|
481 | huff_tables_load( index, &huff , &bufio_in_huff ); |
---|
482 | |
---|
483 | #if (DEBUG_VLD > 1) |
---|
484 | if ( (index == DEBUG_CLUSTER_INDEX) || (DEBUG_CLUSTER_INDEX == 0XFFFFFFFF) ) |
---|
485 | { PRINTF("\nVLD[%d] load Huffman tables for image %d\n", index , image ) } |
---|
486 | #endif |
---|
487 | |
---|
488 | // (re)initializes DC value for each image |
---|
489 | prev_dc = 0; |
---|
490 | |
---|
491 | // (re)align data bufio for each image |
---|
492 | mwmr_bufio_align( &bufio_in_data ); |
---|
493 | |
---|
494 | // (re)initializes bit-stream for each image |
---|
495 | bitreader_init( &stream, &bufio_in_data ); |
---|
496 | |
---|
497 | // loop on the blocks in current image |
---|
498 | for ( block = 0 ; block < nblocks ; block++ ) |
---|
499 | { |
---|
500 | |
---|
501 | #if (DEBUG_VLD > 1) |
---|
502 | if ( (index == DEBUG_CLUSTER_INDEX) || (DEBUG_CLUSTER_INDEX == 0XFFFFFFFF) ) |
---|
503 | { PRINTF("\nVLD[%d] uncompress block %d/%d in image %d\n", index, block, nblocks, image ) } |
---|
504 | #endif |
---|
505 | prev_dc = vld_unpack_block( index, |
---|
506 | image, |
---|
507 | block, |
---|
508 | &stream, |
---|
509 | mwmr_out, |
---|
510 | &huff, |
---|
511 | prev_dc ); |
---|
512 | } // end for blocks |
---|
513 | |
---|
514 | #if DEBUG_VLD |
---|
515 | if ( (index == DEBUG_CLUSTER_INDEX) || (DEBUG_CLUSTER_INDEX == 0XFFFFFFFF) ) |
---|
516 | { PRINTF("\nVLD[%d] completes image %d at cycle %d\n", index , image , giet_proctime() ) } |
---|
517 | #endif |
---|
518 | image = image + x_size*y_size; |
---|
519 | |
---|
520 | } // end while on images |
---|
521 | |
---|
522 | giet_pthread_exit( "VLD completed" ); |
---|
523 | |
---|
524 | } // end vld() |
---|
525 | |
---|