00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00057
00058
00059
00060 #ifndef __MX_MXPEGSCANDECODERSOFTWAREONLYCORE_H__
00061 #define __MX_MXPEGSCANDECODERSOFTWAREONLYCORE_H__
00062
00063
00064 #include "mxcpcHuffmanTree.h"
00065
00066 #include <interfaces/IUndecodedMxPEGFrameReceiver.h>
00067
00068 #include <mxm/core/mxmObject.h>
00069 #include <mxm/core/mxmHuffmanTableId.h>
00070 #include <mxm/core/mxm_generic_stuff.h>
00071
00072 #include <cstring>
00073 #include <cstdlib>
00074 #include <cstdio>
00075
00076
00077
00078 namespace mx {
00079
00081
00086 class MxPEGScanDecoderSoftwareOnlyCore : public mxmObject,
00087 public virtual
00088 IUndecodedMxPEGFrameReceiver {
00089
00090 protected:
00091 static const int MaxMCUsPerTile = 8;
00092 protected:
00093 static const int ZigZagMap[64];
00094 private:
00095 static const int W1 = 2841;
00096 static const int W2 = 2676;
00097 static const int W3 = 2408;
00098 static const int W5 = 1609;
00099 static const int W6 = 1108;
00100 static const int W7 = 565;
00101 static short iclip[1024];
00102 static short *iclp;
00103
00104 private:
00105 mxcpcHuffmanTree *HuffmanTrees[2][4];
00106 mxm::s16 *QuantizationTables[4];
00107
00108 protected:
00111 unsigned char *CurrentScanByte,
00112 ScanMask;
00113 int ScanBytesLeft;
00114 int CoeffInAdditionalBits;
00115 int MCUsPerTile;
00116 const mxcpcHuffmanTree::Node *HuffmanDCRootForMCU[MaxMCUsPerTile],
00117 *HuffmanACRootForMCU[MaxMCUsPerTile];
00118 mxm::s16 *QuantTableForMCU[MaxMCUsPerTile];
00119 mxm::s16 LastHuffmanDCs[3];
00120 mxm::s16 *LastHuffmanDCPtrForMCU[MaxMCUsPerTile];
00121 mxm::s16 CoeffBuffers[MaxMCUsPerTile][64];
00122
00123
00124 public:
00125 MxPEGScanDecoderSoftwareOnlyCore();
00126 ~MxPEGScanDecoderSoftwareOnlyCore();
00127
00128 public:
00130 void setQuantizationTable(int target_table,
00131 mxm::u8 *data_bytes);
00133 void setHuffmanTable(const mxmHuffmanTableId &target_table,
00134 mxm::u8 *data_bytes);
00135
00136 protected:
00139 bool mapTables(mxmUndecodedMxPEGFrameDescriptor *frame_descriptor);
00140
00143
00148 inline bool consumeScanBit(void) {
00149
00150 bool bit_was_set;
00151 unsigned char last_scan_byte;
00152
00153 bit_was_set = (*CurrentScanByte & ScanMask) ? true : false;
00154
00155 ScanMask /= 2;
00156 if(!ScanMask) {
00157
00158 last_scan_byte = *CurrentScanByte;
00159
00160 CurrentScanByte++;
00161 ScanBytesLeft--;
00162 if(last_scan_byte == 0xff) {
00163 if(*CurrentScanByte == 0x00) {
00164 if(!ScanBytesLeft) {
00165 mxm::sendStatusMessage(mxm::FailureMessage,
00166 "not more scan bytes!",
00167 this);
00168 std::exit(666);
00169 }
00170 else {
00171 CurrentScanByte++;
00172 ScanBytesLeft--;
00173 }
00174 }
00175 else {
00176 mxm::sendStatusMessage(mxm::FailureMessage,
00177 "unexpected marker encountered!",
00178 this);
00179 std::exit(666);
00180 }
00181
00182
00183 }
00184
00185 ScanMask = 128;
00186 }
00187
00188 return(bit_was_set);
00189 }
00190
00193
00204 inline const mxcpcHuffmanTree::Node
00205 *consumeHuffmanCodeword(
00206 const mxcpcHuffmanTree::Node *current_huffman_node) {
00207
00208 const mxcpcHuffmanTree::Node *last_huffman_node;
00209
00210 do {
00211
00212 if(!ScanBytesLeft) return(0);
00213
00214 last_huffman_node = current_huffman_node;
00215
00216 if(consumeScanBit())
00217 current_huffman_node = current_huffman_node->Child1;
00218 else
00219 current_huffman_node = current_huffman_node->Child0;
00220
00221 if(current_huffman_node == last_huffman_node) {
00222
00223 mxm::sendStatusMessage(mxm::FailureMessage,
00224 " !!! invalid codeword !!!",
00225 this);
00226 std::exit(666);
00227 return(0);
00228 }
00229 } while(!current_huffman_node->IsLeaf);
00230
00231 return(current_huffman_node);
00232 }
00233
00236
00248 inline bool consumeAdditionalBits(int n) {
00249
00250 bool positive;
00251 int base;
00252 static int bases[] = { -666, -666, 2, 4, 8, 16, 32, 64, 128, 256, 512 };
00253
00254
00255 if(!ScanBytesLeft) return(true);
00256 positive = consumeScanBit();
00257 if(n == 1) {
00258
00259 if(positive) CoeffInAdditionalBits = 1;
00260 else CoeffInAdditionalBits = -1;
00261 return(false);
00262 }
00263
00264
00265 base = bases[n];
00266 if(!positive) {
00267 base *= 2;
00268 base = -base;
00269 base++;
00270 }
00271 n--;
00272 CoeffInAdditionalBits = 0;
00273 while(n) {
00274
00275 if(!ScanBytesLeft) return(true);
00276
00277 CoeffInAdditionalBits *= 2;
00278
00279 if(consumeScanBit())
00280 CoeffInAdditionalBits += 1;
00281
00282 n--;
00283 }
00284 CoeffInAdditionalBits += base;
00285
00286 return(false);
00287 }
00288
00290 void idct(short *blk);
00292 void dct(short *blk);
00293
00294 private:
00295 void idctrow(short *blk);
00296 void idctcol(short *blk);
00297
00298 };
00299 };
00300
00301
00302
00303 #endif // __MX_MXPEGSCANDECODERSOFTWAREONLYCORE_H__