MgzJDecoder.C

Go to the documentation of this file.
00001 /*!@file Media/MgzJDecoder.C Low-level class to decode mgzj files */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Randolph Voorhies <voories at usc dot edu>
00034 
00035 #include "Media/MgzJDecoder.H"
00036 #include <sys/errno.h>
00037 
00038 // ######################################################################
00039 MgzJDecoder::MgzJDecoder(const std::string& fname)
00040   :
00041   itsFileName(fname)
00042 {
00043   init();
00044 }
00045 
00046 // ######################################################################
00047 MgzJDecoder::~MgzJDecoder()
00048 {
00049   shutdown();
00050 }
00051 
00052 
00053 // ######################################################################
00054 void MgzJDecoder::init()
00055 {
00056   LDEBUG("Opening File: %s", itsFileName.c_str());
00057 
00058   //Open the file in binary input mode, and position the get pointer
00059   //at the end of the file
00060   itsFile.open(itsFileName.c_str(), std::ios::in|std::ios::binary|std::ios::ate);
00061 
00062   if(!itsFile.is_open())
00063     LFATAL("Could not open file: %s", itsFileName.c_str());
00064 
00065   //Get the size of the file
00066   std::ifstream::pos_type fsize = itsFile.tellg();
00067 
00068   //Find the position of the journal start
00069   uint64 journal_start;
00070   itsFile.seekg(-8, std::ios::end);
00071   itsFile.read((char*)&journal_start, 8);
00072 
00073   //Read in the 16 bytes of meta-meta information
00074   byte meta_meta_buffer[16];
00075   itsFile.seekg(journal_start, std::ios::beg);
00076   itsFile.read((char*)meta_meta_buffer, 16);
00077 
00078   //Get the number of journal entries
00079   uint64 num_entries;
00080   memcpy((char*)&num_entries, meta_meta_buffer, 8);
00081 
00082   //Get the flags (for now just assert that they are 0. Anything else
00083   //should be an error)
00084   uint64 flags;
00085   memcpy((char*)&flags, meta_meta_buffer+8, 8);
00086   ASSERT(flags == 0);
00087 
00088   //Calculate the file offset where the actual journal entries begin
00089   uint64 journal_data_start = journal_start + 16;
00090 
00091   //Allocate a buffer to store the whole journal, and read it in
00092   uint64 journal_buf_size = (uint64)fsize - journal_data_start - 8;
00093   byte journal[journal_buf_size];
00094   itsFile.seekg(journal_data_start, std::ios::beg);
00095   itsFile.read((char*)journal, journal_buf_size);
00096 
00097   //Calculate the size of each entry
00098   uint64 entry_size = journal_buf_size / num_entries;
00099 
00100   //Loop through the buffer to deserialize the journal entries
00101   itsJournal.clear();
00102   for(uint64 buf_pos=0; buf_pos < journal_buf_size; buf_pos += entry_size)
00103   {
00104     MgzJEncoder::journalEntry entry;
00105     memcpy((char*)&entry, journal+buf_pos, sizeof(MgzJEncoder::journalEntry));
00106     itsJournal.push_back(entry);
00107   }
00108 
00109 }
00110 
00111 void MgzJDecoder::shutdown()
00112 {
00113   if(itsFile.is_open())
00114     itsFile.close();
00115 }
00116 
00117 // ######################################################################
00118 GenericFrame MgzJDecoder::readFrame()
00119 {
00120 
00121   //Grab the journal entry for this frame and allocate an appropriate
00122   //GenericFrame
00123   MgzJEncoder::journalEntry entry = itsJournal.at(itsFrameNum);
00124   const Dims dims(entry.width, entry.height);
00125   const GenericFrame::NativeType pix_type = GenericFrame::NativeType(entry.pix_type);
00126   const int num_pix = dims.sz();
00127   GenericFrame frame;
00128 
00129   //Read in the compressed image to a buffer
00130   uint64 comp_image_buf_size = entry.end_byte - entry.start_byte;
00131   byte comp_image_buf[comp_image_buf_size];
00132   itsFile.seekg(entry.start_byte, std::ios::beg);
00133   itsFile.read((char*)comp_image_buf, comp_image_buf_size);
00134 
00135   //Prepare zlib to do the decompression
00136   z_stream strm;
00137   strm.zalloc   = Z_NULL;
00138   strm.zfree    = Z_NULL;
00139   strm.opaque   = Z_NULL;
00140   strm.avail_in = 0;
00141   strm.next_in  = Z_NULL;
00142   int ret = inflateInit(&strm);
00143   if(ret != Z_OK) 
00144    LFATAL("Could not initialize zlib!"); 
00145 
00146   strm.avail_in = comp_image_buf_size;
00147   strm.next_in  = comp_image_buf;
00148   switch(pix_type)
00149   {
00150     case GenericFrame::GRAY_U8:
00151       {
00152         Image<byte> img(dims, NO_INIT);
00153         strm.avail_out = num_pix * sizeof(byte);
00154         strm.next_out  = (unsigned char*)img.getArrayPtr();
00155         ret = inflate(&strm, Z_FINISH);
00156         if(ret != Z_STREAM_END)
00157         { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); }
00158         frame = GenericFrame(img);
00159 
00160         break;
00161       }
00162     case GenericFrame::GRAY_U16:
00163       {
00164         Image<uint16> img(dims, NO_INIT);
00165         strm.avail_out = num_pix * sizeof(uint16);
00166         strm.next_out  = (unsigned char*)img.getArrayPtr();
00167         ret = inflate(&strm, Z_FINISH);
00168         if(ret != Z_STREAM_END)
00169         { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); }
00170         frame = GenericFrame(img);
00171 
00172         break;
00173       }
00174     case GenericFrame::GRAY_F32:
00175       {
00176         Image<float> img(dims, NO_INIT);
00177         strm.avail_out = num_pix * sizeof(float);
00178         strm.next_out  = (unsigned char*)img.getArrayPtr();
00179         ret = inflate(&strm, Z_FINISH);
00180         if(ret != Z_STREAM_END)
00181         { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); }
00182         frame = GenericFrame(img, entry.flags);
00183 
00184         break;
00185       }
00186     case GenericFrame::RGB_U8:
00187       {
00188         Image<PixRGB<byte> > img(dims, NO_INIT);
00189         strm.avail_out = num_pix * sizeof(PixRGB<byte>);
00190         strm.next_out  = (unsigned char*)img.getArrayPtr();
00191         ret = inflate(&strm, Z_FINISH);
00192         if(ret != Z_STREAM_END)
00193         { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); }
00194         frame = GenericFrame(img);
00195 
00196         break;
00197       }
00198     case GenericFrame::RGB_U16:
00199       {
00200         Image<PixRGB<uint16> > img(dims, NO_INIT);
00201         strm.avail_out = num_pix * sizeof(PixRGB<uint16>);
00202         strm.next_out  = (unsigned char*)img.getArrayPtr();
00203         ret = inflate(&strm, Z_FINISH);
00204         if(ret != Z_STREAM_END)
00205         { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); }
00206         frame = GenericFrame(img);
00207 
00208         break;
00209       }
00210     case GenericFrame::RGB_F32:
00211       {
00212         Image<PixRGB<float> > img(dims, NO_INIT);
00213         strm.avail_out = num_pix * sizeof(PixRGB<float>);
00214         strm.next_out  = (unsigned char*)img.getArrayPtr();
00215         ret = inflate(&strm, Z_FINISH);
00216         if(ret != Z_STREAM_END)
00217         { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); }
00218         frame = GenericFrame(img, entry.flags);
00219 
00220         break;
00221       }
00222       case GenericFrame::VIDEO:
00223       {
00224         const size_t vidSize = getFrameSize(VideoFormat(entry.flags), dims);
00225         ArrayHandle<byte> vidBuffer(new ArrayData<byte>(Dims(vidSize,1), NO_INIT));
00226         strm.avail_out = vidSize;
00227         strm.next_out = (unsigned char*)vidBuffer.uniq().dataw();
00228         ret = inflate(&strm, Z_FINISH);
00229         if(ret != Z_STREAM_END)
00230         { LFATAL("Could Not Inflate Frame! %d, %s", ret, strm.msg); }
00231         frame = GenericFrame(VideoFrame(vidBuffer, dims, VideoFormat(entry.flags), bool(entry.byte_swap)));
00232         break;
00233       }
00234     default:
00235       LFATAL("Could Not Open Frame Of Type: %d!", pix_type);
00236   }
00237   
00238   inflateEnd(&strm);
00239   return frame;
00240 }
00241 
00242 // ######################################################################
00243 int MgzJDecoder::getNumFrames()
00244 {
00245   return itsJournal.size();
00246 }
00247 
00248 // ######################################################################
00249 bool MgzJDecoder::setFrameNumber(unsigned int n)
00250 {
00251   if(n < itsJournal.size())
00252   {
00253     itsFrameNum = n;
00254     return true;
00255   }
00256   LINFO("Could not set frame number to %d (only %lu frames available)", n, (unsigned long)itsJournal.size());
00257   return false;
00258 }
00259 
00260 
00261 
Generated on Sun May 8 08:05:20 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3