00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "vld.h"
00012 #include <stdio.h>
00013
00014
00015
00016
00017
00018 #define HUFF_EOB 0x00
00019 #define HUFF_ZRL 0xF0
00020
00021 #define HUFF_ID(class, id) (2*(class)+(id))
00022
00023 #define DC_CLASS 0
00024 #define AC_CLASS 1
00025
00026 VLD::VLD(
00027 const Id& n,
00028 In<Marker>& markerIn,
00029 In<Bits>& restartIntervalBitsIn,
00030 In<Bits>& Cin,
00031 In<VYAimageDepth>& imageDepthIn,
00032 In<VYAimageComponent>& imageComponentIdIn,
00033 In<VYAimageH>& imageHIn,
00034 In<VYAimageV>& imageVIn,
00035 In<VYAimageDepth>& scanDepthIn,
00036 In<VYAimageComponent>& scanComponentIdIn,
00037 In<Bits>& HuffmanTableIn,
00038 In<VYAid>& HuffmanTableIdIn,
00039 Out<VYApixel>& Cout)
00040 :
00041 Process(n),
00042 markerInP( id("markerInP"), markerIn),
00043 restartIntervalBitsInP( id("restartIntervalBitsInP"), restartIntervalBitsIn),
00044 CinP( id("CinP"), Cin),
00045 imageDepthInP( id("imageDepthInP"), imageDepthIn),
00046 imageComponentIdInP( id("imageComponentIdInP"), imageComponentIdIn),
00047 imageHInP( id("imageHInP"), imageHIn),
00048 imageVInP( id("imageVInP"), imageVIn),
00049 scanDepthInP( id("scanDepthInP"), scanDepthIn),
00050 scanComponentIdInP( id("scanComponentIdInP"), scanComponentIdIn),
00051 HuffmanTableInP( id("HuffmanTableInP"), HuffmanTableIn),
00052 HuffmanTableIdInP( id("HuffmanTableIdInP"), HuffmanTableIdIn),
00053 CoutP( id("CoutP"), Cout)
00054 {
00055 window = 0;
00056 restartInterval = 0;
00057 }
00058
00059 void VLD::abort()
00060 {
00061 printf("\n");
00062 printf("%s:\n", fullName());
00063 printf("\tERROR:\tAbnormal end of decompression process!\n");
00064 exit(1);
00065 }
00066
00067 #define GLOB_SIZE 32
00068
00069
00070 #define MAX_SIZE(group) ((group)?384:64)
00071
00072 #define MAX_CELLS(group) (MAX_SIZE(group) - GLOB_SIZE)
00073
00074
00075
00076
00077
00078 #define GOOD_NODE_FLAG 0x100
00079 #define GOOD_LEAF_FLAG 0x200
00080 #define BAD_LEAF_FLAG 0x300
00081 #define SPECIAL_FLAG 0x000
00082 #define HUFF_FLAG_MSK 0x300
00083
00084 #define HUFF_FLAG(c) ((c) & HUFF_FLAG_MSK)
00085 #define HUFF_VALUE(c) ((unsigned char)( (c) & (~HUFF_FLAG_MSK) ))
00086
00087
00088
00089
00090
00091 static unsigned int DC_Table0[MAX_SIZE(DC_CLASS)],
00092 DC_Table1[MAX_SIZE(DC_CLASS)];
00093
00094 static unsigned int AC_Table0[MAX_SIZE(AC_CLASS)],
00095 AC_Table1[MAX_SIZE(AC_CLASS)];
00096
00097 static unsigned int *HTable[4] = {
00098 &DC_Table0[0], &DC_Table1[0],
00099 &AC_Table0[0], &AC_Table1[0]
00100 };
00101
00102
00103
00104
00105
00106
00107 int VLD::load_huff_tables()
00108 {
00109 Bits aux;
00110 Bits c;
00111 int size, group, id;
00112 int LeavesN, NodesN, CellsN;
00113 int MaxDepth, i, k, done;
00114 int NextCellPt;
00115 int NextLevelPt;
00116 unsigned int flag;
00117
00118 size = get_size();
00119
00120 size -= 2;
00121
00122 while(size>0)
00123 {
00124 read(HuffmanTableInP, c);
00125 aux = c;
00126 group = first_quad(aux);
00127 id = second_quad(aux);
00128 if (id>1)
00129 {
00130 printf("%s:\n\tERROR:\tBad HTable identity %d!\n",fullName(),id);
00131 return -1;
00132 }
00133 id = HUFF_ID(group, id);
00134 #ifdef VERBOSE
00135 printf("%s:\n\tLoading Huffman Table %d\n", fullName(), id);
00136 #endif
00137 size--;
00138 CellsN = NodesN = 1;
00139 LeavesN = 0;
00140
00141 for(i=0; i<MAX_CELLS(group); i++)
00142 {
00143 HTable[id][i] = SPECIAL_FLAG;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 MaxDepth = 0;
00156 for(i=0; i<16; i++)
00157 {
00158 read(HuffmanTableInP, c);
00159 LeavesN = HTable[id][MAX_SIZE(group)-2*i-1] = c;
00160 CellsN = 2*NodesN;
00161 NodesN = HTable[id][MAX_SIZE(group)-2*i-2] = CellsN-LeavesN;
00162 if (LeavesN) MaxDepth = i;
00163 }
00164 size-=16;
00165
00166
00167
00168
00169 HTable[id][0] = 1 | GOOD_NODE_FLAG;
00170
00171 NextCellPt = 2;
00172 i = 0;
00173
00174 done = 0;
00175
00176 while (i<= MaxDepth)
00177 {
00178
00179
00180 LeavesN = HTable[id][MAX_SIZE(group)-2*i-1];
00181 for(k = 0; k<LeavesN; k++)
00182 {
00183 if (!done)
00184 {
00185 read(HuffmanTableInP, c);
00186 HTable[id][NextCellPt++] = c | GOOD_LEAF_FLAG;
00187 if (NextCellPt >= MAX_CELLS(group))
00188 {
00189 done = 1;
00190 printf("%s:\n\tWARNING:\tTruncating Table at depth %d\n",fullName(), i+1);
00191 }
00192 } else {
00193 read(HuffmanTableInP, c);
00194 }
00195 }
00196 size -= LeavesN;
00197
00198 if (done || (i == MaxDepth)) { i++; continue; }
00199
00200
00201
00202 NodesN = HTable[id][MAX_SIZE(group)-2*i-2];
00203
00204 NextLevelPt = NextCellPt+NodesN;
00205 for(k = 0; k<NodesN; k++)
00206 {
00207 if (NextCellPt >= MAX_CELLS(group)) { done = 1; break; }
00208
00209 flag = ((NextLevelPt|1)>=MAX_CELLS(group))?BAD_LEAF_FLAG:GOOD_NODE_FLAG;
00210
00211 HTable[id][NextCellPt++] = (NextLevelPt/2) | flag;
00212 NextLevelPt += 2;
00213 }
00214
00215 i++;
00216 }
00217 #ifdef VERBOSE
00218 printf("%s:\n\tUsing %d words of table memory\n", fullName(), NextCellPt);
00219 #endif
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 return 0;
00244 }
00245
00246 unsigned int VLD::get_size(void)
00247 {
00248 Bits firstc;
00249 Bits nextc;
00250 unsigned int size;
00251
00252 read(HuffmanTableInP, firstc);
00253 size = firstc;
00254 read(HuffmanTableInP, nextc);
00255 size = (size<<8) | nextc;
00256
00257 return size;
00258 }
00259
00260 void VLD::main()
00261 {
00262 VYAimageDepth nrOfImageComponents;
00263 VYAimageComponent* imageComponent;
00264 VYAimageH* H;
00265 VYAimageV* V;
00266 Marker marker;
00267 unsigned int numberOfMCU;
00268
00269 read(markerInP, marker);
00270 while (marker != SOS_MK)
00271 {
00272 if (marker == DHT_MK)
00273 {
00274 load_huff_tables();
00275 } else
00276 if (marker == DRI_MK)
00277 {
00278 load_restart_interval();
00279 }
00280 read(markerInP, marker);
00281 }
00282
00283 read(imageDepthInP, nrOfImageComponents);
00284
00285 imageComponent = new VYAimageComponent[nrOfImageComponents];
00286 H = new VYAimageH[nrOfImageComponents];
00287 V = new VYAimageV[nrOfImageComponents];
00288
00289 for(unsigned int i=0; i<nrOfImageComponents; i++)
00290 {
00291 read(imageComponentIdInP, imageComponent[i]);
00292 read(imageHInP, H[i]);
00293 read(imageVInP, V[i]);
00294 }
00295
00296 while (true)
00297 {
00298 VYAimageDepth nrOfScanComponents;
00299 VYAimageComponent* scanComponentId;
00300 VYAid* huffmanTableId;
00301 VYApixel* prediction;
00302
00303 read(scanDepthInP, nrOfScanComponents);
00304
00305 scanComponentId = new VYAimageComponent[nrOfScanComponents];
00306 huffmanTableId = new VYAid[nrOfScanComponents];
00307 prediction = new VYApixel[nrOfScanComponents];
00308
00309 for(unsigned int i=0; i<nrOfScanComponents; i++)
00310 {
00311 read(scanComponentIdInP, scanComponentId[i]);
00312 read(HuffmanTableIdInP, huffmanTableId[i]);
00313 prediction[i] = 0;
00314 }
00315
00316 bit_count = 0;
00317 numberOfMCU = 0;
00318 while (true)
00319 {
00320 for(unsigned int i=0; i<nrOfScanComponents; i++)
00321 {
00322 int hi = H[scanComponentId[i]];
00323 int vi = V[scanComponentId[i]];
00324 VYApixel value;
00325 unsigned int cat, run;
00326 unsigned char DC_HT = first_quad(huffmanTableId[i]);
00327 unsigned char AC_HT = second_quad(huffmanTableId[i]);
00328 unsigned char symbol;
00329
00330 for(int j=0; j<hi; j++)
00331 {
00332 for(int k=0; k<vi; k++)
00333 {
00334
00335 symbol = get_symbol(HUFF_ID(DC_CLASS, DC_HT));
00336 value = reformat(get_bits(symbol), symbol);
00337 value += prediction[scanComponentId[i]];
00338 write(CoutP, value);
00339 prediction[scanComponentId[i]] = value;
00340
00341
00342 unsigned int l;
00343 unsigned int m;
00344 for (l=1; l<64; l++)
00345 {
00346 symbol = get_symbol(HUFF_ID(AC_CLASS, AC_HT));
00347 if (symbol == HUFF_EOB) break;
00348 if (symbol == HUFF_ZRL)
00349 {
00350 for (m=l; m<=l+15; m++)
00351 {
00352 write(CoutP, (VYApixel)0);
00353 }
00354 l += 15;
00355 } else {
00356 cat = symbol & 15;
00357 run = (symbol>>4) & 15;
00358 for (m=l; m<l+run; m++)
00359 {
00360 write(CoutP, (VYApixel)0);
00361 }
00362 l += run;
00363 value = reformat(get_bits(cat), cat);
00364 write(CoutP, value);
00365 }
00366 }
00367 for (m=l; m<64; m++)
00368 {
00369 write(CoutP, (VYApixel)0);
00370 }
00371 }
00372 }
00373 }
00374 numberOfMCU++;
00375
00376 if (numberOfMCU == restartInterval)
00377 {
00378 Bits aux;
00379 read(CinP, aux);
00380 if (aux == 0xFF)
00381 {
00382 read(CinP, aux);
00383 if (RST_MK(0xFF00 | aux))
00384 {
00385 bit_count = 0;
00386 for(unsigned int i=0; i<nrOfScanComponents; i++)
00387 {
00388 prediction[i] = 0;
00389 }
00390 numberOfMCU = 0;
00391 } else {
00392 printf("%s:\n\tERROR:\tDid not find restart marker!\n",fullName());
00393 abort();
00394 }
00395 }
00396
00397 }
00398 }
00399 delete [] scanComponentId;
00400 delete [] huffmanTableId;
00401 delete [] prediction;
00402 }
00403
00404 delete [] imageComponent;
00405 delete [] H;
00406 delete [] V;
00407 }
00408
00409
00410
00411 VYApixel VLD::reformat(unsigned long S, int good)
00412 {
00413 unsigned int St;
00414
00415 if (!good)
00416 return 0;
00417 St = 1 << (good-1);
00418 if (S < St)
00419 return (S+1+((-1)<<good));
00420 else
00421 return S;
00422 }
00423
00424
00425
00426 int VLD::get_bits(int number)
00427 {
00428 int i, newbit;
00429 int result = 0;
00430 Bits wwindow;
00431 Bits aux;
00432
00433 if (!number)
00434 return 0;
00435 for (i=0; i<number; i++)
00436 {
00437 if (bit_count == 0)
00438 {
00439 read(CinP, wwindow);
00440 if (wwindow == 0xFF)
00441 {
00442 read(CinP, aux);
00443 switch (aux)
00444 {
00445 case EOF:
00446 case 0xFF:
00447 printf("%s:\n\tERROR:\tRan out of bit stream\n",fullName());
00448 abort();
00449 break;
00450
00451 case 0x00:
00452
00453 break;
00454
00455 default:
00456 if (RST_MK(0xFF00 | aux))
00457 printf("%s:\n\tERROR:\tSpontaneously found restart marker!\n",fullName());
00458 printf("\tERROR:\tLost sync in bit stream\n");
00459 abort();
00460 break;
00461 }
00462 }
00463 bit_count = 8;
00464 } else {
00465 wwindow = window;
00466 }
00467 newbit = (wwindow>>7) & 1;
00468 window = wwindow << 1;
00469 bit_count--;
00470 result = (result << 1) | newbit;
00471 }
00472 return result;
00473 }
00474
00475 unsigned char VLD::get_symbol(int select)
00476 {
00477 int cellPt;
00478
00479 cellPt = 0;
00480
00481 while(HUFF_FLAG(HTable[select][cellPt]) == GOOD_NODE_FLAG)
00482 {
00483 cellPt = get_bits(1) | (HUFF_VALUE(HTable[select][cellPt])<<1);
00484 }
00485
00486 switch (HUFF_FLAG(HTable[select][cellPt]))
00487 {
00488 case SPECIAL_FLAG:
00489 printf("%s:\n\tERROR:\tFound forbidden Huffman symbol !\n", fullName());
00490 abort();
00491 break;
00492
00493 case GOOD_LEAF_FLAG:
00494 return HUFF_VALUE(HTable[select][cellPt]);
00495 break;
00496
00497 case BAD_LEAF_FLAG:
00498
00499
00500 printf("%s:\n\tWARNING:\tFalling out of truncated tree !\n", fullName());
00501 return 0;
00502 break;
00503
00504 default:
00505 break;
00506 }
00507 return 0;
00508 }
00509
00510 void VLD::load_restart_interval()
00511 {
00512 Bits firstc;
00513 Bits nextc;
00514
00515 read(restartIntervalBitsInP, firstc);
00516 restartInterval = firstc;
00517 read(restartIntervalBitsInP, nextc);
00518 restartInterval = (restartInterval<<8) | nextc;
00519 }