00001 /*!@file Transport/HashOutputSeries.C write a series of image hashes to an output file */ 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/HashOutputSeries.C $ 00035 // $Id: HashOutputSeries.C 14290 2010-12-01 21:44:03Z itti $ 00036 // 00037 00038 #ifndef TRANSPORT_HASHOUTPUTSERIES_C_DEFINED 00039 #define TRANSPORT_HASHOUTPUTSERIES_C_DEFINED 00040 00041 #include "Transport/HashOutputSeries.H" 00042 00043 #include "Image/Image.H" 00044 #include "Image/Pixels.H" 00045 #include "Raster/GenericFrame.H" 00046 #include "Util/FileUtil.H" 00047 #include "Util/jenkinshash.H" 00048 00049 #include <cstdio> 00050 #include <set> 00051 00052 struct HashOutputSeries::Impl 00053 { 00054 Impl() 00055 : 00056 fileName(""), 00057 fileOwned(true), 00058 frameNumber(-1), 00059 file(0) 00060 {} 00061 00062 ~Impl() 00063 { 00064 if (this->file != 0) 00065 { 00066 fflush(this->file); 00067 00068 // we might not want to fclose() the file if the file is 00069 // actually stdout or stderr, so we check this->fileOwned 00070 // first: 00071 if (this->fileOwned) 00072 fclose(this->file); 00073 } 00074 } 00075 00076 void openFile() 00077 { 00078 if (this->file == 0) 00079 { 00080 this->file = stdOutputFileOpen(this->fileName, 00081 &this->fileOwned); 00082 00083 // ok, after all is said and done we should have a valid FILE* 00084 ASSERT(this->file != 0); 00085 } 00086 } 00087 00088 void doPrintHash(const uint32 h, 00089 const std::string& imgname, const std::string& imgtype) 00090 { 00091 this->openFile(); 00092 00093 const bool repeat = (this->hashes.find(h) != this->hashes.end()); 00094 if (!repeat) 00095 this->hashes.insert(h); 00096 00097 fprintf(this->file, "%06d %08x %d %% %s (%s)\n", 00098 this->frameNumber, h, int(repeat), 00099 imgname.c_str(), imgtype.c_str()); 00100 fflush(this->file); 00101 } 00102 00103 template <class T> 00104 void printHash(const Image<T>& ima, 00105 const std::string& imgname, const std::string& imgtype) 00106 { 00107 const uint32 h = 00108 jenkinshash(reinterpret_cast<const byte*>(ima.getArrayPtr()), 00109 ima.getSize() * sizeof(T), 00110 0); 00111 00112 this->doPrintHash(h, imgname, imgtype); 00113 } 00114 00115 void printHash(const VideoFrame& frame, 00116 const std::string& imgname, const std::string& imgtype) 00117 { 00118 const uint32 h = 00119 jenkinshash(reinterpret_cast<const byte*>(frame.getBuffer()), 00120 frame.getBufSize(), 00121 0); 00122 00123 this->doPrintHash(h, imgname, imgtype); 00124 } 00125 00126 std::string fileName; 00127 bool fileOwned; 00128 int frameNumber; 00129 FILE* file; 00130 std::set<uint32> hashes; 00131 }; 00132 00133 // ###################################################################### 00134 HashOutputSeries::HashOutputSeries(OptionManager& mgr) 00135 : 00136 FrameOstream(mgr, "Hash Output Series", "HashOutputSeries"), 00137 rep(new Impl) 00138 {} 00139 00140 // ###################################################################### 00141 HashOutputSeries::~HashOutputSeries() 00142 { 00143 delete rep; 00144 } 00145 00146 // ###################################################################### 00147 void HashOutputSeries::setConfigInfo(const std::string& filename) 00148 { 00149 // NOTE: if you modify any behavior here, then please update the 00150 // corresponding documentation for the global "--out" option inside 00151 // the OPT_OutputFrameSink definition in Media/MediaOpts.C 00152 00153 this->setFileName(filename); 00154 } 00155 00156 // ###################################################################### 00157 bool HashOutputSeries::setFrameNumber(int n) 00158 { 00159 rep->frameNumber = n; 00160 00161 return true; 00162 } 00163 00164 // ###################################################################### 00165 void HashOutputSeries::writeFrame(const GenericFrame& f, 00166 const std::string& shortname, 00167 const FrameInfo& auxinfo) 00168 { 00169 const std::string nm = shortname; 00170 const std::string tp = f.nativeTypeName(); 00171 00172 switch (f.nativeType()) 00173 { 00174 case GenericFrame::NONE: break; 00175 case GenericFrame::RGB_U8: rep->printHash(f.asRgbU8(),nm,tp); break; 00176 case GenericFrame::RGBD: rep->printHash(f.asRgbU8(),nm,tp); break; 00177 case GenericFrame::RGB_F32: rep->printHash(f.asRgbF32(),nm,tp); break; 00178 case GenericFrame::GRAY_U8: rep->printHash(f.asGrayU8(),nm,tp); break; 00179 case GenericFrame::GRAY_F32: rep->printHash(f.asGrayF32(),nm,tp);break; 00180 case GenericFrame::VIDEO: rep->printHash(f.asVideo(),nm,tp); break; 00181 case GenericFrame::RGB_U16: break; 00182 case GenericFrame::GRAY_U16: break; 00183 } 00184 } 00185 00186 // ###################################################################### 00187 void HashOutputSeries::closeStream(const std::string& shortname) 00188 { 00189 /* nothing to see here, move along */ 00190 } 00191 00192 // ###################################################################### 00193 void HashOutputSeries::setFileName(const std::string& s) 00194 { 00195 if (rep->file != 0) 00196 LFATAL("can't change filename while output file is already open"); 00197 00198 rep->fileName = s; 00199 } 00200 00201 // ###################################################################### 00202 /* So things look consistent in everyone's emacs... */ 00203 /* Local Variables: */ 00204 /* indent-tabs-mode: nil */ 00205 /* End: */ 00206 00207 #endif // TRANSPORT_HASHOUTPUTSERIES_C_DEFINED