Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

mxcpcFramewiseMxPEGScanDecoderSoftwareOnly.h

00001 //           ///          //                                        Mx clientSDK
00002 //          /////        ////                    Mx Crossplatform Client Library
00003 //         /// XXX     XXX ///
00004 //        ///    XXX XXX    ///     $RCSfile: mxcpcFramewiseMxPEGScanDecoderSoftwareOnly.h,v $
00005 //       ///       XXX       ///     $Revision: 1.4 $
00006 //      ///      XXX XXX      ///     $Date: 2005/12/20 16:41:55 $
00007 //     ////    XXX     XXX    ////     $Author: cvs-kai $
00008 //    ////                     ////
00009 //   ////  M  O  B  O  T  I  X  ////////////////////////////////////////////////
00010 //  //// Security Vision Systems //////////////////////////////////////////////
00011 //                                                                          //
00012 //  Copyright (C) 2005 - 2006, MOBOTIX AG, Germany                         //
00013 //  This software is made available under the BSD licence. Please refer   //
00014 //  to the file LICENCE.TXT contained in this distribution for details.  //
00015 //                                                                      //
00016 //  /////////////////////////////////////////////////////////////////////
00017 
00018 
00019 
00020 #ifndef __MXCPC_FRAMEWISEMXPEGSCANDECODERSOFTWAREONLY_H__
00021 #define __MXCPC_FRAMEWISEMXPEGSCANDECODERSOFTWAREONLY_H__
00022 
00023 
00024 
00025 #include <mxcpcFramewiseMxPEGScanDecoder.h>
00026 #include <mxcpcHuffmanTree.h>
00027 #include <mxcpc_namespace.h>
00028 
00029 #include <cstring>
00030 #include <cstdlib>
00031 #include <cstdio>
00032 
00033 
00034 
00035 //! Software-only decoding module to be used with the framewise (frame 
00036 //! prefetching) <tt>MxPEG</tt> decoder facility implemented by
00037 //! mxcpcFramewiseMxPEGDecoder.
00038 /*!
00039  *  \ingroup mxcpc_core
00040  *
00041  *  Through this portable scan decoder implementation we establish baseline
00042  *  <tt>MxPEG</tt> decoding on all three major target platforms in a fashion
00043  *  entirely independent of additional support libraries like Intel's IPP.
00044  *  However, where available the performance benefits of such support libraries
00045  *  can be exploited by plugging into the mxcpcFramewiseMxPEGDecoder another
00046  *  scan decoder implementation, for example the 
00047  *  mxcpcFramewiseMxPEGScanDecoderIPP.
00048  *
00049  *  \author Kai Hergenroether
00050  */
00051 class mxcpcFramewiseMxPEGScanDecoderSoftwareOnly : public mxcpcFramewiseMxPEGScanDecoder {
00052 
00053  private:
00054   static const int ZigZagMap[64];
00055   static short iclip[1024];
00056   static short *iclp;
00057         
00058  private:
00059   mxcpcHuffmanTree *HuffmanTree_Y_DC, 
00060                    *HuffmanTree_Y_AC;         
00061   mxcpcHuffmanTree *HuffmanTree_UV_DC, 
00062                    *HuffmanTree_UV_AC;
00063   mxcpc::s16 QuantizationTable_Y[64],
00064              QuantizationTable_UV[64];
00065                     
00066   // The following fields' state is defined to only be valid during scan sweeps
00067   // - so they won't show up in the constructor...
00068   unsigned char *CurrentScanByte,
00069                 ScanMask;
00070   int ScanBytesLeft;
00071   int CoeffInAdditionalBits;      
00072   
00073  public:
00074   mxcpcFramewiseMxPEGScanDecoderSoftwareOnly();
00075   ~mxcpcFramewiseMxPEGScanDecoderSoftwareOnly();
00076  
00077  public:
00078   //! (Re)implemented.
00079   const char *getAccelerationTypeString(void);
00080   //! (Re)implemented.
00081   void setYQuantizationTable(unsigned char *data_bytes);
00082   //! (Re)implemented.
00083   void setUVQuantizationTable(unsigned char *data_bytes);
00084   //! (Re)implemented.
00085   void performScanSweep(mxcpcFramewiseMxPEGDecoder::UndecodedFrameDescriptor
00086                          *frame_descriptor);        
00087                          
00088  private:
00089   //! We need this often in inner loops of performScanSweep(), so we 
00090   //! request inline substitution and hope the compiler sufficiently rocks.
00091   /*!
00092    *  Only to be called if <tt>ScanBytesLeft > 0</tt>.
00093    *
00094    *  Returns whether or not the bit just consumed was set.
00095    */
00096   inline bool consumeScanBit(void) {
00097     
00098     bool bit_was_set;
00099     unsigned char last_scan_byte;
00100     
00101     bit_was_set = *CurrentScanByte & ScanMask;
00102     
00103     ScanMask /= 2;
00104     if(!ScanMask) {
00105      
00106       last_scan_byte = *CurrentScanByte;
00107     
00108       CurrentScanByte++;
00109       ScanBytesLeft--;
00110       if(last_scan_byte == 0xff) {
00111         if(*CurrentScanByte == 0x00) {
00112           if(!ScanBytesLeft) {
00113             mxcpc::sendStatusMsg("not more scan bytes!");
00114             std::exit(666);
00115           }
00116           else {
00117             CurrentScanByte++;
00118             ScanBytesLeft--;
00119           }
00120         }
00121         else {
00122           mxcpc::sendStatusMsg("unexpected marker encountered!");
00123           std::exit(666);
00124         }
00125       
00126         //mxcpc::sendStatusMsg("warning: 0xff in datastream, feeding now, checking later!");
00127       }
00128       
00129       ScanMask = 128;
00130     }
00131     
00132     return(bit_was_set);
00133   }
00134   
00135   //! We need this often in inner loops of performScanSweep(), so we 
00136   //! request inline substitution and hope the compiler sufficiently rocks.
00137   /*!
00138    *  Specify as argument the root of the Huffman tree to be used for codeword
00139    *  recognition.
00140    * 
00141    *  Internally checks for <tt>ScanBytesLeft > 0</tt>.
00142    *
00143    *  Returns the Huffman leaf node corresponding to the codeword just
00144    *  consumed or <tt>0</tt> in case of failure. Failure conditions can be
00145    *  - an invalid bitstring was encountered
00146    *  - all scan bytes were cosumed before a valid codeword was detected 
00147    */
00148   inline const mxcpcHuffmanTree
00149                  ::Node *consumeHuffmanCodeword(
00150                           const mxcpcHuffmanTree::Node *current_huffman_node) {
00151   
00152     const mxcpcHuffmanTree::Node *last_huffman_node;
00153     
00154     do {
00155          
00156       if(!ScanBytesLeft) return(0);
00157      
00158       last_huffman_node = current_huffman_node;
00159           
00160       if(consumeScanBit())
00161         current_huffman_node = current_huffman_node->Child1;
00162       else 
00163         current_huffman_node = current_huffman_node->Child0; 
00164         
00165       if(current_huffman_node == last_huffman_node) {
00166         std::printf(" !!! invalid codeword !!!\n");
00167         std::exit(666);
00168         return(0);
00169       }
00170               
00171     } while(!current_huffman_node->IsLeaf);
00172     
00173     return(current_huffman_node);
00174   }
00175   
00176   //! We need this often in inner loops of performScanSweep(), so we 
00177   //! request inline substitution and hope the compiler sufficiently rocks.
00178   /*!
00179    *  Specify as argument the number <tt>n >= 1</tt> of additional bits to 
00180    *  read. 
00181    *  
00182    *  The coefficient represented by the read bits will be stored to the
00183    *  class member variable <tt>CoeffInAdditionalBits</tt>.
00184    *
00185    *  The method internally checks for <tt>ScanBytesLeft > 0</tt>.
00186    *
00187    *  It returns <tt>false</tt> on success, and <tt>true</tt> if all scan
00188    *  bytes were cosumed before a valid codeword was detected. 
00189    */
00190   inline bool consumeAdditionalBits(int n) {
00191   
00192     bool positive;
00193     int base;
00194     static int bases[] = { -666, -666, 2, 4, 8, 16, 32, 64, 128, 256, 512 };    
00195     
00196     // read first bit...
00197     if(!ScanBytesLeft) return(true);
00198     positive = consumeScanBit();
00199     if(n == 1) {
00200       if(positive) CoeffInAdditionalBits =  1;
00201       else         CoeffInAdditionalBits = -1;
00202       return(false);
00203     }
00204     
00205     // read remaining bits...
00206     base = bases[n];
00207     if(!positive) {
00208       base *= 2;
00209       base = -base;
00210       base++;
00211     }
00212     n--;
00213     CoeffInAdditionalBits = 0;
00214     while(n) {
00215     
00216       if(!ScanBytesLeft) return(true);
00217       
00218       CoeffInAdditionalBits *= 2;
00219       
00220       if(consumeScanBit()) 
00221         CoeffInAdditionalBits += 1;
00222        
00223       n--;
00224     }
00225     CoeffInAdditionalBits += base;  
00226     
00227     return(false);
00228   }
00229   
00230   
00231   //! Stolen.
00232   void idctrow(short *blk);
00233   //! Stolen.
00234   void idctcol(short *blk);
00235   //! Stolen.
00236   void idct(short *blk);
00237 };
00238 
00239 
00240 
00241 #endif   // __MXCPC_FRAMEWISEMXPEGSCANDECODERSOFTWAREONLY_H__

Generated on Mon Jan 30 15:52:42 2006 for mxcpc by  doxygen 1.4.4