From e2de64d6f1beb9e492daf5b886e19933c1fa41dd Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- mpeglib/lib/mpegplay/decoderClass.cpp | 893 ++++++++++++++++++++++++++++++++++ 1 file changed, 893 insertions(+) create mode 100644 mpeglib/lib/mpegplay/decoderClass.cpp (limited to 'mpeglib/lib/mpegplay/decoderClass.cpp') diff --git a/mpeglib/lib/mpegplay/decoderClass.cpp b/mpeglib/lib/mpegplay/decoderClass.cpp new file mode 100644 index 00000000..e259c8e6 --- /dev/null +++ b/mpeglib/lib/mpegplay/decoderClass.cpp @@ -0,0 +1,893 @@ +/* + class for decoders + Copyright (C) 1999 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "decoderClass.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + + +#ifndef NDEBUG +#define NDEBUG +#endif +#include + + +#define DEBUG_DECODERCLASS(x) +//#define DEBUG_DECODERCLASS(x) x + +/* Array mapping zigzag to array pointer offset. */ + + +static const int zigzag_direct_nommx[64] = { + 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}; + + +static const int zigzag_direct_mmx[64] = { + + 0*8+0/* 0*/, 1*8+0/* 1*/, 0*8+1/* 8*/, 0*8+2/*16*/, 1*8+1/* 9*/, 2*8+0/* 2*/, 3*8+0/* 3*/, 2*8+1/*10*/, + 1*8+2/*17*/, 0*8+3/*24*/, 0*8+4/*32*/, 1*8+3/*25*/, 2*8+2/*18*/, 3*8+1/*11*/, 4*8+0/* 4*/, 5*8+0/* 5*/, + 4*8+1/*12*/, 5*8+2/*19*/, 2*8+3/*26*/, 1*8+4/*33*/, 0*8+5/*40*/, 0*8+6/*48*/, 1*8+5/*41*/, 2*8+4/*34*/, + 3*8+3/*27*/, 4*8+2/*20*/, 5*8+1/*13*/, 6*8+0/* 6*/, 7*8+0/* 7*/, 6*8+1/*14*/, 5*8+2/*21*/, 4*8+3/*28*/, + 3*8+4/*35*/, 2*8+5/*42*/, 1*8+6/*49*/, 0*8+7/*56*/, 1*8+7/*57*/, 2*8+6/*50*/, 3*8+5/*43*/, 4*8+4/*36*/, + 5*8+3/*29*/, 6*8+2/*22*/, 7*8+1/*15*/, 7*8+2/*23*/, 6*8+3/*30*/, 5*8+4/*37*/, 4*8+5/*44*/, 3*8+6/*51*/, + 2*8+7/*58*/, 3*8+7/*59*/, 4*8+6/*52*/, 5*8+5/*45*/, 6*8+4/*38*/, 7*8+3/*31*/, 7*8+4/*39*/, 6*8+5/*46*/, + 7*8+6/*53*/, 4*8+7/*60*/, 5*8+7/*61*/, 6*8+6/*54*/, 7*8+5/*47*/, 7*8+6/*55*/, 6*8+7/*62*/, 7*8+7/*63*/ +}; + + + + + +/* Bit masks used by bit i/o operations. */ + + + +static unsigned int bitMask[] = {0xffffffff,0x7fffffff,0x3fffffff,0x1fffffff, + 0x0fffffff, 0x07ffffff, 0x03ffffff, 0x01ffffff, + 0x00ffffff, 0x007fffff, 0x003fffff, 0x001fffff, + 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff, + 0x0000ffff, 0x00007fff, 0x00003fff, 0x00001fff, + 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff, + 0x000000ff, 0x0000007f, 0x0000003f, 0x0000001f, + 0x0000000f, 0x00000007, 0x00000003, 0x00000001}; + +static unsigned int rBitMask[] = {0xffffffff,0xfffffffe,0xfffffffc,0xfffffff8, + 0xfffffff0, 0xffffffe0, 0xffffffc0, 0xffffff80, + 0xffffff00, 0xfffffe00, 0xfffffc00, 0xfffff800, + 0xfffff000, 0xffffe000, 0xffffc000, 0xffff8000, + 0xffff0000, 0xfffe0000, 0xfffc0000, 0xfff80000, + 0xfff00000, 0xffe00000, 0xffc00000, 0xff800000, + 0xff000000, 0xfe000000, 0xfc000000, 0xf8000000, + 0xf0000000, 0xe0000000, 0xc0000000, 0x80000000}; + +static unsigned int bitTest[] = { 0x80000000,0x40000000,0x20000000,0x10000000, + 0x08000000, 0x04000000, 0x02000000, 0x01000000, + 0x00800000, 0x00400000, 0x00200000, 0x00100000, + 0x00080000, 0x00040000, 0x00020000, 0x00010000, + 0x00008000, 0x00004000, 0x00002000, 0x00001000, + 0x00000800, 0x00000400, 0x00000200, 0x00000100, + 0x00000080, 0x00000040, 0x00000020, 0x00000010, + 0x00000008, 0x00000004, 0x00000002, 0x00000001}; + + + + + +DecoderClass::DecoderClass(VideoDecoder* vid_stream, + MpegVideoStream* mpegVideoStream) { + + this->vid_stream=vid_stream; + this->mpegVideoStream=mpegVideoStream; + + +#ifdef INTEL + lmmx=mm_support(); +#else + lmmx=false; + DEBUG_DECODERCLASS(cout << "no INTEL arch- disable MMX in decoderClass"<showBits(5); + if (index < 31) { + macro_val = dct_dc_size_luminance[index].value; + mpegVideoStream->flushBits(dct_dc_size_luminance[index].num_bits); + } else { + index=mpegVideoStream->showBits(9); + index -= 0x1f0; + macro_val = dct_dc_size_luminance1[index].value; + mpegVideoStream->flushBits(dct_dc_size_luminance1[index].num_bits); + } + return macro_val; +} + + +int DecoderClass::decodeDCTDCSizeChrom() { + unsigned int macro_val; + unsigned int index; + index=mpegVideoStream->showBits(5); + if (index < 31) { + macro_val = dct_dc_size_chrominance[index].value; + mpegVideoStream->flushBits(dct_dc_size_chrominance[index].num_bits); + }else { + index=mpegVideoStream->showBits(10); + index -= 0x3e0; + macro_val = dct_dc_size_chrominance1[index].value; + mpegVideoStream->flushBits(dct_dc_size_chrominance1[index].num_bits); + } + return macro_val; +} + +/* + *-------------------------------------------------------------- + * + * DecodeMBAddrInc -- + * + * Huffman DecoderClass for macro_block_address_increment; the location + * in which the result will be placed is being passed as argument. + * The decoded value is obtained by doing a table lookup on + * mb_addr_inc. + * + * Results: + * The decoded value for macro_block_address_increment or MPGDECODE_ERROR + * for unbound values will be placed in the location specified. + * + * Side effects: + * Bit stream is irreversibly parsed. + * + *-------------------------------------------------------------- + */ +int DecoderClass::decodeMBAddrInc() { + unsigned int index; + int val; + index=mpegVideoStream->showBits(11); + val = mb_addr_inc[index].value; + mpegVideoStream->flushBits(mb_addr_inc[index].num_bits); + if (mb_addr_inc[index].num_bits==0) { + DEBUG_DECODERCLASS(cout<<"num_bits==0"<showBits(11); + value = motion_vectors[index].code; + + mpegVideoStream->flushBits(motion_vectors[index].num_bits); + return value; +} + + +/* + *-------------------------------------------------------------- + * + * DecodeCBP -- + * + * Huffman DecoderClass for coded_block_pattern; location in which the + * decoded result will be placed is being passed as argument. The + * decoded values are obtained by doing a table lookup on + * coded_block_pattern. + * + * Results: + * The decoded value for coded_block_pattern or MPGDECODE_ERROR for unbound + * values will be placed in the location specified. + * + * Side effects: + * Bit stream is irreversibly parsed. + * + *-------------------------------------------------------------- + */ +int DecoderClass::decodeCBP() { + unsigned int index; + unsigned int coded_bp; + index=mpegVideoStream->showBits(9); + coded_bp = coded_block_pattern[index].cbp; + mpegVideoStream->flushBits(coded_block_pattern[index].num_bits); + return coded_bp; +} + + + + + + + +/* + *-------------------------------------------------------------- + * + * DecodeMBTypeB -- + * + * Huffman Decoder for macro_block_type in bidirectionally-coded + * pictures;locations in which the decoded results: macroblock_quant, + * macroblock_motion_forward, macro_block_motion_backward, + * macroblock_pattern, macro_block_intra, will be placed are + * being passed as argument. The decoded values are obtained by + * doing a table lookup on mb_type_B. + * + * Results: + * The various decoded values for macro_block_type in + * bidirectionally-coded pictures or MPGDECODE_ERROR for unbound values will + * be placed in the locations specified. + * + * Side effects: + * Bit stream is irreversibly parsed. + * + *-------------------------------------------------------------- + */ +void DecoderClass::decodeMBTypeB(int& quant,int& motion_fwd, + int& motion_bwd,int& pat,int& intra){ + unsigned int index; + + index=mpegVideoStream->showBits(6); + + quant = mb_type_B[index].mb_quant; + motion_fwd = mb_type_B[index].mb_motion_forward; + motion_bwd = mb_type_B[index].mb_motion_backward; + pat = mb_type_B[index].mb_pattern; + intra = mb_type_B[index].mb_intra; + if (index == 0) { + DEBUG_DECODERCLASS(cout << "error in decodeMBTypeB"<flushBits(mb_type_B[index].num_bits); +} + + +/* + *-------------------------------------------------------------- + * + * DecodeMBTypeI -- + * + * Huffman Decoder for macro_block_type in intra-coded pictures; + * locations in which the decoded results: macroblock_quant, + * macroblock_motion_forward, macro_block_motion_backward, + * macroblock_pattern, macro_block_intra, will be placed are + * being passed as argument. + * + * Results: + * The various decoded values for macro_block_type in intra-coded + * pictures or MPGDECODE_ERROR for unbound values will be placed in the + * locations specified. + * + * Side effects: + * Bit stream is irreversibly parsed. + * + *-------------------------------------------------------------- + */ +void DecoderClass::decodeMBTypeI(int& quant,int& motion_fwd, + int& motion_bwd,int& pat,int& intra) { + + unsigned int index; + static int quantTbl[4] = {MPGDECODE_ERROR, 1, 0, 0}; + + index=mpegVideoStream->showBits(2); + + motion_fwd = 0; + motion_bwd = 0; + pat = 0; + intra = 1; + quant = quantTbl[index]; + if (quant == MPGDECODE_ERROR) { + DEBUG_DECODERCLASS(cout << "decodeMBTypeI Error"<flushBits (1 + quant); + } + +} + + + +/* + *-------------------------------------------------------------- + * + * DecodeMBTypeP -- + * + * Huffman Decoder for macro_block_type in predictive-coded pictures; + * locations in which the decoded results: macroblock_quant, + * macroblock_motion_forward, macro_block_motion_backward, + * macroblock_pattern, macro_block_intra, will be placed are + * being passed as argument. The decoded values are obtained by + * doing a table lookup on mb_type_P. + * + * Results: + * The various decoded values for macro_block_type in + * predictive-coded pictures or MPGDECODE_ERROR for unbound values will be + * placed in the locations specified. + * + * Side effects: + * Bit stream is irreversibly parsed. + * + *-------------------------------------------------------------- + */ +void DecoderClass::decodeMBTypeP(int& quant,int& motion_fwd, + int& motion_bwd,int& pat,int& intra) { + + unsigned int index; + + index=mpegVideoStream->showBits(6); + + quant = mb_type_P[index].mb_quant; + motion_fwd = mb_type_P[index].mb_motion_forward; + motion_bwd = mb_type_P[index].mb_motion_backward; + pat = mb_type_P[index].mb_pattern; + intra = mb_type_P[index].mb_intra; + if (index == 0) { + DEBUG_DECODERCLASS(cout << "error in decodeMBTypeP"<flushBits(mb_type_P[index].num_bits); +} + +/* + *-------------------------------------------------------------- + * + * decodeDCTCoeff -- + * + * Huffman Decoder for dct_coeff_first and dct_coeff_next; + * locations where the results of decoding: run and level, are to + * be placed and also the type of DCT coefficients, either + * dct_coeff_first or dct_coeff_next, are being passed as argument. + * + * The decoder first examines the next 8 bits in the input stream, + * and perform according to the following cases: + * + * '0000 0000' - examine 8 more bits (i.e. 16 bits total) and + * perform a table lookup on dct_coeff_tbl_0. + * One more bit is then examined to determine the sign + * of level. + * + * '0000 0001' - examine 4 more bits (i.e. 12 bits total) and + * perform a table lookup on dct_coeff_tbl_1. + * One more bit is then examined to determine the sign + * of level. + * + * '0000 0010' - examine 2 more bits (i.e. 10 bits total) and + * perform a table lookup on dct_coeff_tbl_2. + * One more bit is then examined to determine the sign + * of level. + * + * '0000 0011' - examine 2 more bits (i.e. 10 bits total) and + * perform a table lookup on dct_coeff_tbl_3. + * One more bit is then examined to determine the sign + * of level. + * + * otherwise - perform a table lookup on dct_coeff_tbl. If the + * value of run is not ESCAPE, extract one more bit + * to determine the sign of level; otherwise 6 more + * bits will be extracted to obtain the actual value + * of run , and then 8 or 16 bits to get the value of level. + * + * + * + * Results: + * The decoded values of run and level or MPGDECODE_ERROR + * for unbound values + * are placed in the locations specified. + * + * Side effects: + * Bit stream is irreversibly parsed. + * + *-------------------------------------------------------------- + */ + +void DecoderClass::decodeDCTCoeff(unsigned short int* dct_coeff_tbl, + unsigned RUNTYPE& run,int& level) { + + + unsigned int temp, index; + unsigned int value, next32bits, flushed; + + /* + * Grab the next 32 bits and use it to improve performance of + * getting the bits to parse. Thus, calls are translated as: + * + * show_bitsX <--> next32bits >> (32-X) + * get_bitsX <--> val = next32bits >> (32-flushed-X); + * flushed += X; + * next32bits &= bitMask[flushed]; + * flush_bitsX <--> flushed += X; + * next32bits &= bitMask[flushed]; + * + */ + next32bits=mpegVideoStream->showBits32(); + + flushed = 0; + + /* show_bits8(index); */ + index = next32bits >> 24; + + if (index > 3) { + value = dct_coeff_tbl[index]; + run = (value & RUN_MASK) >> RUN_SHIFT; + if (run == END_OF_BLOCK) { + level = END_OF_BLOCK; + } + else { + /* num_bits = (value & NUM_MASK) + 1; */ + /* flush_bits(num_bits); */ + flushed = (value & NUM_MASK) + 1; + next32bits &= bitMask[flushed]; + if (run != ESCAPE) { + level = (value & LEVEL_MASK) >> LEVEL_SHIFT; + /* get_bits1(value); */ + /* if (value) *level = -*level; */ + if (next32bits >> (31-flushed)) level = -level; + flushed++; + /* next32bits &= bitMask[flushed]; last op before update */ + } + else { /* *run == ESCAPE */ + /* get_bits14(temp); */ + temp = next32bits >> (18-flushed); + flushed += 14; + next32bits &= bitMask[flushed]; + run = temp >> 8; + temp &= 0xff; + if (temp == 0) { + /* get_bits8(*level); */ + level = next32bits >> (24-flushed); + flushed += 8; + /* next32bits &= bitMask[flushed]; last op before update */ + assert(level >= 128); + } else if (temp != 128) { + /* Grab sign bit */ + level = ((int) (temp << 24)) >> 24; + } else { + /* get_bits8(*level); */ + level = next32bits >> (24-flushed); + flushed += 8; + /* next32bits &= bitMask[flushed]; last op before update */ + level = level - 256; + assert(level <= -128 && level >= -255); + } + } + /* Update bitstream... */ + mpegVideoStream->flushBitsDirect(flushed); + } + } + else { + if (index == 2) { + /* show_bits10(index); */ + index = next32bits >> 22; + value = dct_coeff_tbl_2[index & 3]; + } + else if (index == 3) { + /* show_bits10(index); */ + index = next32bits >> 22; + value = dct_coeff_tbl_3[index & 3]; + } + else if (index) { /* index == 1 */ + /* show_bits12(index); */ + index = next32bits >> 20; + value = dct_coeff_tbl_1[index & 15]; + } + else { /* index == 0 */ + /* show_bits16(index); */ + index = next32bits >> 16; + value = dct_coeff_tbl_0[index & 255]; + } + run = (value & RUN_MASK) >> RUN_SHIFT; + level = (value & LEVEL_MASK) >> LEVEL_SHIFT; + + /* + * Fold these operations together to make it fast... + */ + /* num_bits = (value & NUM_MASK) + 1; */ + /* flush_bits(num_bits); */ + /* get_bits1(value); */ + /* if (value) *level = -*level; */ + + flushed = (value & NUM_MASK) + 2; + if ((next32bits >> (32-flushed)) & 0x1) level = -level; + + /* Update bitstream ... */ + mpegVideoStream->flushBitsDirect(flushed); + + } + +} + + +void DecoderClass::resetDCT() { + /* Reset past dct dc y, cr, and cb values. */ + + dct_dc_y_past = 1024 << 3; + dct_dc_cr_past = 1024 << 3; + dct_dc_cb_past = 1024 << 3; + +} + + + +/* + *-------------------------------------------------------------- + * + * ParseReconBlock -- + * + * Parse values for block structure from bitstream. + * n is an indication of the position of the block within + * the macroblock (i.e. 0-5) and indicates the type of + * block (i.e. luminance or chrominance). Reconstructs + * coefficients from values parsed and puts in + * block.dct_recon array in vid stream structure. + * sparseFlag is set when the block contains only one + * coeffictient and is used by the IDCT. + * + * Results: + * + * + * Side effects: + * Bit stream irreversibly parsed. + * + *-------------------------------------------------------------- + */ + + +void DecoderClass::ParseReconBlock(int& n,int& mb_intra, + unsigned int& qscale, + int& lflag, + unsigned int* iqmatrixptr, + unsigned int* niqmatrixptr) { + + + + + int coeffCount=0; + if (mpegVideoStream->hasBytes(512) == false) { + DEBUG_DECODERCLASS(cout << "cannot get 512 raw bytes"< next16bits >> (16-X) + * get_bitsX <--> val = next16bits >> (16-flushed-X); + * flushed += X; + * next16bits &= bitMask[flushed]; + * flush_bitsX <--> flushed += X; + * next16bits &= bitMask[flushed]; + * + * I've streamlined the code a lot, so that we don't have to mask + * out the low order bits and a few of the extra adds are removed. + * bsmith + */ + unsigned int next16bits, index, flushed; + next16bits=mpegVideoStream->showBits16(); + + index = next16bits >> (16-5); + if (index < 31) { + size = dct_dc_size_luminance[index].value; + flushed = dct_dc_size_luminance[index].num_bits; + } else { + index = next16bits >> (16-9); + index -= 0x1f0; + size = dct_dc_size_luminance1[index].value; + flushed = dct_dc_size_luminance1[index].num_bits; + } + next16bits &= bitMask[(16+flushed)&0x1f]; + if (size != 0) { + flushed += size; + coeff = next16bits >> (16-flushed); + if (!(coeff & bitTest[32-size])) { + coeff++; + coeff|= rBitMask[size&0x1f]; + } + coeff <<= 3; + } else { + coeff = 0; + } + mpegVideoStream->flushBitsDirect(flushed); + + if ( (n == 0) && (lflag) ) { + coeff += 1024; + } else { + coeff += dct_dc_y_past; + } + dct_dc_y_past = coeff; + + } else { /* n = 4 or 5 */ + /* + * Get the chrominance bits. This code has been hand optimized to + * as described above + */ + + unsigned int next16bits, index, flushed; + next16bits=mpegVideoStream->showBits16(); + + index = next16bits >> (16-5); + if (index < 31) { + size = dct_dc_size_chrominance[index].value; + flushed = dct_dc_size_chrominance[index].num_bits; + } else { + index = next16bits >> (16-10); + index -= 0x3e0; + size = dct_dc_size_chrominance1[index].value; + flushed = dct_dc_size_chrominance1[index].num_bits; + } + next16bits &= bitMask[(16+flushed)&0x1f]; + + if (size != 0) { + flushed += size; + coeff = next16bits >> (16-flushed); + if (!(coeff & bitTest[32-size])) { + coeff++; + coeff|=rBitMask[size&0x1f]; + } + coeff <<= 3; + } else { + coeff = 0; + } + mpegVideoStream->flushBitsDirect(flushed); + + /* We test 5 first; a result of the mixup of Cr and Cb */ + + if (n == 5) { + if (lflag) { + coeff += 1024; + } else { + coeff += dct_dc_cr_past; + } + dct_dc_cr_past = coeff; + } else { + if (lflag) { + coeff += 1024; + } else { + coeff += dct_dc_cb_past; + } + dct_dc_cb_past = coeff; + } + } + + coeff <<= lmmx; + reconptr[0] = coeff; + + pos=0; + i = 0; + coeffCount = (coeff != 0); + + + // we never have d_types so there is no check + + + while(1) { + decodeDCTCoeff(dct_coeff_next,run,level); + + if (run >=END_OF_BLOCK) { + break; + } + i++; + i+=run; + pos = zigzag_direct[i&0x3f]; + + + coeff = (level * qscale * iqmatrixptr[pos]) >> 3 ; + + if (level < 0) { + coeff += (1 - (coeff & 1)); + } else { + coeff -= (1 - (coeff & 1)); + } + + coeff <<= lmmx; + + reconptr[pos] = coeff; + coeffCount++; + + } + mpegVideoStream->flushBitsDirect(2); + + goto end; + + } else { /* non-intra-coded macroblock */ + + decodeDCTCoeff(dct_coeff_first,run,level); + i = run; + + pos = zigzag_direct[i&0x3f]; + + /* quantizes and oddifies each coefficient */ + if (level < 0) { + coeff = ((level - 1) * qscale * niqmatrixptr[pos]) >>3; + if ((coeff & 1) == 0) {coeff++;} + } else { + coeff = ((level + 1) * qscale * niqmatrixptr[pos]) >>3; + coeff = (coeff-1) | 1; + } + + coeff <<= lmmx; + + reconptr[pos] = coeff; + coeffCount = (coeff!=0); + + // we never have d_type pictures here, we do not support them + + while(1) { + decodeDCTCoeff(dct_coeff_next,run,level); + + if (run >= END_OF_BLOCK) { + break; + } + i++; + i+=run; + pos = zigzag_direct[i&0x3f]; + + if (level < 0) { + coeff = ((level - 1) * qscale * niqmatrixptr[pos]) >>3; + if ((coeff & 1) == 0) {coeff++;} + } else { + coeff = ((level + 1) * qscale * niqmatrixptr[pos]) >> 3; + coeff = (coeff-1) | 1; + } + + coeff <<= lmmx; + + reconptr[pos] = coeff; + coeffCount++; + } /* end while */ + + mpegVideoStream->flushBitsDirect(2); + goto end; + } + + end: + if (coeffCount == 1) { + if (lmmx) { + emms(); + reconptr[pos]>>=lmmx; + j_rev_dct_sparse (reconptr, pos); + //IDCT_mmx(reconptr); + } else { + j_rev_dct_sparse (reconptr, pos); + } + + } else { + + if (lmmx) { + IDCT_mmx(reconptr); + } else { + j_rev_dct(reconptr); + } + + } + } + + // we call this at the edn of the "critical sections" + /* + if (lmmx) { + emms(); + } + */ + + return; + +} + + + + + +void DecoderClass::print() { + int i; + for(i=0;i<64;i++) { + printf(" %d ",zigzag_direct[i]); + } + printf("\n"); +} + + + + + + + + + + + + + + + + + + -- cgit v1.2.1