- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# pic_io.cpp

    00001 /* ***** BEGIN LICENSE BLOCK *****
    00002 *
    00003 * $Id: pic_io.cpp,v 1.2 2005/01/30 05:11:40 gabest Exp $ $Name:  $
    00004 *
    00005 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    00006 *
    00007 * The contents of this file are subject to the Mozilla Public License
    00008 * Version 1.1 (the "License"); you may not use this file except in compliance
    00009 * with the License. You may obtain a copy of the License at
    00010 * http://www.mozilla.org/MPL/
    00011 *
    00012 * Software distributed under the License is distributed on an "AS IS" basis,
    00013 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
    00014 * the specific language governing rights and limitations under the License.
    00015 *
    00016 * The Original Code is BBC Research and Development code.
    00017 *
    00018 * The Initial Developer of the Original Code is the British Broadcasting
    00019 * Corporation.
    00020 * Portions created by the Initial Developer are Copyright (C) 2004.
    00021 * All Rights Reserved.
    00022 *
    00023 * Contributor(s): Thomas Davies (Original Author),
    00024 *                 Scott Robert Ladd,
    00025 *                 Stuart Cunningham,
    00026 *                 Tim Borer
    00027 *
    00028 * Alternatively, the contents of this file may be used under the terms of
    00029 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
    00030 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
    00031 * the GPL or the LGPL are applicable instead of those above. If you wish to
    00032 * allow use of your version of this file only under the terms of the either
    00033 * the GPL or LGPL and not to allow others to use your version of this file
    00034 * under the MPL, indicate your decision by deleting the provisions above
    00035 * and replace them with the notice and other provisions required by the GPL
    00036 * or LGPL. If you do not delete the provisions above, a recipient may use
    00037 * your version of this file under the terms of any one of the MPL, the GPL
    00038 * or the LGPL.
    00039 * ***** END LICENSE BLOCK ***** */
    00040
    00041 #include <libdirac_common/pic_io.h>
    00042 #include <libdirac_common/dirac_assertions.h>
    00043 using namespace dirac;
    00044
    00045 /*************************************Output***********************************/
    00046
    00047 StreamPicOutput::StreamPicOutput()
    00048 {}
    00049
    00050 StreamPicOutput::~StreamPicOutput()
    00051 {}
    00052
    00053 StreamPicOutput::StreamPicOutput (const SeqParams& sp) :
    00054     m_sparams(sp),
    00055     m_op_pic_ptr(0)
    00056 { }
    00057
    00058
    00059 bool StreamPicOutput::WriteNextFrame( const Frame& myframe )
    00060 {
    00061     bool ret_val;
    00062
    00063     ret_val=WriteComponent(myframe.Ydata() , Y_COMP );
    00064
    00065     if ( m_sparams.CFormat() != Yonly )
    00066     {
    00067         ret_val|=WriteComponent( myframe.Udata() , U_COMP );
    00068         ret_val|=WriteComponent( myframe.Vdata() , V_COMP );
    00069     }
    00070
    00071     return ret_val;
    00072 }
    00073
    00074 bool StreamPicOutput::WriteComponent( const PicArray& pic_data , const CompSort& cs)
    00075 {
    00076     //initially set up for 10-bit data input, rounded to 8 bits on file output
    00077     //This will throw out any padding to the right and bottom of a frame
    00078
    00079     int xl,yl;
    00080     if (cs == Y_COMP)
    00081     {
    00082         xl = m_sparams.Xl();
    00083         yl = m_sparams.Yl();
    00084     }
    00085     else
    00086     {
    00087         xl = m_sparams.ChromaWidth();
    00088         yl = m_sparams.ChromaHeight();
    00089     }
    00090
    00091     unsigned char* tempc=new unsigned char[xl];
    00092     ValueType tempv;
    00093
    00094     if (m_op_pic_ptr)
    00095     {
    00096         for (int j=0 ; j<yl ;++j)
    00097         {
    00098             for (int i=0 ; i<xl ; ++i)
    00099             {
    00100                 tempv = pic_data[j][i]+2;
    00101                 tempv >>= 2;
    00102                 tempc[i] = (unsigned char) tempv;
    00103             }//I
    00104
    00105             m_op_pic_ptr->write((char*) tempc,xl);
    00106
    00107         }//J
    00108     }
    00109     else
    00110     {
    00111         std::cerr<<std::endl<<"Can't open picture data file for writing";
    00112
    00113         //tidy up
    00114         delete[] tempc;
    00115
    00116         //exit failure
    00117         return false;
    00118     }
    00119
    00120     m_op_pic_ptr->flush();
    00121
    00122     delete[] tempc;
    00123
    00124     //exit success
    00125     return true;
    00126 }
    00127
    00128 MemoryStreamOutput::MemoryStreamOutput()
    00129 {
    00130     //picture input
    00131     m_op_pic_ptr =
    00132         new std::ostream(&m_membuf);
    00133 }
    00134
    00135 MemoryStreamOutput::~MemoryStreamOutput()
    00136 {
    00137     delete m_op_pic_ptr;
    00138 }
    00139
    00140 void MemoryStreamOutput::SetMembufReference (unsigned char *buf, int buf_size)
    00141 {
    00142     m_membuf.SetMembufReference(buf, buf_size);
    00143 }
    00144
    00145
    00146 FileStreamOutput::FileStreamOutput(const char* output_name,
    00147                      const SeqParams& sp,
    00148                      bool write_header_only) : StreamPicOutput(sp)
    00149 {
    00150     m_op_head_ptr = NULL;
    00151
    00152     OpenHeader(output_name);
    00153     if (! write_header_only)
    00154         OpenYUV(output_name);
    00155 }
    00156
    00157 bool FileStreamOutput::OpenHeader(const char* output_name)
    00158 {
    00159     char output_name_hdr[FILENAME_MAX];
    00160
    00161     strncpy(output_name_hdr, output_name, sizeof(output_name_hdr));
    00162     strcat(output_name_hdr, ".hdr");
    00163
    00164     //header output
    00165     m_op_head_ptr =
    00166         new std::ofstream(output_name_hdr,std::ios::out | std::ios::binary);
    00167
    00168     if (!(*m_op_head_ptr))
    00169     {
    00170         std::cerr <<std::endl <<
    00171             "Can't open output header file for output: " <<
    00172              output_name_hdr << std::endl;
    00173
    00174         return false;
    00175
    00176     }
    00177
    00178     return true;
    00179 }
    00180
    00181 bool FileStreamOutput::OpenYUV(const char* output_name)
    00182 {
    00183     char output_name_yuv[FILENAME_MAX];
    00184
    00185     strncpy(output_name_yuv,output_name, sizeof(output_name_yuv));
    00186     strcat(output_name_yuv,".yuv");
    00187
    00188     //picture output
    00189     m_op_pic_ptr =
    00190         new std::ofstream(output_name_yuv,std::ios::out | std::ios::binary);
    00191
    00192     if (!(*m_op_pic_ptr))
    00193     {
    00194         std::cerr << std::endl <<
    00195             "Can't open output picture data file for output: " <<
    00196             output_name_yuv<<std::endl;
    00197
    00198         return false;
    00199
    00200     }
    00201
    00202     return true;
    00203 }
    00204
    00205 FileStreamOutput::~FileStreamOutput()
    00206 {
    00207     if (m_op_head_ptr && *m_op_head_ptr)
    00208     {
    00209         m_op_head_ptr->close();
    00210         delete m_op_head_ptr;
    00211     }
    00212
    00213     if (m_op_pic_ptr && *m_op_pic_ptr)
    00214     {
    00215         static_cast<std::ofstream *>(m_op_pic_ptr)->close();
    00216         delete m_op_pic_ptr;
    00217     }
    00218 }
    00219
    00220 //write a human-readable picture header as separate file
    00221 bool FileStreamOutput::WritePicHeader()
    00222 {
    00223     if (!m_op_head_ptr || !*m_op_head_ptr)
    00224         return false;
    00225
    00226     *m_op_head_ptr << m_sparams.CFormat() << std::endl;
    00227     *m_op_head_ptr << m_sparams.Xl() << std::endl;
    00228     *m_op_head_ptr << m_sparams.Yl() << std::endl;
    00229     *m_op_head_ptr << m_sparams.Interlace() << std::endl;
    00230     *m_op_head_ptr << m_sparams.TopFieldFirst() << std::endl;
    00231     *m_op_head_ptr << m_sparams.FrameRate() << std::endl;
    00232
    00233     return true;
    00234
    00235 }
    00236
    00237 /**************************************Input***********************************/
    00238
    00239 StreamPicInput::StreamPicInput () :
    00240     m_ip_pic_ptr(0),
    00241     m_xpad(0),
    00242     m_ypad(0)
    00243 {}
    00244
    00245 StreamPicInput::StreamPicInput (std::istream *ip_pic_ptr, const SeqParams &sparams) :
    00246     m_sparams(m_sparams),
    00247     m_ip_pic_ptr(ip_pic_ptr),
    00248     m_xpad(0),
    00249     m_ypad(0)
    00250 {}
    00251
    00252 StreamPicInput::~StreamPicInput ()
    00253 {}
    00254
    00255 void StreamPicInput::SetPadding(const int xpd, const int ypd)
    00256 {
    00257     m_xpad=xpd;
    00258     m_ypad=ypd;
    00259 }
    00260
    00261 bool StreamPicInput::ReadNextFrame(Frame& myframe)
    00262 {
    00263     //return value. Failure if one of the components can't be read,
    00264     //success otherwise/.
    00265
    00266     bool ret_val;
    00267     ret_val=ReadComponent( myframe.Ydata() , Y_COMP);
    00268
    00269     if (m_sparams.CFormat() != Yonly)
    00270     {
    00271         ret_val|=ReadComponent(myframe.Udata() , U_COMP);
    00272         ret_val|=ReadComponent(myframe.Vdata() , V_COMP);
    00273     }
    00274
    00275     return ret_val;
    00276 }
    00277
    00278
    00279 bool StreamPicInput::ReadComponent(PicArray& pic_data, const CompSort& cs)
    00280 {
    00281     if (! *m_ip_pic_ptr)
    00282         return false;
    00283
    00284     //initially set up for 8-bit file input expanded to 10 bits for array output
    00285
    00286     int xl,yl;
    00287     if (cs == Y_COMP){
    00288         xl = m_sparams.Xl();
    00289         yl = m_sparams.Yl();
    00290     }
    00291     else{
    00292         if (m_sparams.CFormat() == format411)
    00293         {
    00294             xl = m_sparams.Xl()/4;
    00295             yl = m_sparams.Yl();
    00296         }
    00297         else if (m_sparams.CFormat()==format420)
    00298         {
    00299             xl = m_sparams.Xl()/2;
    00300             yl = m_sparams.Yl()/2;
    00301         }
    00302         else if (m_sparams.CFormat() == format422)
    00303         {
    00304             xl = m_sparams.Xl()/2;
    00305             yl = m_sparams.Yl();
    00306         }
    00307         else{
    00308             xl = m_sparams.Xl();
    00309             yl = m_sparams.Yl();
    00310         }
    00311     }
    00312
    00313     unsigned char * temp = new unsigned char[xl];//array big enough for one line
    00314
    00315     for (int j=0 ; j<yl ; ++j)
    00316     {
    00317         m_ip_pic_ptr->read((char*) temp, xl);
    00318
    00319         for (int i=0 ; i<xl ; ++i)
    00320         {
    00321             pic_data[j][i] = (ValueType) temp[i];
    00322             pic_data[j][i] <<= 2;
    00323         }//I
    00324
    00325         //pad the columns on the rhs using the edge value
    00326         for (int i=xl ; i<pic_data.LengthX() ; ++i ){
    00327             pic_data[j][i] = pic_data[j][xl-1];
    00328         }//I
    00329
    00330     }//J
    00331
    00332     delete [] temp;
    00333
    00334     //now do the padded lines, using the last true line
    00335     for (int j=yl ; j<pic_data.LengthY() ; ++j )
    00336     {
    00337         for (int i=0 ; i<pic_data.LengthX() ; ++i )
    00338         {
    00339             pic_data[j][i] = pic_data[yl-1][i];
    00340         }//I
    00341     }//J
    00342
    00343     return true;
    00344 }
    00345
    00346 MemoryStreamInput::MemoryStreamInput()
    00347 {
    00348     //picture input
    00349     m_ip_pic_ptr =
    00350         new std::istream(&m_membuf);
    00351 }
    00352
    00353 MemoryStreamInput::~MemoryStreamInput()
    00354 {
    00355     delete m_ip_pic_ptr;
    00356 }
    00357
    00358 void MemoryStreamInput::SetMembufReference (unsigned char *buf, int buf_size)
    00359 {
    00360     m_membuf.SetMembufReference(buf, buf_size);
    00361 }
    00362
    00363 void MemoryStreamInput::Skip(const int num)
    00364 {
    00365     REPORTM (false, "MemoryStreamInput::Skip - Reached unimplemented function");
    00366 }
    00367
    00368 FileStreamInput::FileStreamInput(const char* input_name)
    00369 {
    00370
    00371     char input_name_yuv[FILENAME_MAX];
    00372     char input_name_hdr[FILENAME_MAX];
    00373
    00374     strncpy(input_name_yuv, input_name, sizeof(input_name_yuv));
    00375     strncpy(input_name_hdr, input_name, sizeof(input_name_hdr));
    00376     strcat(input_name_yuv, ".yuv");
    00377     strcat(input_name_hdr, ".hdr");
    00378
    00379     //header output
    00380     m_ip_head_ptr =
    00381         new std::ifstream(input_name_hdr,std::ios::in | std::ios::binary);
    00382     //picture output
    00383     m_ip_pic_ptr =
    00384         new std::ifstream(input_name_yuv,std::ios::in | std::ios::binary);
    00385
    00386     if (!(*m_ip_head_ptr))
    00387         std::cerr << std::endl <<
    00388             "Can't open input header file: " << input_name_hdr << std::endl;
    00389     if (!(*m_ip_pic_ptr))
    00390         std::cerr << std::endl<<
    00391             "Can't open input picture data file: " <<
    00392             input_name_yuv << std::endl;
    00393 }
    00394
    00395 FileStreamInput::~FileStreamInput()
    00396 {
    00397     static_cast<std::ifstream *>(m_ip_pic_ptr)->close();
    00398     m_ip_head_ptr->close();
    00399     delete m_ip_pic_ptr;
    00400     delete m_ip_head_ptr;
    00401 }
    00402
    00403 //read a picture header from a separate file
    00404 bool FileStreamInput::ReadPicHeader()
    00405 {
    00406     if (! *m_ip_head_ptr)
    00407         return false;
    00408
    00409     int temp_int;
    00410     bool temp_bool;
    00411
    00412     *m_ip_head_ptr >> temp_int;
    00413     m_sparams.SetCFormat( (ChromaFormat)temp_int );
    00414
    00415     *m_ip_head_ptr >> temp_int;
    00416     m_sparams.SetXl( temp_int );
    00417
    00418    *m_ip_head_ptr >> temp_int;
    00419     m_sparams.SetYl( temp_int );
    00420
    00421     *m_ip_head_ptr >> temp_bool;
    00422     m_sparams.SetInterlace( temp_bool );
    00423
    00424     *m_ip_head_ptr >> temp_bool;
    00425     m_sparams.SetTopFieldFirst( temp_bool );
    00426
    00427     *m_ip_head_ptr >> temp_int;
    00428     m_sparams.SetFrameRate( temp_int );
    00429
    00430     return true;
    00431 }
    00432
    00433 void FileStreamInput::Skip(const int num)
    00434 {
    00435     const int num_pels = m_sparams.Xl()*m_sparams.Yl();
    00436     int num_bytes;
    00437
    00438     const ChromaFormat cf = m_sparams.CFormat();
    00439
    00440     if ( cf == Yonly)
    00441         num_bytes = num_pels;
    00442     else if ( cf == format411 || cf == format420 )
    00443        num_bytes = (num_pels*3)/2;
    00444     else if ( cf == format422 )
    00445        num_bytes = num_pels*2;
    00446     else
    00447        num_bytes = num_pels*3;
    00448
    00449     m_ip_pic_ptr->seekg( num*num_bytes , std::ios::cur );
    00450 }
    00451
    00452 bool StreamPicInput::End() const
    00453 {
    00454     return m_ip_pic_ptr->eof();
    00455 }