pic_io.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:12k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. *
  3. * $Id: pic_io.cpp,v 1.2 2005/01/30 05:11:40 gabest Exp $ $Name:  $
  4. *
  5. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  6. *
  7. * The contents of this file are subject to the Mozilla Public License
  8. * Version 1.1 (the "License"); you may not use this file except in compliance
  9. * with the License. You may obtain a copy of the License at
  10. * http://www.mozilla.org/MPL/
  11. *
  12. * Software distributed under the License is distributed on an "AS IS" basis,
  13. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  14. * the specific language governing rights and limitations under the License.
  15. *
  16. * The Original Code is BBC Research and Development code.
  17. *
  18. * The Initial Developer of the Original Code is the British Broadcasting
  19. * Corporation.
  20. * Portions created by the Initial Developer are Copyright (C) 2004.
  21. * All Rights Reserved.
  22. *
  23. * Contributor(s): Thomas Davies (Original Author),
  24. *                 Scott Robert Ladd,
  25. *                 Stuart Cunningham,
  26. *                 Tim Borer
  27. *
  28. * Alternatively, the contents of this file may be used under the terms of
  29. * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
  30. * Public License Version 2.1 (the "LGPL"), in which case the provisions of
  31. * the GPL or the LGPL are applicable instead of those above. If you wish to
  32. * allow use of your version of this file only under the terms of the either
  33. * the GPL or LGPL and not to allow others to use your version of this file
  34. * under the MPL, indicate your decision by deleting the provisions above
  35. * and replace them with the notice and other provisions required by the GPL
  36. * or LGPL. If you do not delete the provisions above, a recipient may use
  37. * your version of this file under the terms of any one of the MPL, the GPL
  38. * or the LGPL.
  39. * ***** END LICENSE BLOCK ***** */
  40. #include <libdirac_common/pic_io.h>
  41. #include <libdirac_common/dirac_assertions.h>
  42. using namespace dirac;
  43. /*************************************Output***********************************/
  44. StreamPicOutput::StreamPicOutput()
  45. {}
  46. StreamPicOutput::~StreamPicOutput()
  47. {}
  48. StreamPicOutput::StreamPicOutput (const SeqParams& sp) :
  49.     m_sparams(sp),
  50.     m_op_pic_ptr(0)
  51. { }
  52. bool StreamPicOutput::WriteNextFrame( const Frame& myframe )
  53. {
  54.     bool ret_val;
  55.     ret_val=WriteComponent(myframe.Ydata() , Y_COMP );
  56.     if ( m_sparams.CFormat() != Yonly )
  57.     {
  58.         ret_val|=WriteComponent( myframe.Udata() , U_COMP );
  59.         ret_val|=WriteComponent( myframe.Vdata() , V_COMP );
  60.     }
  61.     return ret_val;
  62. }
  63. bool StreamPicOutput::WriteComponent( const PicArray& pic_data , const CompSort& cs)
  64. {
  65.     //initially set up for 10-bit data input, rounded to 8 bits on file output
  66.     //This will throw out any padding to the right and bottom of a frame
  67.     int xl,yl;
  68.     if (cs == Y_COMP)
  69.     {
  70.         xl = m_sparams.Xl();
  71.         yl = m_sparams.Yl();
  72.     }
  73.     else
  74.     {
  75.         xl = m_sparams.ChromaWidth();
  76.         yl = m_sparams.ChromaHeight();
  77.     }
  78.     unsigned char* tempc=new unsigned char[xl];
  79.     ValueType tempv;
  80.     if (m_op_pic_ptr)
  81.     {
  82.         for (int j=0 ; j<yl ;++j)
  83.         {
  84.             for (int i=0 ; i<xl ; ++i)
  85.             {                
  86.                 tempv = pic_data[j][i]+2;
  87.                 tempv >>= 2;
  88.                 tempc[i] = (unsigned char) tempv;                
  89.             }//I
  90.             m_op_pic_ptr->write((char*) tempc,xl);
  91.         }//J
  92.     }
  93.     else
  94.     {
  95.         std::cerr<<std::endl<<"Can't open picture data file for writing";
  96.         //tidy up        
  97.         delete[] tempc;
  98.         //exit failure
  99.         return false;
  100.     }
  101.     m_op_pic_ptr->flush();
  102.     delete[] tempc;
  103.     //exit success
  104.     return true;
  105. }
  106. MemoryStreamOutput::MemoryStreamOutput()
  107. {
  108.     //picture input
  109.     m_op_pic_ptr =
  110.         new std::ostream(&m_membuf);
  111. }
  112. MemoryStreamOutput::~MemoryStreamOutput()
  113. {
  114.     delete m_op_pic_ptr;
  115. }
  116. void MemoryStreamOutput::SetMembufReference (unsigned char *buf, int buf_size)
  117. {
  118.     m_membuf.SetMembufReference(buf, buf_size);
  119. }
  120. FileStreamOutput::FileStreamOutput(const char* output_name,
  121.                      const SeqParams& sp,
  122.                      bool write_header_only) : StreamPicOutput(sp)
  123. {
  124.     m_op_head_ptr = NULL;
  125.     OpenHeader(output_name);
  126.     if (! write_header_only)
  127.         OpenYUV(output_name);
  128. }
  129. bool FileStreamOutput::OpenHeader(const char* output_name)
  130. {
  131.     char output_name_hdr[FILENAME_MAX];
  132.     strncpy(output_name_hdr, output_name, sizeof(output_name_hdr));
  133.     strcat(output_name_hdr, ".hdr");
  134.     //header output
  135.     m_op_head_ptr =
  136.         new std::ofstream(output_name_hdr,std::ios::out | std::ios::binary);
  137.     if (!(*m_op_head_ptr))
  138.     {
  139.         std::cerr <<std::endl <<
  140.             "Can't open output header file for output: " << 
  141.              output_name_hdr << std::endl;
  142.         return false;    
  143.     }
  144.     return true;
  145. }
  146. bool FileStreamOutput::OpenYUV(const char* output_name)
  147. {
  148.     char output_name_yuv[FILENAME_MAX];
  149.     strncpy(output_name_yuv,output_name, sizeof(output_name_yuv));
  150.     strcat(output_name_yuv,".yuv");
  151.     //picture output
  152.     m_op_pic_ptr =
  153.         new std::ofstream(output_name_yuv,std::ios::out | std::ios::binary);
  154.     if (!(*m_op_pic_ptr))
  155.     {
  156.         std::cerr << std::endl << 
  157.             "Can't open output picture data file for output: " << 
  158.             output_name_yuv<<std::endl;
  159.         return false;    
  160.     }
  161.     return true;
  162. }
  163. FileStreamOutput::~FileStreamOutput()
  164. {
  165.     if (m_op_head_ptr && *m_op_head_ptr)
  166.     {
  167.         m_op_head_ptr->close();
  168.         delete m_op_head_ptr;
  169.     }
  170.     if (m_op_pic_ptr && *m_op_pic_ptr)
  171.     {
  172.         static_cast<std::ofstream *>(m_op_pic_ptr)->close();
  173.         delete m_op_pic_ptr;
  174.     }
  175. }
  176. //write a human-readable picture header as separate file
  177. bool FileStreamOutput::WritePicHeader()
  178. {
  179.     if (!m_op_head_ptr || !*m_op_head_ptr)
  180.         return false;
  181.     *m_op_head_ptr << m_sparams.CFormat() << std::endl;
  182.     *m_op_head_ptr << m_sparams.Xl() << std::endl;
  183.     *m_op_head_ptr << m_sparams.Yl() << std::endl;
  184.     *m_op_head_ptr << m_sparams.Interlace() << std::endl;
  185.     *m_op_head_ptr << m_sparams.TopFieldFirst() << std::endl;
  186.     *m_op_head_ptr << m_sparams.FrameRate() << std::endl;
  187.     return true;
  188. }
  189. /**************************************Input***********************************/
  190. StreamPicInput::StreamPicInput () :
  191.     m_ip_pic_ptr(0),
  192.     m_xpad(0),
  193.     m_ypad(0)
  194. {}
  195. StreamPicInput::StreamPicInput (std::istream *ip_pic_ptr, const SeqParams &sparams) :
  196.     m_sparams(m_sparams),
  197.     m_ip_pic_ptr(ip_pic_ptr),
  198.     m_xpad(0),
  199.     m_ypad(0)
  200. {}
  201. StreamPicInput::~StreamPicInput ()
  202. {}
  203. void StreamPicInput::SetPadding(const int xpd, const int ypd)
  204. {
  205.     m_xpad=xpd;
  206.     m_ypad=ypd;
  207. }
  208. bool StreamPicInput::ReadNextFrame(Frame& myframe)
  209. {
  210.     //return value. Failure if one of the components can't be read,
  211.     //success otherwise/.
  212.     bool ret_val;
  213.     ret_val=ReadComponent( myframe.Ydata() , Y_COMP);
  214.     if (m_sparams.CFormat() != Yonly)
  215.     {
  216.         ret_val|=ReadComponent(myframe.Udata() , U_COMP);
  217.         ret_val|=ReadComponent(myframe.Vdata() , V_COMP);
  218.     }
  219.     return ret_val;
  220. }
  221. bool StreamPicInput::ReadComponent(PicArray& pic_data, const CompSort& cs)
  222. {
  223.     if (! *m_ip_pic_ptr)
  224.         return false;
  225.     //initially set up for 8-bit file input expanded to 10 bits for array output
  226.     int xl,yl;
  227.     if (cs == Y_COMP){
  228.         xl = m_sparams.Xl();
  229.         yl = m_sparams.Yl();
  230.     }
  231.     else{
  232.         if (m_sparams.CFormat() == format411)
  233.         {
  234.             xl = m_sparams.Xl()/4;
  235.             yl = m_sparams.Yl();
  236.         }
  237.         else if (m_sparams.CFormat()==format420)
  238.         {
  239.             xl = m_sparams.Xl()/2;
  240.             yl = m_sparams.Yl()/2;
  241.         }
  242.         else if (m_sparams.CFormat() == format422)
  243.         {
  244.             xl = m_sparams.Xl()/2;
  245.             yl = m_sparams.Yl();
  246.         }
  247.         else{
  248.             xl = m_sparams.Xl();
  249.             yl = m_sparams.Yl();
  250.         }
  251.     }
  252.     unsigned char * temp = new unsigned char[xl];//array big enough for one line
  253.     for (int j=0 ; j<yl ; ++j)
  254.     {        
  255.         m_ip_pic_ptr->read((char*) temp, xl);        
  256.         for (int i=0 ; i<xl ; ++i)
  257.         {            
  258.             pic_data[j][i] = (ValueType) temp[i];
  259.             pic_data[j][i] <<= 2;
  260.         }//I
  261.         //pad the columns on the rhs using the edge value        
  262.         for (int i=xl ; i<pic_data.LengthX() ; ++i ){
  263.             pic_data[j][i] = pic_data[j][xl-1];
  264.         }//I
  265.     }//J
  266.     delete [] temp;
  267.     //now do the padded lines, using the last true line
  268.     for (int j=yl ; j<pic_data.LengthY() ; ++j )
  269.     {
  270.         for (int i=0 ; i<pic_data.LengthX() ; ++i )
  271.         {
  272.             pic_data[j][i] = pic_data[yl-1][i];
  273.         }//I
  274.     }//J
  275.     return true;
  276. }
  277. MemoryStreamInput::MemoryStreamInput()
  278. {
  279.     //picture input
  280.     m_ip_pic_ptr =
  281.         new std::istream(&m_membuf);
  282. }
  283. MemoryStreamInput::~MemoryStreamInput()
  284. {
  285.     delete m_ip_pic_ptr;
  286. }
  287. void MemoryStreamInput::SetMembufReference (unsigned char *buf, int buf_size)
  288. {
  289.     m_membuf.SetMembufReference(buf, buf_size);
  290. }
  291. void MemoryStreamInput::Skip(const int num)
  292. {
  293.     REPORTM (false, "MemoryStreamInput::Skip - Reached unimplemented function");
  294. }
  295. FileStreamInput::FileStreamInput(const char* input_name)
  296. {
  297.     char input_name_yuv[FILENAME_MAX];
  298.     char input_name_hdr[FILENAME_MAX];
  299.     strncpy(input_name_yuv, input_name, sizeof(input_name_yuv));
  300.     strncpy(input_name_hdr, input_name, sizeof(input_name_hdr));
  301.     strcat(input_name_yuv, ".yuv");
  302.     strcat(input_name_hdr, ".hdr");
  303.     //header output
  304.     m_ip_head_ptr =
  305.         new std::ifstream(input_name_hdr,std::ios::in | std::ios::binary);
  306.     //picture output
  307.     m_ip_pic_ptr =
  308.         new std::ifstream(input_name_yuv,std::ios::in | std::ios::binary);
  309.     if (!(*m_ip_head_ptr))
  310.         std::cerr << std::endl <<
  311.             "Can't open input header file: " << input_name_hdr << std::endl;
  312.     if (!(*m_ip_pic_ptr))
  313.         std::cerr << std::endl<<
  314.             "Can't open input picture data file: " <<
  315.             input_name_yuv << std::endl;
  316. }
  317. FileStreamInput::~FileStreamInput()
  318. {
  319.     static_cast<std::ifstream *>(m_ip_pic_ptr)->close();
  320.     m_ip_head_ptr->close();
  321.     delete m_ip_pic_ptr;
  322.     delete m_ip_head_ptr;
  323. }
  324. //read a picture header from a separate file
  325. bool FileStreamInput::ReadPicHeader()
  326. {
  327.     if (! *m_ip_head_ptr)
  328.         return false;
  329.     int temp_int;
  330.     bool temp_bool;
  331.     *m_ip_head_ptr >> temp_int;
  332.     m_sparams.SetCFormat( (ChromaFormat)temp_int );
  333.     *m_ip_head_ptr >> temp_int;
  334.     m_sparams.SetXl( temp_int );
  335.  
  336.    *m_ip_head_ptr >> temp_int;
  337.     m_sparams.SetYl( temp_int );
  338.     *m_ip_head_ptr >> temp_bool;
  339.     m_sparams.SetInterlace( temp_bool );
  340.     *m_ip_head_ptr >> temp_bool;
  341.     m_sparams.SetTopFieldFirst( temp_bool );
  342.     *m_ip_head_ptr >> temp_int;    
  343.     m_sparams.SetFrameRate( temp_int );
  344.     return true;
  345. }
  346. void FileStreamInput::Skip(const int num)
  347. {
  348.     const int num_pels = m_sparams.Xl()*m_sparams.Yl();
  349.     int num_bytes;
  350.  
  351.     const ChromaFormat cf = m_sparams.CFormat();
  352.     if ( cf == Yonly)
  353.         num_bytes = num_pels;
  354.     else if ( cf == format411 || cf == format420 )
  355.        num_bytes = (num_pels*3)/2;
  356.     else if ( cf == format422 )
  357.        num_bytes = num_pels*2;
  358.     else
  359.        num_bytes = num_pels*3;
  360.     m_ip_pic_ptr->seekg( num*num_bytes , std::ios::cur );
  361. }
  362. bool StreamPicInput::End() const
  363. {
  364.     return m_ip_pic_ptr->eof();
  365. }