00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __MXCPC_FRAMEWISEMXPEGSCANDECODERSOFTWAREONLY_H__
00018 #define __MXCPC_FRAMEWISEMXPEGSCANDECODERSOFTWAREONLY_H__
00019
00020
00021
00022 #include <mxcpcFramewiseMxPEGScanDecoder.h>
00023 #include <mxcpcHuffmanTree.h>
00024 #include <mxcpc_namespace.h>
00025
00026 #include <cstring>
00027 #include <cstdlib>
00028 #include <cstdio>
00029
00030
00031
00035
00048 class mxcpcFramewiseMxPEGScanDecoderSoftwareOnly : public mxcpcFramewiseMxPEGScanDecoder {
00049
00050 private:
00051 static const int ZigZagMap[64];
00052 static short iclip[1024];
00053 static short *iclp;
00054
00055 private:
00056 mxcpcHuffmanTree *HuffmanTree_Y_DC,
00057 *HuffmanTree_Y_AC;
00058 mxcpcHuffmanTree *HuffmanTree_UV_DC,
00059 *HuffmanTree_UV_AC;
00060
00061 mxcpc::s16 QuantizationTable_Y[64],
00062 QuantizationTable_UV[64];
00063
00064
00065
00066 unsigned char *CurrentScanByte,
00067 ScanMask;
00068 int ScanBytesLeft;
00069 int CoeffInAdditionalBits;
00070
00071 public:
00072 mxcpcFramewiseMxPEGScanDecoderSoftwareOnly();
00073 ~mxcpcFramewiseMxPEGScanDecoderSoftwareOnly();
00074
00075 public:
00077 void setYQuantizationTable(unsigned char *data_bytes);
00079 void setUVQuantizationTable(unsigned char *data_bytes);
00081 void performScanSweep(mxcpcFramewiseMxPEGDecoder::UndecodedFrameDescriptor
00082 *frame_descriptor);
00083
00084 private:
00087
00092 inline bool consumeScanBit(void) {
00093
00094 bool bit_was_set;
00095 unsigned char last_scan_byte;
00096
00097 bit_was_set = *CurrentScanByte & ScanMask;
00098
00099 ScanMask /= 2;
00100 if(!ScanMask) {
00101
00102 last_scan_byte = *CurrentScanByte;
00103
00104 CurrentScanByte++;
00105 ScanBytesLeft--;
00106 if(last_scan_byte == 0xff) {
00107 if(*CurrentScanByte == 0x00) {
00108 if(!ScanBytesLeft) {
00109 mxcpc::sendStatusMsg("not more scan bytes!");
00110 std::exit(666);
00111 }
00112 else {
00113 CurrentScanByte++;
00114 ScanBytesLeft--;
00115 }
00116 }
00117 else {
00118 mxcpc::sendStatusMsg("unexpected marker encountered!");
00119 std::exit(666);
00120 }
00121
00122
00123 }
00124
00125 ScanMask = 128;
00126 }
00127
00128 return(bit_was_set);
00129 }
00130
00133
00144 inline const mxcpcHuffmanTree
00145 ::Node *consumeHuffmanCodeword(
00146 const mxcpcHuffmanTree::Node *current_huffman_node) {
00147
00148 const mxcpcHuffmanTree::Node *last_huffman_node;
00149
00150 do {
00151
00152 if(!ScanBytesLeft) return(0);
00153
00154 last_huffman_node = current_huffman_node;
00155
00156 if(consumeScanBit())
00157 current_huffman_node = current_huffman_node->Child1;
00158 else
00159 current_huffman_node = current_huffman_node->Child0;
00160
00161 if(current_huffman_node == last_huffman_node) {
00162 std::printf(" !!! invalid codeword !!!\n");
00163 std::exit(666);
00164 return(0);
00165 }
00166
00167 } while(!current_huffman_node->IsLeaf);
00168
00169 return(current_huffman_node);
00170 }
00171
00174
00186 inline bool consumeAdditionalBits(int n) {
00187
00188 bool positive;
00189 int base;
00190 static int bases[] = { -666, -666, 2, 4, 8, 16, 32, 64, 128, 256, 512 };
00191
00192
00193 if(!ScanBytesLeft) return(true);
00194 positive = consumeScanBit();
00195 if(n == 1) {
00196 if(positive) CoeffInAdditionalBits = 1;
00197 else CoeffInAdditionalBits = -1;
00198 return(false);
00199 }
00200
00201
00202 base = bases[n];
00203 if(!positive) {
00204 base *= 2;
00205 base = -base;
00206 base++;
00207 }
00208 n--;
00209 CoeffInAdditionalBits = 0;
00210 while(n) {
00211
00212 if(!ScanBytesLeft) return(true);
00213
00214 CoeffInAdditionalBits *= 2;
00215
00216 if(consumeScanBit())
00217 CoeffInAdditionalBits += 1;
00218
00219 n--;
00220 }
00221 CoeffInAdditionalBits += base;
00222
00223 return(false);
00224 }
00225
00226
00228 void idctrow(short *blk);
00230 void idctcol(short *blk);
00232 void idct(short *blk);
00233 };
00234
00235
00236
00237 #endif // __MXCPC_FRAMEWISEMXPEGSCANDECODERSOFTWAREONLY_H__