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

mxcpcFramewiseMxPEGScanToJPEGConverterIPP.cpp

00001 //           ///          //
00002 //          /////        ////
00003 //         /// XXX     XXX ///
00004 //        ///    XXX XXX    ///     $RCSfile: mxcpcFramewiseMxPEGScanToJPEGConverterIPP.cpp,v $  
00005 //       ///       XXX       ///     $Revision: 1.1 $
00006 //      ///      XXX XXX      ///     $Date: 2005/12/20 16:41:56 $
00007 //     ////    XXX     XXX    ////     $Author: cvs-kai $
00008 //    ////                     ////
00009 //   ////  M  O  B  O  T  I  X  ////////////////////////////////////////////////
00010 //  //// Security Vision Systems ///////////////////////////////////////////////
00011 
00012 
00013 
00014 #include <mxcpcFramewiseMxPEGScanToJPEGConverterIPP.h>
00015 #include <mxcpcMxPEGDecoderBackEnd.h>
00016 #include <mxcpcJPEGReceiver.h> 
00017 #include <mxcpc_exceptions.h>
00018 
00019 #include <memory>
00020 
00021 
00022 
00023 const unsigned char mxcpcFramewiseMxPEGScanToJPEGConverterIPP
00024                      ::ZigZag_StoreMap[64] = {
00025   0,  1,  5,  6, 14, 15, 27, 28,
00026   2,  4,  7, 13, 16, 26, 29, 42,
00027   3,  8, 12, 17, 25, 30, 41, 43,
00028   9, 11, 18, 24, 31, 40, 44, 53,
00029   10, 19, 23, 32, 39, 45, 52, 54,
00030   20, 22, 33, 38, 46, 51, 55, 60,
00031   21, 34, 37, 47, 50, 56, 59, 61,
00032   35, 36, 48, 49, 57, 58, 62, 63
00033 };
00034 
00035 
00036 
00037 mxcpcFramewiseMxPEGScanToJPEGConverterIPP
00038  ::mxcpcFramewiseMxPEGScanToJPEGConverterIPP(mxcpcJPEGReceiver *receiver)
00039     : mxcpcFramewiseMxPEGScanToJPEGConverter(receiver)                    {
00040 
00041   int huffman_size;
00042   int i;
00043   
00044   HuffmanTree_Y_DC  = 0;
00045   HuffmanTree_Y_AC  = 0;
00046   HuffmanTree_UV_DC = 0;
00047   HuffmanTree_UV_AC = 0;
00048   HuffmanEncodeSpec_Y_DC  = 0;
00049   HuffmanEncodeSpec_Y_AC  = 0;
00050   HuffmanEncodeSpec_UV_DC = 0;
00051   HuffmanEncodeSpec_UV_AC = 0;
00052     
00053   ippiDecodeHuffmanSpecGetBufSize_JPEG_8u(&huffman_size);
00054   HuffmanTree_Y_DC  = (IppiDecodeHuffmanSpec *)std::malloc(huffman_size);
00055   HuffmanTree_Y_AC  = (IppiDecodeHuffmanSpec *)std::malloc(huffman_size);
00056   HuffmanTree_UV_DC = (IppiDecodeHuffmanSpec *)std::malloc(huffman_size);
00057   HuffmanTree_UV_AC = (IppiDecodeHuffmanSpec *)std::malloc(huffman_size);
00058   ippiEncodeHuffmanSpecGetBufSize_JPEG_8u(&huffman_size);
00059   HuffmanEncodeSpec_Y_DC  = (IppiEncodeHuffmanSpec *)std::malloc(huffman_size);
00060   HuffmanEncodeSpec_Y_AC  = (IppiEncodeHuffmanSpec *)std::malloc(huffman_size);
00061   HuffmanEncodeSpec_UV_DC = (IppiEncodeHuffmanSpec *)std::malloc(huffman_size);
00062   HuffmanEncodeSpec_UV_AC = (IppiEncodeHuffmanSpec *)std::malloc(huffman_size);
00063   
00064   if(   !HuffmanTree_Y_DC
00065      || !HuffmanTree_Y_AC
00066      || !HuffmanTree_UV_DC
00067      || !HuffmanTree_UV_AC
00068      || !HuffmanEncodeSpec_Y_DC
00069      || !HuffmanEncodeSpec_Y_AC
00070      || !HuffmanEncodeSpec_UV_DC
00071      || !HuffmanEncodeSpec_UV_AC) {
00072     
00073     std::free(HuffmanTree_Y_DC);
00074     std::free(HuffmanTree_Y_AC);
00075     std::free(HuffmanTree_UV_DC);
00076     std::free(HuffmanTree_UV_AC);
00077     std::free(HuffmanEncodeSpec_Y_DC);
00078     std::free(HuffmanEncodeSpec_Y_AC);
00079     std::free(HuffmanEncodeSpec_UV_DC);
00080     std::free(HuffmanEncodeSpec_UV_AC);
00081     
00082     throw std::bad_alloc();
00083   }
00084   
00085   try {
00086      
00087     if(ippiDecodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_Y_DC[0],
00088                                          &DefaultHuffmanTable_Y_DC[16],
00089                                          HuffmanTree_Y_DC)
00090         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00091     if(ippiDecodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_Y_AC[0],
00092                                          &DefaultHuffmanTable_Y_AC[16],
00093                                          HuffmanTree_Y_AC)
00094         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00095     if(ippiDecodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_UV_DC[0],
00096                                          &DefaultHuffmanTable_UV_DC[16],
00097                                          HuffmanTree_UV_DC)
00098         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00099     if(ippiDecodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_UV_AC[0],
00100                                          &DefaultHuffmanTable_UV_AC[16],
00101                                          HuffmanTree_UV_AC)
00102         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00103              
00104     if(ippiEncodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_Y_DC[0],
00105                                          &DefaultHuffmanTable_Y_DC[16],
00106                                          HuffmanEncodeSpec_Y_DC)
00107         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00108     if(ippiEncodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_Y_AC[0],
00109                                          &DefaultHuffmanTable_Y_AC[16],
00110                                          HuffmanEncodeSpec_Y_AC)
00111         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00112     if(ippiEncodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_UV_DC[0],
00113                                          &DefaultHuffmanTable_UV_DC[16],
00114                                          HuffmanEncodeSpec_UV_DC)
00115         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00116     if(ippiEncodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_UV_AC[0],
00117                                          &DefaultHuffmanTable_UV_AC[16],
00118                                          HuffmanEncodeSpec_UV_AC)
00119         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00120         
00121   } catch(mxcpcDidntWorkOutException) {
00122   
00123       std::free(HuffmanTree_Y_DC);
00124       std::free(HuffmanTree_Y_AC);
00125       std::free(HuffmanTree_UV_DC);
00126       std::free(HuffmanTree_UV_AC);
00127       std::free(HuffmanEncodeSpec_Y_DC);
00128       std::free(HuffmanEncodeSpec_Y_AC);
00129       std::free(HuffmanEncodeSpec_UV_DC);
00130       std::free(HuffmanEncodeSpec_UV_AC);
00131       
00132       throw;
00133     }
00134     
00135   for(i = 0; i < 64; i++) {
00136     QuantizationTable_Y[i]  = 0;
00137     QuantizationTable_UV[i] = 0;
00138   }
00139   
00140   CoeffBuffer = 0;
00141   TileNumX = TileNumY = 0;
00142   
00143   FramesProcessed = 0;
00144   
00145   
00146   // init APP0 - taken from Klaus' jp-hdr.c (20050422)...
00147   APP0_Block.ff          = 0xff;
00148   APP0_Block.app0_marker = mxcpc_mxpeg::MarkerId_APP0;
00149   APP0_Block.len_hi      = (sizeof(mxcpc_mxpeg::APP0) - 2) / 256;
00150   APP0_Block.len_lo      = (sizeof(mxcpc_mxpeg::APP0) - 2) % 256;
00151   std::strcpy(APP0_Block.id, "JFIF"); 
00152   APP0_Block.major_vers  = 0x01; 
00153   APP0_Block.minor_vers  = 0x01;
00154   APP0_Block.units       = 0x00;
00155   APP0_Block.xdpu_hi     = 0;
00156   APP0_Block.xdpu_lo     = 1;
00157   APP0_Block.ydpu_hi     = 0;
00158   APP0_Block.ydpu_lo     = 1;
00159   APP0_Block.thumbnail_x = 0;
00160   APP0_Block.thumbnail_y = 0;
00161   
00162   // init SOF0, image size is zeroed out...
00163   SOF0_Block.ff                         = 0xff;
00164   SOF0_Block.marker                     = mxcpc_mxpeg::MarkerId_SOF0;
00165   SOF0_Block.len_hi                     = (sizeof(mxcpc_mxpeg::SOF0) - 2) / 256;
00166   SOF0_Block.len_lo                     = (sizeof(mxcpc_mxpeg::SOF0) - 2) % 256;
00167   SOF0_Block.data_precision             = 0x08;
00168   SOF0_Block.y_sz_hi                    = 0;
00169   SOF0_Block.y_sz_lo                    = 0;
00170   SOF0_Block.x_sz_hi                    = 0;
00171   SOF0_Block.x_sz_lo                    = 0;
00172   SOF0_Block.num_components             = 3;
00173   SOF0_Block.components[0].component_id = 1;   // Y
00174   SOF0_Block.components[0].sampl_fact   = 0x22;
00175   SOF0_Block.components[0].quant_tbl_no = 0;
00176   SOF0_Block.components[1].component_id = 2;   // U
00177   SOF0_Block.components[1].sampl_fact   = 0x11;
00178   SOF0_Block.components[1].quant_tbl_no = 1;
00179   SOF0_Block.components[2].component_id = 3;   // V
00180   SOF0_Block.components[2].sampl_fact   = 0x11;
00181   SOF0_Block.components[2].quant_tbl_no = 1;
00182   
00183   // init SOF0, image size is zeroed out...
00184   SOS_Block.ff                    = 0xff;
00185   SOS_Block.sos_marker            = mxcpc_mxpeg::MarkerId_SOS;
00186   SOS_Block.sz_hi                 = (sizeof(mxcpc_mxpeg::SOS) - 2) / 256;
00187   SOS_Block.sz_lo                 = (sizeof(mxcpc_mxpeg::SOS) - 2) % 256;
00188   SOS_Block.comps_in_scan         = 3;
00189   SOS_Block.components[0].comp_id = 1;
00190   SOS_Block.components[0].td_ta   = 0x00;
00191   SOS_Block.components[1].comp_id = 2;
00192   SOS_Block.components[1].td_ta   = 0x11;
00193   SOS_Block.components[2].comp_id = 3;
00194   SOS_Block.components[2].td_ta   = 0x11;
00195   SOS_Block.Ss                    = 0x00;
00196   SOS_Block.Se                    = 0x3f;
00197   SOS_Block.Ah_Al                 = 0x00;
00198 }   
00199 
00200 
00201 mxcpcFramewiseMxPEGScanToJPEGConverterIPP
00202  ::~mxcpcFramewiseMxPEGScanToJPEGConverterIPP() {
00203 
00204   std::free(HuffmanTree_Y_DC);
00205   std::free(HuffmanTree_Y_AC);
00206   std::free(HuffmanTree_UV_DC);
00207   std::free(HuffmanTree_UV_AC);
00208   std::free(HuffmanEncodeSpec_Y_DC);
00209   std::free(HuffmanEncodeSpec_Y_AC);
00210   std::free(HuffmanEncodeSpec_UV_DC);
00211   std::free(HuffmanEncodeSpec_UV_AC);
00212   
00213   delete[] CoeffBuffer;
00214 }   
00215 
00216 
00217 
00218 const char *mxcpcFramewiseMxPEGScanToJPEGConverterIPP
00219             ::getAccelerationTypeString(void) {
00220                     
00221   return("Intel Performance Primitives");
00222 }
00223 
00224 
00225 void mxcpcFramewiseMxPEGScanToJPEGConverterIPP::setYQuantizationTable(
00226                                                  unsigned char *data_bytes) {
00227 
00228   ippiQuantInvTableInit_JPEG_8u16u(data_bytes,
00229                                    QuantizationTable_Y);
00230 }
00231 
00232  
00233 void mxcpcFramewiseMxPEGScanToJPEGConverterIPP::setUVQuantizationTable(
00234                                                  unsigned char *data_bytes) {
00235 
00236   ippiQuantInvTableInit_JPEG_8u16u(data_bytes,
00237                                    QuantizationTable_UV);
00238 }
00239 
00240 
00241 void mxcpcFramewiseMxPEGScanToJPEGConverterIPP
00242       ::performScanSweep(mxcpcFramewiseMxPEGDecoder::UndecodedFrameDescriptor 
00243                           *frame_descriptor)                                  {
00244                           
00245   // init some local data facilitating invocation of the IPP routines...
00246   //   done only once for an entire scan sweep, so we can do this here on the
00247   //   stack...
00248   const IppiDecodeHuffmanSpec *dc_huffman_trees[6] = { HuffmanTree_Y_DC,
00249                                                        HuffmanTree_Y_DC,
00250                                                        HuffmanTree_Y_DC, 
00251                                                        HuffmanTree_Y_DC,
00252                                                        HuffmanTree_UV_DC, 
00253                                                        HuffmanTree_UV_DC,                                      
00254                                                      };    
00255   const IppiDecodeHuffmanSpec *ac_huffman_trees[6] = { HuffmanTree_Y_AC,
00256                                                        HuffmanTree_Y_AC,
00257                                                        HuffmanTree_Y_AC, 
00258                                                        HuffmanTree_Y_AC,
00259                                                        HuffmanTree_UV_AC, 
00260                                                        HuffmanTree_UV_AC,                                      
00261                                                      };
00262   const IppiEncodeHuffmanSpec *dc_huffman_encode_specs[6] = { HuffmanEncodeSpec_Y_DC,
00263                                                               HuffmanEncodeSpec_Y_DC,
00264                                                               HuffmanEncodeSpec_Y_DC,
00265                                                               HuffmanEncodeSpec_Y_DC,
00266                                                               HuffmanEncodeSpec_UV_DC,
00267                                                               HuffmanEncodeSpec_UV_DC,
00268                                                             };
00269   const IppiEncodeHuffmanSpec *ac_huffman_encode_specs[6] = { HuffmanEncodeSpec_Y_AC,
00270                                                               HuffmanEncodeSpec_Y_AC,
00271                                                               HuffmanEncodeSpec_Y_AC,
00272                                                               HuffmanEncodeSpec_Y_AC,
00273                                                               HuffmanEncodeSpec_UV_AC,
00274                                                               HuffmanEncodeSpec_UV_AC,
00275                                                             };
00276   Ipp16s last_y_dc = 0, last_u_dc = 0, last_v_dc = 0;
00277   Ipp16s *last_dc_ptrs[6] = { &last_y_dc, &last_y_dc, &last_y_dc, &last_y_dc,
00278                               &last_u_dc, &last_v_dc
00279                             };
00280   int detected_marker = 0;
00281   Ipp32u prefetched_bits = 0;
00282   int prefetched_bit_num = 0;
00283   int pos = 0;
00284   Ipp8u bitstream_buffer[MXCPC_FRAMEWISEMXPEGSCANTOJPEGCONVERTERIPP_BITSTREAM_BUFFSIZE];
00285   int bitstream_pos = 0;
00286   
00287   // remaining local data...
00288   IppStatus ipp_status;
00289   bool use_bitmask;
00290   int tilebits_left;
00291   unsigned char *tilebit_ptr, tilebit_mask;
00292   int x, y;
00293   bool next_tile_right_here;
00294   int tiles_to_write;
00295   Ipp16s *sub_mcu_coeffs;
00296   mxcpc::u8 quantization_table_to_write[64];
00297   Ipp16u *quant_coeff;
00298   const unsigned char *huffman_table_to_write;
00299   int                  huffman_table_to_write_size;
00300   int i, j;
00301   
00302   mxcpc::u8 write_buffer[10];
00303     
00304   
00305   // guard against missing backend
00306   if(!BackEnd) return;
00307   
00308   
00309   // check coeff buffer and its dimensions...
00310   if(   (frame_descriptor->TileNumX != TileNumX)
00311      || (frame_descriptor->TileNumY != TileNumY)) {
00312   
00313     delete[] CoeffBuffer;
00314     
00315     try {
00316     
00317       CoeffBuffer = new Ipp16s[frame_descriptor->TileNumX * frame_descriptor->TileNumY
00318                                 * 6 * 64];
00319       TileNumX = frame_descriptor->TileNumX;
00320       TileNumY = frame_descriptor->TileNumY;
00321       
00322       mxcpc::sendStatusMsg("JPG converter : reallocated coeff buffer");
00323                                 
00324     } catch(std::bad_alloc) {
00325       
00326         CoeffBuffer = 0;
00327         TileNumX = TileNumY = 0;
00328       }
00329   }  
00330   if(!CoeffBuffer) {
00331     BackEnd->errorEncountered();
00332     return;
00333   } 
00334       
00335     
00336   // decide for bitmask mode...
00337   tilebits_left = frame_descriptor->TileNumX * frame_descriptor->TileNumY;
00338   tilebit_ptr   = frame_descriptor->TileBits;
00339   tilebit_mask  = 128;
00340   x = -1;
00341   y = 0;
00342   ipp_status = ippStsNoErr;
00343   next_tile_right_here = true;   // default for bitmask-less mode
00344   if(tilebit_ptr) 
00345     use_bitmask = true;
00346   else
00347     use_bitmask = false;
00348    
00349     
00350   // iterate over all tiles (MCUs)...
00351   while(tilebits_left) {
00352   
00353     // advance target tile coordinates...
00354     x++;
00355     if(x == frame_descriptor->TileNumX) {
00356       x = 0;
00357       y++;
00358     }
00359   
00360     // if in bitmask mode, consume and honor current tile bit...
00361     if(use_bitmask) {
00362       next_tile_right_here = (*tilebit_ptr & tilebit_mask) != 0;
00363       tilebit_mask /= 2;
00364       if(!tilebit_mask) {
00365         tilebit_mask = 128;
00366         tilebit_ptr++;
00367       }
00368     }
00369    
00370     if(next_tile_right_here) {   // decode tile...
00371       
00372       // iterate over the 6 sub-MCUs (Y,Y,Y,Y,U,V)...
00373       for(i = 0; i < 6; i++) {
00374        
00375         if(ipp_status != ippStsNoErr) {   // decoding of previous sub-MCU caused
00376                                           // an error - better stop...
00377           BackEnd->errorEncountered();
00378           return;
00379         }
00380         
00381         ipp_status = ippiDecodeHuffman8x8_Direct_JPEG_1u16s_C1(
00382                       frame_descriptor->ScanBytes, &pos,
00383                       &CoeffBuffer[y * TileNumX * 6*64  +  x * 6*64  +  i * 64],
00384                       last_dc_ptrs[i],
00385                       &detected_marker,
00386                       &prefetched_bits, &prefetched_bit_num,
00387                       dc_huffman_trees[i], ac_huffman_trees[i]);
00388       }
00389       
00390       // got all 6 sub-MCUs!
00391             
00392       BackEnd->videoTileReceived();
00393     } 
00394     
00395     tilebits_left--;
00396   }
00397   
00398   // ok, got a frame...
00399   
00400   Receiver->beginFrame();
00401   
00402   // write SOI...
00403   write_buffer[0] = 0xff;
00404   write_buffer[1] = mxcpc_mxpeg::MarkerId_SOI;
00405   Receiver->receiveJPEGBytes(write_buffer, 2);
00406   
00407   // write APP0...
00408   Receiver->receiveJPEGBytes((mxcpc::u8 *)&APP0_Block, 
00409                              sizeof(mxcpc_mxpeg::APP0));
00410   
00411   // write quantization tables, Y(0) and UV(1)...
00412   for(i = 0; i < 2; i++) {   // got two of them
00413     
00414     write_buffer[0] = 0xff;
00415     write_buffer[1] = mxcpc_mxpeg::MarkerId_DQT;
00416     write_buffer[2] = 0;
00417     write_buffer[3] = 67;
00418     write_buffer[4] = i;
00419     Receiver->receiveJPEGBytes(write_buffer, 5);
00420   
00421     if(!i) quant_coeff = QuantizationTable_Y;
00422     else   quant_coeff = QuantizationTable_UV;
00423     for(j = 0; j < 64; j++) 
00424       quantization_table_to_write[ZigZag_StoreMap[j]] = *quant_coeff++;
00425     Receiver->receiveJPEGBytes(quantization_table_to_write, 64);
00426   }
00427   
00428   // write SOF0...
00429   SOF0_Block.x_sz_hi = frame_descriptor->Width / 256;
00430   SOF0_Block.x_sz_lo = frame_descriptor->Width % 256;
00431   SOF0_Block.y_sz_hi = frame_descriptor->Height / 256;
00432   SOF0_Block.y_sz_lo = frame_descriptor->Height % 256;
00433   Receiver->receiveJPEGBytes((mxcpc::u8 *)&SOF0_Block, 
00434                              sizeof(mxcpc_mxpeg::SOF0));
00435   
00436   // write huffman tables...
00437   for(i = 0; i < 4; i++) {   // got four of them
00438   
00439     write_buffer[0] = 0xff;
00440     write_buffer[1] = mxcpc_mxpeg::MarkerId_DHT;
00441     if(i == 0) {
00442       write_buffer[4] = 0x00;
00443       huffman_table_to_write      = DefaultHuffmanTable_Y_DC;
00444       huffman_table_to_write_size = DefaultHuffmanTable_Y_DC_Size;
00445     }
00446     else if(i == 1) {
00447       write_buffer[4] = 0x10;
00448       huffman_table_to_write      = DefaultHuffmanTable_Y_AC;
00449       huffman_table_to_write_size = DefaultHuffmanTable_Y_AC_Size;
00450     }
00451     else if(i == 2) {
00452       write_buffer[4] = 0x01;
00453       huffman_table_to_write      = DefaultHuffmanTable_UV_DC;
00454       huffman_table_to_write_size = DefaultHuffmanTable_UV_DC_Size;
00455     }
00456     else {
00457       write_buffer[4] = 0x11;
00458       huffman_table_to_write      = DefaultHuffmanTable_UV_AC;
00459       huffman_table_to_write_size = DefaultHuffmanTable_UV_AC_Size;
00460     }
00461     write_buffer[2] = (huffman_table_to_write_size + 3) / 256;
00462     write_buffer[3] = (huffman_table_to_write_size + 3) % 256;
00463   
00464     Receiver->receiveJPEGBytes(write_buffer, 5);
00465     Receiver->receiveJPEGBytes((mxcpc::u8 *)huffman_table_to_write, 
00466                                huffman_table_to_write_size);
00467   }  
00468   
00469   // write SOS...
00470   Receiver->receiveJPEGBytes((mxcpc::u8 *)&SOS_Block, 
00471                              sizeof(mxcpc_mxpeg::SOS));
00472   
00473   // write out scan...
00474   last_y_dc = last_u_dc = last_v_dc = 0;
00475   sub_mcu_coeffs = CoeffBuffer;
00476   bitstream_pos  = 0;
00477   tiles_to_write = TileNumX * TileNumY;
00478   while(tiles_to_write) {
00479   
00480     // iterate over sub-MCUs of current tile...
00481     for(i = 0; i < 6; i++) {
00482          
00483       ippiEncodeHuffman8x8_Direct_JPEG_16s1u_C1(sub_mcu_coeffs,
00484                                                 bitstream_buffer,
00485                                                 &bitstream_pos,
00486                                                 last_dc_ptrs[i],
00487                                                 dc_huffman_encode_specs[i],
00488                                                 ac_huffman_encode_specs[i]);
00489   
00490       if(bitstream_pos >= 8) {
00491         
00492         Receiver->receiveJPEGBytes(bitstream_buffer, bitstream_pos/8);
00493                                                                                               
00494         // copy down partially filled byte at the end...
00495         bitstream_buffer[0] = bitstream_buffer[bitstream_pos/8];
00496         bitstream_pos = bitstream_pos % 8;
00497       }
00498                                                  
00499       sub_mcu_coeffs += 64;
00500     }
00501     
00502     tiles_to_write--;
00503   }
00504   
00505   // deal with last byte
00506   Receiver->receiveJPEGBytes(bitstream_buffer, 1);   // pad unused bits?
00507   
00508   // write EOI...
00509   write_buffer[0] = 0xff;
00510   write_buffer[1] = mxcpc_mxpeg::MarkerId_EOI;
00511   Receiver->receiveJPEGBytes(write_buffer, 2);
00512    
00513   Receiver->endFrame();
00514   // TODO : forward error from converter backend to decoder backend
00515   
00516   FramesProcessed++;
00517 }

Generated on Mon Jan 30 15:13:07 2006 for mxcpc by  doxygen 1.4.4