00001 /*!@file Transport/RasterOutputSeries.C */ 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: Rob Peters <rjpeters at usc dot edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Transport/RasterOutputSeries.C $ 00035 // $Id: RasterOutputSeries.C 10353 2008-10-15 23:05:53Z ilab24 $ 00036 // 00037 00038 #ifndef TRANSPORT_RASTEROUTPUTSERIES_C_DEFINED 00039 #define TRANSPORT_RASTEROUTPUTSERIES_C_DEFINED 00040 00041 #include "Transport/RasterOutputSeries.H" 00042 00043 #include "Component/GlobalOpts.H" 00044 #include "Component/OptionManager.H" 00045 #include "Raster/GenericFrame.H" 00046 #include "Raster/Raster.H" 00047 #include "Transport/TransportOpts.H" 00048 #include "Util/FileUtil.H" 00049 #include "Util/TextLog.H" 00050 #include "Util/sformat.H" 00051 00052 // ###################################################################### 00053 RasterOutputSeries::RasterOutputSeries(OptionManager& mgr) 00054 : 00055 FrameOstream(mgr, "Raster Output Series", "RasterOutputSeries"), 00056 itsLogFile(&OPT_TextLogFile, this), 00057 itsPrefix(""), 00058 itsFrameNumber(-1), 00059 itsNumericFieldWidth(6) 00060 {} 00061 00062 // ###################################################################### 00063 RasterOutputSeries::~RasterOutputSeries() 00064 {} 00065 00066 // ###################################################################### 00067 void RasterOutputSeries::setConfigInfo(const std::string& filestem) 00068 { 00069 // NOTE: if you modify any behavior here, then please update the 00070 // corresponding documentation for the global "--out" option inside 00071 // the OPT_OutputFrameSink definition in Media/MediaOpts.C 00072 00073 this->setFileStem(filestem); 00074 } 00075 00076 // ###################################################################### 00077 bool RasterOutputSeries::setFrameNumber(int n) 00078 { 00079 ASSERT(n >= 0); 00080 itsFrameNumber = n; 00081 00082 return true; 00083 } 00084 00085 // ###################################################################### 00086 void RasterOutputSeries::writeFrame(const GenericFrame& frame, 00087 const std::string& shortname, 00088 const FrameInfo& auxinfo) 00089 { 00090 // figure out the file name to use: 00091 std::string fname(computeOutputFileName(shortname)); 00092 00093 // find out file format: 00094 const RasterFileFormat ff = getRasterFileFormat(); 00095 00096 // write the image: 00097 fname = Raster::WriteFrame(frame, fname, ff); 00098 00099 const std::string& logfl = itsLogFile.getVal(); 00100 00101 switch (frame.nativeType()) 00102 { 00103 case GenericFrame::NONE: textLog(logfl, "WriteNil", fname); break; 00104 case GenericFrame::RGB_U8: textLog(logfl, "WriteRGB", fname); break; 00105 case GenericFrame::RGB_F32: textLog(logfl, "WriteRgbF32", fname); break; 00106 case GenericFrame::GRAY_U8: textLog(logfl, "WriteGray", fname); break; 00107 case GenericFrame::GRAY_F32: textLog(logfl, "WriteFloat", fname); break; 00108 case GenericFrame::VIDEO: textLog(logfl, "WriteVideo", fname); break; 00109 case GenericFrame::RGB_U16: textLog(logfl, "WriteRGBU16", fname); break; 00110 case GenericFrame::GRAY_U16: textLog(logfl, "WriteGrayU16", fname); break; 00111 default: break; 00112 } 00113 } 00114 00115 // ###################################################################### 00116 void RasterOutputSeries::closeStream(const std::string& shortname) 00117 { 00118 /* nothing to see here, move along */ 00119 } 00120 00121 // ###################################################################### 00122 void RasterOutputSeries::setFileStem(const std::string& s) 00123 { 00124 // NOTE: if you modify any behavior here, then please update the 00125 // corresponding documentation for the global "--out" option inside 00126 // the OPT_OutputFrameSink definition in Media/MediaOpts.C 00127 00128 itsPrefix = s; 00129 00130 // look for a single hash or a pair of hashes; if present, these 00131 // will specify the numeric field width to use when formatting the 00132 // frame numbers into the final filenames 00133 const std::string::size_type hashpos1 = s.find_first_of('#'); 00134 00135 // ok, got at least one hash: 00136 if (hashpos1 != s.npos) 00137 { 00138 // check for a second hash: 00139 const std::string::size_type hashpos2 = 00140 (hashpos1 + 1 < s.size()) 00141 ? s.find_first_of('#', hashpos1 + 1) 00142 : s.npos; 00143 00144 if (hashpos2 == hashpos1 + 1) 00145 { 00146 // ok, we got "##" which is equivalent to "#0#" 00147 itsPrefix.replace(hashpos1, 2, ""); 00148 itsNumericFieldWidth = 0; 00149 } 00150 else if (hashpos2 != s.npos) 00151 { 00152 // ok, we got "#nnn#" where we expect nnn to be an integer 00153 ASSERT(hashpos2 > hashpos1); 00154 00155 const std::string::size_type flen = hashpos2-hashpos1-1; 00156 00157 const std::string format = s.substr(hashpos1+1, flen); 00158 int width = -1; 00159 if (sscanf(format.c_str(), "%d", &width) != 1 00160 || width < 0 00161 || width >= 256) 00162 LFATAL("invalid number format '#%s#' in file stem %s; " 00163 "expected '#nnn#' where nnn is a non-negative integer " 00164 "less than 256", 00165 format.c_str(), s.c_str()); 00166 itsPrefix.replace(hashpos1, flen+2, ""); 00167 itsNumericFieldWidth = width; 00168 } 00169 else 00170 { 00171 // ok, we got "#" which by tradition is treated as "#6#" 00172 itsPrefix.replace(hashpos1, 1, ""); 00173 itsNumericFieldWidth = 6; 00174 } 00175 } 00176 } 00177 00178 // ###################################################################### 00179 std::string RasterOutputSeries:: 00180 computeOutputFileName(const std::string& key) const 00181 { 00182 // NOTE: if you modify any behavior here, then please update the 00183 // corresponding documentation for the global "--out" option inside 00184 // the OPT_OutputFrameSink definition in Media/MediaOpts.C 00185 00186 if (key.length() == 0) 00187 LFATAL("output filename key must be non-empty"); 00188 00189 // first split itsPrefix into path and file components: 00190 std::string pfxdir, pfxtail; 00191 splitPath(itsPrefix, pfxdir, pfxtail); 00192 00193 // also split the given key into path and file components: 00194 std::string keydir, keytail; 00195 splitPath(key, keydir, keytail); 00196 00197 ASSERT(itsFrameNumber >= 0); 00198 00199 ASSERT(itsNumericFieldWidth >= 0); 00200 ASSERT(itsNumericFieldWidth < 256); 00201 00202 // if the 'pfxtail' part of our prefix is non-empty, then put a 00203 // hyphen after it before the key and the frame number: 00204 if (pfxtail.length() > 0) 00205 return sformat("%s%s%s-%s%0*d", 00206 pfxdir.c_str(), keydir.c_str(), 00207 pfxtail.c_str(), keytail.c_str(), 00208 itsNumericFieldWidth, itsFrameNumber); 00209 else 00210 return sformat("%s%s%s%0*d", 00211 pfxdir.c_str(), keydir.c_str(), 00212 keytail.c_str(), 00213 itsNumericFieldWidth, itsFrameNumber); 00214 } 00215 00216 // ###################################################################### 00217 GenericRasterOutputSeries::GenericRasterOutputSeries(OptionManager& mgr) 00218 : 00219 RasterOutputSeries(mgr), 00220 itsRasterFileFormat(&OPT_OutputRasterFileFormat, this) 00221 {} 00222 00223 // ###################################################################### 00224 GenericRasterOutputSeries::~GenericRasterOutputSeries() {} 00225 00226 // ###################################################################### 00227 RasterFileFormat GenericRasterOutputSeries::getRasterFileFormat() const 00228 { 00229 return itsRasterFileFormat.getVal(); 00230 } 00231 00232 // ###################################################################### 00233 template <RasterFileFormat F> 00234 FixedRasterOutputSeries<F>::FixedRasterOutputSeries(OptionManager& mgr) 00235 : 00236 RasterOutputSeries(mgr) 00237 {} 00238 00239 // ###################################################################### 00240 template <RasterFileFormat F> 00241 FixedRasterOutputSeries<F>::~FixedRasterOutputSeries() {} 00242 00243 // ###################################################################### 00244 template <RasterFileFormat F> 00245 RasterFileFormat FixedRasterOutputSeries<F>::getRasterFileFormat() const 00246 { 00247 return F; 00248 } 00249 00250 template class FixedRasterOutputSeries<RASFMT_PNM>; 00251 template class FixedRasterOutputSeries<RASFMT_PNG>; 00252 template class FixedRasterOutputSeries<RASFMT_PFM>; 00253 template class FixedRasterOutputSeries<RASFMT_RAW_VIDEO>; 00254 template class FixedRasterOutputSeries<RASFMT_RAW_IMAGE>; 00255 template class FixedRasterOutputSeries<RASFMT_TXT>; 00256 template class FixedRasterOutputSeries<RASFMT_CCODE>; 00257 00258 // ###################################################################### 00259 /* So things look consistent in everyone's emacs... */ 00260 /* Local Variables: */ 00261 /* indent-tabs-mode: nil */ 00262 /* End: */ 00263 00264 #endif // TRANSPORT_RASTEROUTPUTSERIES_C_DEFINED