/* * THIS ROUTINE IS PART OF THE CLEMENTINE PDS FILE READER PROGRAM. * IT WAS WRITTEN BY ACT CORP. IN DIRECT SUPPORT TO THE * CLEMENTINE (DSPSE) PROGRAM. * * IF YOU FIND A PROBLEM OR MAKE ANY CHANGES TO THIS CODE PLEASE CONTACT * Dr. Erick Malaret at ACT Corp. * tel: (703) 742-0294 * (703) 683-7431 * email: nrlvax.nrl.navy.mil * * */ #include #include "jpeg_c.h" #include "pds.h" #define ZRL 240 #define EOB 0 void inithuffcode(); void genhuffsize(char *, short *, short *); void genhuffcode(short *, char *); void genehuf(short *, short *, short *, char *, char *, short); void gendectbls(short *, short *, short *, short *, short *); short dcbits[16], acbits[16]; char dchuffval[12], achuffval[162]; short dcehufco[16]; short dcehufsi[16]; short dcmincode[16]; short dcmaxcode[16]; short dcvalptr[16]; short acehufco[256]; short acehufsi[256]; short acmincode[16]; short acmaxcode[16]; short acvalptr[16]; /******************* Initialization of Huffman tables ********************/ void inithuffcode() { char dchuffsize[13], achuffsize[163]; short dchuffcode[12], achuffcode[162]; short dclastk, aclastk, i; /* generate dc Huffman codes */ genhuffsize(dchuffsize,dcbits,&dclastk); genhuffcode(dchuffcode,dchuffsize); fprintf(qparm,"dc huffman tables:\n"); fprintf(qparm,"(symbol length code)\n"); genehuf(dcehufco,dcehufsi,dchuffcode,dchuffsize,dchuffval,dclastk); /* generate ac Huffman codes */ genhuffsize(achuffsize,acbits,&aclastk); genhuffcode(achuffcode,achuffsize); fprintf(qparm,"ac huffman tables:\n"); fprintf(qparm,"(symbol length code)\n"); genehuf(acehufco,acehufsi,achuffcode,achuffsize,achuffval,aclastk); /* generate decoding tables */ gendectbls(dcmincode,dcmaxcode,dcvalptr,dchuffcode,dcbits); gendectbls(acmincode,acmaxcode,acvalptr,achuffcode,acbits); } void genhuffsize(char *huffsize, short *bits, short *lastk) { short i = 0,j = 1,k = 0; while ( i < 16 ) if ( j > bits[i] ) { i++; j = 1; } else { huffsize[k] = i+1; k++; j++; } huffsize[k] = 0; *lastk = k; } void genhuffcode(short *huffcode, char *huffsize) { short code, k; char si; k = code = 0; si = huffsize[0]; while ( huffsize[k] ) { if ( huffsize[k] == si ) { huffcode[k] = code; code++; k++; } else { code <<= 1; si++; } } } void genehuf(short *ehufco, short *ehufsi, short *huffcode, char *huffsize, char *huffvalue, short lastk) { short k; short value; for (k=0; k < lastk; k++) { value = ((short)huffvalue[k])&0x00ff; ehufco[value] = huffcode[k]; ehufsi[value] = huffsize[k]; fprintf(qparm,"%#.2x\t%d\t%#x\n", huffvalue[k]&0x00ff, ehufsi[value], ehufco[value] ); } } void gendectbls(short *mincode, short *maxcode, short *valptr, short *huffcode, short *bits) { short k, l; l = k = 0; while ( l < 16 ) { if ( bits[l] ) { valptr[l] = k; mincode[l] = huffcode[k]; maxcode[l] = huffcode[k + bits[l] -1]; k += bits[l]; } else maxcode[l] = -1; l++; } } /************************** Decoding Section *****************************/ unsigned short mask[] = {0x0000, 0x0001,0x0002,0x0004,0x0008,0x0010,0x0020,0x0040,0x0080, 0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000}; short code; void decode(short *u, BitStream *ibs) { short symbol, coeff, i, run, cat, j, l; /* get dc coefficient */ l = 0; code = BitStream_read(ibs,1); while ( code > dcmaxcode[l] ) { code = (short)(code << 1) | BitStream_read(ibs,1); l++; } symbol = (dchuffval[dcvalptr[l] + code - dcmincode[l]]) & 0x00ff; if ( symbol ) { coeff = BitStream_read(ibs,symbol); if ( coeff & mask[symbol] ) u[0] = coeff; else u[0] = ((0xffff << symbol) | coeff) + 1; } else u[0] = 0; /* get ac coefficients */ i = 1; while ( i < 64 ) { l = 0; code = BitStream_read(ibs,1); while ( code > acmaxcode[l] ) { code = (short)(code << 1) | BitStream_read(ibs,1); l++; } symbol = (achuffval[acvalptr[l] + code - acmincode[l]]) & 0x00ff; if ( symbol == ZRL ) { for (j=0; j < 16; j++) u[i++] = 0; } else if ( symbol == EOB ) { for (j=i; j < 64; j++) u[i++] = 0; } else { run = (symbol >> 4) & 0x000f; cat = symbol&0x000f; while ( run-- ) u[i++] = 0; coeff = BitStream_read(ibs,cat); if ( coeff & mask[cat] ) u[i++] = coeff; else u[i++] = ((0xffff << cat) | coeff) + 1; } } }