PfzWriter.C

Go to the documentation of this file.
00001 /*!@file Raster/PfzWriter.C Write pfm image 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: T. Nathan Mundenk <mundhenk@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Raster/PfzWriter.C $
00035 // $Id: PfzWriter.C 14290 2010-12-01 21:44:03Z itti $
00036 //
00037 
00038 #ifndef RASTER_PFMWRITER_C_DEFINED
00039 #define RASTER_PFMWRITER_C_DEFINED
00040 
00041 #include "Raster/PfzWriter.H"
00042 
00043 #include "Image/Image.H"
00044 #include "Image/Pixels.H"
00045 #include "Raster/GenericFrame.H"
00046 
00047 #include <fstream>
00048 #include <iostream> // for std::cerr
00049 #include <sstream>
00050 
00051 PfzWriter::PfzWriter() {}
00052 
00053 PfzWriter::~PfzWriter() {}
00054 
00055 std::deque<std::string> PfzWriter::itsTagName(0);
00056 std::deque<std::string> PfzWriter::itsTagValue(0);
00057 z_stream                PfzWriter::zstrm;
00058 unsigned char           PfzWriter::buff_uin[PFZ_CHUNK];
00059 unsigned char           PfzWriter::buff_uout[PFZ_CHUNK];
00060 int                     PfzWriter::itsCompressionLevel(PFZ_LEVEL);
00061 
00062 std::string PfzWriter::writeFrame(const GenericFrame& image,
00063                                   const std::string& fname)
00064 {
00065   switch (image.nativeType())
00066     {
00067     case GenericFrame::NONE:
00068       LFATAL("cannot write an empty image to '%s'", fname.c_str());
00069       break;
00070 
00071     case GenericFrame::RGB_U8:
00072     case GenericFrame::RGBD:
00073       LFATAL("cannot write an RGB byte image '%s' in PFZ format", fname.c_str());
00074       break;
00075 
00076     case GenericFrame::RGB_U16:
00077       LFATAL("cannot write an RGB byte image '%s' in PFZ format", fname.c_str());
00078       break;
00079 
00080     case GenericFrame::RGB_F32:
00081       LFATAL("cannot write an RGB float image '%s' in PFZ format", fname.c_str());
00082       break;
00083 
00084     case GenericFrame::GRAY_U8:
00085       PfzWriter::writeFloat(image.asFloat(), fname);
00086       break;
00087 
00088     case GenericFrame::GRAY_U16:
00089       LFATAL("cannot write an 16 bit gray image '%s' in PFZ format", fname.c_str());
00090       break;
00091 
00092     case GenericFrame::GRAY_F32:
00093       PfzWriter::writeFloat(image.asFloat(), fname);
00094       break;
00095 
00096     case GenericFrame::VIDEO:
00097       LFATAL("cannot write a video frame '%s' in PFZ format", fname.c_str());
00098       break;
00099     }
00100 
00101   return fname;
00102 }
00103 
00104 void PfzWriter::writeFloat(const Image<float>& image,
00105                            const std::string& fname,
00106                            const std::deque<std::string> tagName,
00107                            const std::deque<std::string> tagValue)
00108 {
00109   itsTagName  = tagName;
00110   itsTagValue = tagValue;
00111   writeFloat(image,fname,true);
00112 }
00113 
00114 void PfzWriter::writeFloat(const Image<float>& image,
00115                            const std::string& fname,
00116                            const bool useTag)
00117 {
00118   int flush = 0;
00119 
00120   /* allocate deflate state */
00121   zstrm.zalloc   = Z_NULL;
00122   zstrm.zfree    = Z_NULL;
00123   zstrm.opaque   = Z_NULL;
00124 
00125   //
00126   if((itsCompressionLevel < -1) || (itsCompressionLevel > 9))
00127     LFATAL("Invalid compression level '%d' given for pfz image '%s'",
00128            itsCompressionLevel,fname.c_str());
00129 
00130   const int retI = deflateInit(&zstrm, itsCompressionLevel);
00131 
00132   if (retI != Z_OK)
00133     LFATAL("Unable to allocate memory and set up zlib compression in PFZ '%s'",
00134            fname.c_str());
00135 
00136   // first we take the image into a standard stream for formating
00137 
00138   std::stringstream os;
00139   std::ofstream ofs(fname.c_str(), std::ios::binary);
00140   if (!ofs.is_open())
00141     LFATAL("Couldn't open PFZ file '%s' for writing.", fname.c_str());
00142 
00143   ofs << "PZ\n"
00144       << "# PFZ image - Mundhenk, Itti (C) 2006\n";
00145   os  << image.getWidth() << ' ' << image.getHeight()
00146       << "\n1.0\n"
00147       << "!Image Info\n"
00148       << "PFZ Image compressed floating point image for INVT\n"
00149       << "!URL\n"
00150       << "http://www.nerd-cam.com\n"
00151       << "!Compression Level\n"
00152       << itsCompressionLevel << "\n";
00153 
00154   // write extra tags if supplied, these will be compressed
00155   if(useTag)
00156   {
00157     std::deque<std::string>::iterator tagNameItr  = itsTagName.begin();
00158     std::deque<std::string>::iterator tagValueItr = itsTagValue.begin();
00159     while(tagNameItr != itsTagName.end())
00160     {
00161       os << "!" << *tagNameItr << "\n" << *tagValueItr << "\n";
00162       ++tagNameItr; ++tagValueItr;
00163     }
00164   }
00165 
00166   os << " ";
00167 
00168   // push the image into the sstream
00169   os.write(reinterpret_cast<const char*>(image.getArrayPtr()),
00170             image.getSize() * sizeof(float));
00171 
00172   // sync the string stream buffers
00173   os.flush();
00174 
00175   // buffer each PFZ_CHUNK of the image stream into zlibs stream
00176   while(os.good())
00177   {
00178     os.read(reinterpret_cast<char*>(buff_uin),PFZ_CHUNK);
00179     zstrm.avail_in = os.gcount();
00180     /*
00181     unsigned char *uin = &buff_uin[0];
00182     char           *in = &buff_in[0];
00183     for(uint i = 0; i < PFZ_CHUNK; i++)
00184     {
00185       *uin = clamped_convert<byte>(*in);
00186       ++uin; ++in;
00187     }
00188     */
00189     zstrm.next_in = buff_uin;
00190     // for each in chunk, compress them, we use this inner loop
00191     // because zlib may not compress the entire chunk in one go and may
00192     // need to take it in several pieces
00193     // avail_out is set via pointer to 0 when we are done
00194     zstrm.avail_out = 0;
00195 
00196     if(os.good())
00197       flush = Z_NO_FLUSH;
00198     else
00199       flush = Z_FINISH;
00200 
00201     while(zstrm.avail_out == 0)
00202     {
00203       zstrm.avail_out = PFZ_CHUNK;
00204       zstrm.next_out  = buff_uout;
00205       const int ret   = deflate(&zstrm, flush);
00206 
00207       if(ret == Z_STREAM_ERROR)
00208         LFATAL("Error in PFZ zlib compression stream of image '%s'",
00209                fname.c_str());
00210 
00211       const uint have = PFZ_CHUNK - zstrm.avail_out;
00212       /*
00213       unsigned char *uout = &buff_uout[0];
00214       char           *out = &buff_out[0];
00215       for(uint i = 0; i < have; i++)
00216       {
00217         *out = clamped_convert<char>(*uout);
00218         ++uout; ++out;
00219       }
00220       */
00221       ofs.write(reinterpret_cast<char*>(buff_uout),have);
00222       if (ofs.fail())
00223         LFATAL("Output stream failure while writing '%s'.", fname.c_str());
00224     }
00225   }
00226   ofs.close();
00227   deflateEnd(&zstrm);
00228 }
00229 
00230 // ######################################################################
00231 /* So things look consistent in everyone's emacs... */
00232 /* Local Variables: */
00233 /* mode: c++ */
00234 /* indent-tabs-mode: nil */
00235 /* End: */
00236 
00237 #endif // RASTER_PFMWRITER_C_DEFINED
Generated on Sun May 8 08:41:16 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3