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

mxcpcFramewiseMxPEGScanToJPEGConverterIPP.cpp

00001 //           ///          //
00002 //          /////        ////
00003 //         /// XXX     XXX ///
00004 //        ///    XXX XXX    ///     $RCSfile: mxcpcFramewiseMxPEGScanToJPEGConverterIPP.cpp,v $  
00005 //       ///       XXX       ///     $Revision: 1.4 $
00006 //      ///      XXX XXX      ///     $Date: 2005/08/09 13:57:26 $
00007 //     ////    XXX     XXX    ////     $Author: cvs-steve $
00008 //    ////                     ////
00009 //   ////  M  O  B  O  T  I  X  ////////////////////////////////////////////////
00010 //  //// Security Vision Systems ///////////////////////////////////////////////
00011 
00012 // Copyright (c) 2005, MOBOTIX AG.
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 #include <mxcpcFramewiseMxPEGScanToJPEGConverterIPP.h>
00018 #include <mxcpcMxPEGDecoderBackEnd.h>
00019 #include <mxcpcMxPEGScanToJPEGConverterBackEnd.h> 
00020 #include <mxcpc_exceptions.h>
00021 
00022 #include <memory>
00023 
00024 
00025 
00026 const unsigned char mxcpcFramewiseMxPEGScanToJPEGConverterIPP::ZigZag_StoreMap[64] = {
00027   0,  1,  5,  6, 14, 15, 27, 28,
00028   2,  4,  7, 13, 16, 26, 29, 42,
00029   3,  8, 12, 17, 25, 30, 41, 43,
00030   9, 11, 18, 24, 31, 40, 44, 53,
00031   10, 19, 23, 32, 39, 45, 52, 54,
00032   20, 22, 33, 38, 46, 51, 55, 60,
00033   21, 34, 37, 47, 50, 56, 59, 61,
00034   35, 36, 48, 49, 57, 58, 62, 63
00035 };
00036 
00037 
00038 
00039 mxcpcFramewiseMxPEGScanToJPEGConverterIPP::mxcpcFramewiseMxPEGScanToJPEGConverterIPP(
00040                                             mxcpcMxPEGScanToJPEGConverterBackEnd *backend
00041                                            )                                             {
00042 
00043   int huffman_size;
00044   int i;
00045   
00046   HuffmanTree_Y_DC  = 0;
00047   HuffmanTree_Y_AC  = 0;
00048   HuffmanTree_UV_DC = 0;
00049   HuffmanTree_UV_AC = 0;
00050   HuffmanEncodeSpec_Y_DC  = 0;
00051   HuffmanEncodeSpec_Y_AC  = 0;
00052   HuffmanEncodeSpec_UV_DC = 0;
00053   HuffmanEncodeSpec_UV_AC = 0;
00054     
00055   ippiDecodeHuffmanSpecGetBufSize_JPEG_8u(&huffman_size);
00056   HuffmanTree_Y_DC  = (IppiDecodeHuffmanSpec *)std::malloc(huffman_size);
00057   HuffmanTree_Y_AC  = (IppiDecodeHuffmanSpec *)std::malloc(huffman_size);
00058   HuffmanTree_UV_DC = (IppiDecodeHuffmanSpec *)std::malloc(huffman_size);
00059   HuffmanTree_UV_AC = (IppiDecodeHuffmanSpec *)std::malloc(huffman_size);
00060   ippiEncodeHuffmanSpecGetBufSize_JPEG_8u(&huffman_size);
00061   HuffmanEncodeSpec_Y_DC  = (IppiEncodeHuffmanSpec *)std::malloc(huffman_size);
00062   HuffmanEncodeSpec_Y_AC  = (IppiEncodeHuffmanSpec *)std::malloc(huffman_size);
00063   HuffmanEncodeSpec_UV_DC = (IppiEncodeHuffmanSpec *)std::malloc(huffman_size);
00064   HuffmanEncodeSpec_UV_AC = (IppiEncodeHuffmanSpec *)std::malloc(huffman_size);
00065   
00066   if(   !HuffmanTree_Y_DC
00067      || !HuffmanTree_Y_AC
00068      || !HuffmanTree_UV_DC
00069      || !HuffmanTree_UV_AC
00070      || !HuffmanEncodeSpec_Y_DC
00071      || !HuffmanEncodeSpec_Y_AC
00072      || !HuffmanEncodeSpec_UV_DC
00073      || !HuffmanEncodeSpec_UV_AC) {
00074     
00075     std::free(HuffmanTree_Y_DC);
00076     std::free(HuffmanTree_Y_AC);
00077     std::free(HuffmanTree_UV_DC);
00078     std::free(HuffmanTree_UV_AC);
00079     std::free(HuffmanEncodeSpec_Y_DC);
00080     std::free(HuffmanEncodeSpec_Y_AC);
00081     std::free(HuffmanEncodeSpec_UV_DC);
00082     std::free(HuffmanEncodeSpec_UV_AC);
00083     
00084     throw std::bad_alloc();
00085   }
00086   
00087   try {
00088      
00089     if(ippiDecodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_Y_DC[0],
00090                                          &DefaultHuffmanTable_Y_DC[16],
00091                                          HuffmanTree_Y_DC)
00092         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00093     if(ippiDecodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_Y_AC[0],
00094                                          &DefaultHuffmanTable_Y_AC[16],
00095                                          HuffmanTree_Y_AC)
00096         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00097     if(ippiDecodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_UV_DC[0],
00098                                          &DefaultHuffmanTable_UV_DC[16],
00099                                          HuffmanTree_UV_DC)
00100         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00101     if(ippiDecodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_UV_AC[0],
00102                                          &DefaultHuffmanTable_UV_AC[16],
00103                                          HuffmanTree_UV_AC)
00104         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00105              
00106     if(ippiEncodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_Y_DC[0],
00107                                          &DefaultHuffmanTable_Y_DC[16],
00108                                          HuffmanEncodeSpec_Y_DC)
00109         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00110     if(ippiEncodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_Y_AC[0],
00111                                          &DefaultHuffmanTable_Y_AC[16],
00112                                          HuffmanEncodeSpec_Y_AC)
00113         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00114     if(ippiEncodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_UV_DC[0],
00115                                          &DefaultHuffmanTable_UV_DC[16],
00116                                          HuffmanEncodeSpec_UV_DC)
00117         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00118     if(ippiEncodeHuffmanSpecInit_JPEG_8u(&DefaultHuffmanTable_UV_AC[0],
00119                                          &DefaultHuffmanTable_UV_AC[16],
00120                                          HuffmanEncodeSpec_UV_AC)
00121         != ippStsNoErr) throw mxcpcDidntWorkOutException();
00122         
00123   } catch(mxcpcDidntWorkOutException) {
00124   
00125       std::free(HuffmanTree_Y_DC);
00126       std::free(HuffmanTree_Y_AC);
00127       std::free(HuffmanTree_UV_DC);
00128       std::free(HuffmanTree_UV_AC);
00129       std::free(HuffmanEncodeSpec_Y_DC);
00130       std::free(HuffmanEncodeSpec_Y_AC);
00131       std::free(HuffmanEncodeSpec_UV_DC);
00132       std::free(HuffmanEncodeSpec_UV_AC);
00133       
00134       throw;
00135     }
00136     
00137   for(i = 0; i < 64; i++) {
00138     QuantizationTable_Y[i]  = 0;
00139     QuantizationTable_UV[i] = 0;
00140   }
00141   
00142   CoeffBuffer = 0;
00143   TileNumX = TileNumY = 0;
00144   
00145   //  OutStream = stdout;
00146   FramesProcessed = 0;
00147   
00148   ConverterBackEnd = backend;
00149   
00150   
00151   // init APP0 - taken from Klaus' jp-hdr.c (20050422)...
00152   APP0_Block.ff          = 0xff;
00153   APP0_Block.app0_marker = mxcpc_mxpeg::MarkerId_APP0;
00154   APP0_Block.len_hi      = (sizeof(mxcpc_mxpeg::APP0) - 2) / 256;
00155   APP0_Block.len_lo      = (sizeof(mxcpc_mxpeg::APP0) - 2) % 256;
00156   std::strcpy(APP0_Block.id, "JFIF"); 
00157   APP0_Block.major_vers  = 0x01; 
00158   APP0_Block.minor_vers  = 0x01;
00159   APP0_Block.units       = 0x00;
00160   APP0_Block.xdpu_hi     = 0;
00161   APP0_Block.xdpu_lo     = 1;
00162   APP0_Block.ydpu_hi     = 0;
00163   APP0_Block.ydpu_lo     = 1;
00164   APP0_Block.thumbnail_x = 0;
00165   APP0_Block.thumbnail_y = 0;
00166   
00167   // init SOF0, image size is zeroed out...
00168   SOF0_Block.ff                         = 0xff;
00169   SOF0_Block.marker                     = mxcpc_mxpeg::MarkerId_SOF0;
00170   SOF0_Block.len_hi                     = (sizeof(mxcpc_mxpeg::SOF0) - 2) / 256;
00171   SOF0_Block.len_lo                     = (sizeof(mxcpc_mxpeg::SOF0) - 2) % 256;
00172   SOF0_Block.data_precision             = 0x08;
00173   SOF0_Block.y_sz_hi                    = 0;
00174   SOF0_Block.y_sz_lo                    = 0;
00175   SOF0_Block.x_sz_hi                    = 0;
00176   SOF0_Block.x_sz_lo                    = 0;
00177   SOF0_Block.num_components             = 3;
00178   SOF0_Block.components[0].component_id = 1;   // Y
00179   SOF0_Block.components[0].sampl_fact   = 0x22;
00180   SOF0_Block.components[0].quant_tbl_no = 0;
00181   SOF0_Block.components[1].component_id = 2;   // U
00182   SOF0_Block.components[1].sampl_fact   = 0x11;
00183   SOF0_Block.components[1].quant_tbl_no = 1;
00184   SOF0_Block.components[2].component_id = 3;   // V
00185   SOF0_Block.components[2].sampl_fact   = 0x11;
00186   SOF0_Block.components[2].quant_tbl_no = 1;
00187   
00188   // init SOF0, image size is zeroed out...
00189   SOS_Block.ff                    = 0xff;
00190   SOS_Block.sos_marker            = mxcpc_mxpeg::MarkerId_SOS;
00191   SOS_Block.sz_hi                 = (sizeof(mxcpc_mxpeg::SOS) - 2) / 256;
00192   SOS_Block.sz_lo                 = (sizeof(mxcpc_mxpeg::SOS) - 2) % 256;
00193   SOS_Block.comps_in_scan         = 3;
00194   SOS_Block.components[0].comp_id = 1;
00195   SOS_Block.components[0].td_ta   = 0x00;
00196   SOS_Block.components[1].comp_id = 2;
00197   SOS_Block.components[1].td_ta   = 0x11;
00198   SOS_Block.components[2].comp_id = 3;
00199   SOS_Block.components[2].td_ta   = 0x11;
00200   SOS_Block.Ss                    = 0x00;
00201   SOS_Block.Se                    = 0x3f;
00202   SOS_Block.Ah_Al                 = 0x00;
00203 }   
00204 
00205 
00206 mxcpcFramewiseMxPEGScanToJPEGConverterIPP::~mxcpcFramewiseMxPEGScanToJPEGConverterIPP() {
00207 
00208   delete ConverterBackEnd;
00209 
00210   std::free(HuffmanTree_Y_DC);
00211   std::free(HuffmanTree_Y_AC);
00212   std::free(HuffmanTree_UV_DC);
00213   std::free(HuffmanTree_UV_AC);
00214   std::free(HuffmanEncodeSpec_Y_DC);
00215   std::free(HuffmanEncodeSpec_Y_AC);
00216   std::free(HuffmanEncodeSpec_UV_DC);
00217   std::free(HuffmanEncodeSpec_UV_AC);
00218   
00219   delete[] CoeffBuffer;
00220 }   
00221 
00222 
00223 
00224 void mxcpcFramewiseMxPEGScanToJPEGConverterIPP::setYQuantizationTable(
00225                                                  unsigned char *data_bytes) {
00226 
00227   ippiQuantInvTableInit_JPEG_8u16u(data_bytes,
00228                                    QuantizationTable_Y);
00229 }
00230 
00231  
00232 void mxcpcFramewiseMxPEGScanToJPEGConverterIPP::setUVQuantizationTable(
00233                                                  unsigned char *data_bytes) {
00234 
00235   ippiQuantInvTableInit_JPEG_8u16u(data_bytes,
00236                                    QuantizationTable_UV);
00237 }
00238 
00239 
00240 void mxcpcFramewiseMxPEGScanToJPEGConverterIPP
00241       ::performScanSweep(mxcpcFramewiseMxPEGDecoder::UndecodedFrameDescriptor 
00242                           *frame_descriptor)                                  {
00243                           
00244   // init some local data facilitating invocation of the IPP routines...
00245   //   done only once for an entire scan sweep, so we can do this here on the
00246   //   stack...
00247   const IppiDecodeHuffmanSpec *dc_huffman_trees[6] = { HuffmanTree_Y_DC,
00248                                                        HuffmanTree_Y_DC,
00249                                                        HuffmanTree_Y_DC, 
00250                                                        HuffmanTree_Y_DC,
00251                                                        HuffmanTree_UV_DC, 
00252                                                        HuffmanTree_UV_DC,                                      
00253                                                      };    
00254   const IppiDecodeHuffmanSpec *ac_huffman_trees[6] = { HuffmanTree_Y_AC,
00255                                                        HuffmanTree_Y_AC,
00256                                                        HuffmanTree_Y_AC, 
00257                                                        HuffmanTree_Y_AC,
00258                                                        HuffmanTree_UV_AC, 
00259                                                        HuffmanTree_UV_AC,                                      
00260                                                      };
00261   const IppiEncodeHuffmanSpec *dc_huffman_encode_specs[6] = { HuffmanEncodeSpec_Y_DC,
00262                                                               HuffmanEncodeSpec_Y_DC,
00263                                                               HuffmanEncodeSpec_Y_DC,
00264                                                               HuffmanEncodeSpec_Y_DC,
00265                                                               HuffmanEncodeSpec_UV_DC,
00266                                                               HuffmanEncodeSpec_UV_DC,
00267                                                             };
00268   const IppiEncodeHuffmanSpec *ac_huffman_encode_specs[6] = { HuffmanEncodeSpec_Y_AC,
00269                                                               HuffmanEncodeSpec_Y_AC,
00270                                                               HuffmanEncodeSpec_Y_AC,
00271                                                               HuffmanEncodeSpec_Y_AC,
00272                                                               HuffmanEncodeSpec_UV_AC,
00273                                                               HuffmanEncodeSpec_UV_AC,
00274                                                             };
00275   Ipp16s last_y_dc = 0, last_u_dc = 0, last_v_dc = 0;
00276   Ipp16s *last_dc_ptrs[6] = { &last_y_dc, &last_y_dc, &last_y_dc, &last_y_dc,
00277                               &last_u_dc, &last_v_dc
00278                             };
00279   int detected_marker = 0;
00280   Ipp32u prefetched_bits = 0;
00281   int prefetched_bit_num = 0;
00282   int pos = 0;
00283   Ipp8u bitstream_buffer[MXCPC_FRAMEWISEMXPEGSCANTOJPEGCONVERTERIPP_BITSTREAM_BUFFSIZE];
00284   int bitstream_pos = 0;
00285   
00286   // remaining local data...
00287   IppStatus ipp_status;
00288   bool use_bitmask;
00289   int tilebits_left;
00290   unsigned char *tilebit_ptr, tilebit_mask;
00291   int x, y;
00292   bool next_tile_right_here;
00293   int tiles_to_write;
00294   Ipp16s *sub_mcu_coeffs;
00295   mxcpc::u8 quantization_table_to_write[64];
00296   Ipp16u *quant_coeff;
00297   const unsigned char *huffman_table_to_write;
00298   int                  huffman_table_to_write_size;
00299   char filename[100];
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 //   std::sprintf(filename, "ExtractedJPG_%04d.jpg", FramesProcessed);
00401 //   OutStream = std::fopen(filename, "w");
00402 //   ConverterBackEnd->beginFrame();
00403   
00404   // write SOI...
00405   write_buffer[0] = 0xff;
00406   write_buffer[1] = mxcpc_mxpeg::MarkerId_SOI;
00407   //  fwrite(write_buffer, 2, 1, OutStream);
00408   ConverterBackEnd->receiveJPEGBytes(write_buffer, 2);
00409   
00410   // write APP0...
00411   //fwrite(&APP0_Block, sizeof(mxcpc_mxpeg::APP0), 1, OutStream);
00412   ConverterBackEnd->receiveJPEGBytes((mxcpc::u8 *)&APP0_Block, 
00413                                      sizeof(mxcpc_mxpeg::APP0));
00414   
00415   // write quantization tables, Y(0) and UV(1)...
00416   for(i = 0; i < 2; i++) {   // got two of them
00417     
00418     write_buffer[0] = 0xff;
00419     write_buffer[1] = mxcpc_mxpeg::MarkerId_DQT;
00420     write_buffer[2] = 0;
00421     write_buffer[3] = 67;
00422     write_buffer[4] = i;
00423     // fwrite(write_buffer, 5, 1, OutStream);
00424     ConverterBackEnd->receiveJPEGBytes(write_buffer, 5);
00425   
00426     if(!i) quant_coeff = QuantizationTable_Y;
00427     else   quant_coeff = QuantizationTable_UV;
00428     for(j = 0; j < 64; j++) 
00429       quantization_table_to_write[ZigZag_StoreMap[j]] = *quant_coeff++;
00430     // fwrite(quantization_table_to_write, 64, 1, OutStream);
00431     ConverterBackEnd->receiveJPEGBytes(quantization_table_to_write, 64);
00432   }
00433   
00434   // write SOF0...
00435   SOF0_Block.x_sz_hi = frame_descriptor->Width / 256;
00436   SOF0_Block.x_sz_lo = frame_descriptor->Width % 256;
00437   SOF0_Block.y_sz_hi = frame_descriptor->Height / 256;
00438   SOF0_Block.y_sz_lo = frame_descriptor->Height % 256;
00439   // fwrite(&SOF0_Block, sizeof(mxcpc_mxpeg::SOF0), 1, OutStream);
00440   ConverterBackEnd->receiveJPEGBytes((mxcpc::u8 *)&SOF0_Block, 
00441                                      sizeof(mxcpc_mxpeg::SOF0));
00442   
00443   // write huffman tables...
00444   for(i = 0; i < 4; i++) {   // got four of them
00445   
00446     write_buffer[0] = 0xff;
00447     write_buffer[1] = mxcpc_mxpeg::MarkerId_DHT;
00448     if(i == 0) {
00449       write_buffer[4] = 0x00;
00450       huffman_table_to_write      = DefaultHuffmanTable_Y_DC;
00451       huffman_table_to_write_size = DefaultHuffmanTable_Y_DC_Size;
00452     }
00453     else if(i == 1) {
00454       write_buffer[4] = 0x10;
00455       huffman_table_to_write      = DefaultHuffmanTable_Y_AC;
00456       huffman_table_to_write_size = DefaultHuffmanTable_Y_AC_Size;
00457     }
00458     else if(i == 2) {
00459       write_buffer[4] = 0x01;
00460       huffman_table_to_write      = DefaultHuffmanTable_UV_DC;
00461       huffman_table_to_write_size = DefaultHuffmanTable_UV_DC_Size;
00462     }
00463     else {
00464       write_buffer[4] = 0x11;
00465       huffman_table_to_write      = DefaultHuffmanTable_UV_AC;
00466       huffman_table_to_write_size = DefaultHuffmanTable_UV_AC_Size;
00467     }
00468     write_buffer[2] = (huffman_table_to_write_size + 3) / 256;
00469     write_buffer[3] = (huffman_table_to_write_size + 3) % 256;
00470   
00471     // fwrite(write_buffer, 5, 1, OutStream);
00472     ConverterBackEnd->receiveJPEGBytes(write_buffer, 5);
00473     // fwrite(huffman_table_to_write, huffman_table_to_write_size, 1, OutStream); 
00474     ConverterBackEnd->receiveJPEGBytes((mxcpc::u8 *)huffman_table_to_write, 
00475                                        huffman_table_to_write_size);
00476   }  
00477   
00478   // write SOS...
00479   // fwrite(&SOS_Block, sizeof(mxcpc_mxpeg::SOS), 1, OutStream); 
00480   ConverterBackEnd->receiveJPEGBytes((mxcpc::u8 *)&SOS_Block, 
00481                                      sizeof(mxcpc_mxpeg::SOS));
00482   
00483   // write out scan...
00484   last_y_dc = last_u_dc = last_v_dc = 0;
00485   sub_mcu_coeffs = CoeffBuffer;
00486   bitstream_pos  = 0;
00487   tiles_to_write = TileNumX * TileNumY;
00488   while(tiles_to_write) {
00489   
00490     // iterate over sub-MCUs of current tile...
00491     for(i = 0; i < 6; i++) {
00492          
00493       ippiEncodeHuffman8x8_Direct_JPEG_16s1u_C1(sub_mcu_coeffs,
00494                                                 bitstream_buffer,
00495                                                 &bitstream_pos,
00496                                                 last_dc_ptrs[i],
00497                                                 dc_huffman_encode_specs[i],
00498                                                 ac_huffman_encode_specs[i]);
00499                                                 
00500                                                 
00501       // Print out one sub-MCU for testing only ....
00502       if( FramesProcessed == 0 && i==0 && tiles_to_write == (TileNumX * TileNumY) ){
00503         
00504           fprintf(stderr,"_____________________________________\n");
00505           fprintf(stderr,"First Frame, first sub tile! \n");
00506           fprintf(stderr,"_____________________________________\n");
00507           
00508           for(int k=0;k<8;k++){
00509                   
00510             fprintf(stderr,"| %d\t%d\t%d\t%d\t%d\t%d\t%d\t%d | \n", 
00511                                                   sub_mcu_coeffs[k],
00512                                                   sub_mcu_coeffs[k+1],
00513                                                   sub_mcu_coeffs[k+2],
00514                                                   sub_mcu_coeffs[k+3],
00515                                                   sub_mcu_coeffs[k+4],
00516                                                   sub_mcu_coeffs[k+5],
00517                                                   sub_mcu_coeffs[k+6],
00518                                                   sub_mcu_coeffs[k+7]);
00519         }
00520         
00521       }
00522       
00523   
00524       if(bitstream_pos >= 8) {
00525         
00526         // fwrite(bitstream_buffer, bitstream_pos/8, 1, OutStream); 
00527         ConverterBackEnd->receiveJPEGBytes(bitstream_buffer, bitstream_pos/8);
00528                                                                                               
00529         // copy down partially filled byte at the end...
00530         bitstream_buffer[0] = bitstream_buffer[bitstream_pos/8];
00531         bitstream_pos = bitstream_pos % 8;
00532       }
00533                                                  
00534       sub_mcu_coeffs += 64;
00535     }
00536     
00537     tiles_to_write--;
00538   }
00539   
00540   // deal with last byte
00541   // fwrite(bitstream_buffer, 1, 1, OutStream);   // maybe pad unused bits?
00542   ConverterBackEnd->receiveJPEGBytes(bitstream_buffer, 1);
00543   
00544   // write EOI...
00545   write_buffer[0] = 0xff;
00546   write_buffer[1] = mxcpc_mxpeg::MarkerId_EOI;
00547   // fwrite(write_buffer, 2, 1, OutStream);
00548   ConverterBackEnd->receiveJPEGBytes(write_buffer, 2);
00549    
00550   // fclose(OutStream);
00551   // OutStream = stdout;
00552   
00553   ConverterBackEnd->endFrame();
00554   // TODO : forward error from converter backend to decoder backend
00555   
00556   FramesProcessed++;
00557 }

Generated on Mon Aug 15 03:39:29 2005 for mxcpc by  doxygen 1.4.2-20050421