/*-------------------------------------------*/ /* File : huffman.c, utilities for jfif view */ /* Author : Pierre Guerrier, march 1998 */ /*-------------------------------------------*/ #include #include /*--------------------------------------*/ /* private huffman.c defines and macros */ /*--------------------------------------*/ #define HUFF_EOB 0x00 #define HUFF_ZRL 0xF0 #define DC_CLASS 0 #define AC_CLASS 1 /*------------------------------------------*/ /* some constants for on-the-fly IQ and IZZ */ /*------------------------------------------*/ static const int G_ZZ[] = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 }; /* Memory size of HTables; */ #define MAX_SIZE(hclass) ((hclass)?162:14) /*--------------------------------------*/ /* some static structures for storage */ /*--------------------------------------*/ static unsigned char DC_Table0[MAX_SIZE(DC_CLASS)], DC_Table1[MAX_SIZE(DC_CLASS)]; static unsigned char AC_Table0[MAX_SIZE(AC_CLASS)], AC_Table1[MAX_SIZE(AC_CLASS)]; static unsigned char *HTable[4] = { &DC_Table0[0], &DC_Table1[0], &AC_Table0[0], &AC_Table1[0] }; static int MinCode[4][16]; static int MaxCode[4][16]; static int ValPtr[4][16]; typedef union { /* block of frequency-space values */ int block[8][8]; int linear[64]; } FBlock; /*-----------------------------------*/ /* extract a single symbol from file */ /* using specified huffman table ... */ /*-----------------------------------*/ unsigned char get_symbol(FILE *fi, int select) { long code = 0; int length; int index; for (length = 0; length < 16; length++) { code = (2*code) | get_one_bit(fi); #ifdef SPY trace_bits(1, 0); #endif if (code <= MaxCode[select][length]) break; } index = ValPtr[select][length] + code - MinCode[select][length]; #ifdef SPY trace_bits(0, 0); #endif if (index < MAX_SIZE(select/2)) return HTable[select][index]; fprintf(stderr, "%ld:\tWARNING:\tOverflowing symbol table !\n", ftell(fi)); return 0; } /*-------------------------------------------------*/ /* here we unpack, predict, unquantify and reorder */ /* a complete 8*8 DCT block ... */ /*-------------------------------------------------*/ void unpack_block(FILE *fi, FBlock *T, int select) { unsigned int i, run, cat; int value; unsigned char symbol; /* Init the block with 0's: */ for (i=0; i<64; i++) T->linear[i] = 0; /* First get the DC coefficient: */ symbol = get_symbol(fi, HUFF_ID(DC_CLASS, comp[select].DC_HT)); value = reformat(get_bits(fi, symbol), symbol); #ifdef SPY trace_bits(symbol, 1); #endif value += comp[select].PRED; comp[select].PRED = value; T->linear[0] = value * QTable[comp[select].QT]->linear[0]; /* Now get all 63 AC values: */ for (i=1; i<64; i++) { symbol = get_symbol(fi, HUFF_ID(AC_CLASS, comp[select].AC_HT)); if (symbol == HUFF_EOB) break; if (symbol == HUFF_ZRL) { i += 15; continue; } cat = symbol & 0x0F; run = (symbol>>4) & 0x0F; i += run; value = reformat(get_bits(fi, cat), cat); #ifdef SPY trace_bits(cat, 1); #endif /* Dequantify and ZigZag-reorder: */ T->linear[G_ZZ[i]] = value * QTable[comp[select].QT]->linear[i]; } } int main(void) { unpack_block(NULL, NULL, 0); return 0; }