00001 /*!@file Media/MgzEncoder.C Low-level class to decode mgz 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: Rob Peters <rjpeters at usc dot edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Media/MgzEncoder.C $ 00035 // $Id: MgzEncoder.C 8906 2007-10-25 23:30:51Z rjpeters $ 00036 // 00037 00038 #ifndef MEDIA_MGZENCODER_C_DEFINED 00039 #define MEDIA_MGZENCODER_C_DEFINED 00040 00041 #include "Media/MgzEncoder.H" 00042 00043 #include "Image/Image.H" 00044 #include "Image/Pixels.H" 00045 #include "Util/log.H" 00046 #include "Util/sformat.H" 00047 #include "rutz/trace.h" 00048 00049 #include <sys/errno.h> 00050 00051 // ###################################################################### 00052 MgzEncoder::MgzEncoder(const std::string& fname, const int complev) 00053 { 00054 // build the open mode, including compression level: 00055 if (complev < 1 || complev > 9) 00056 LFATAL("Invalid compression level %d: must be in [1..9]", complev); 00057 const std::string m = sformat("wb%d", complev); 00058 00059 // open the file for writing: 00060 itsFile = gzopen(fname.c_str(), m.c_str()); 00061 00062 if (itsFile == NULL) 00063 { 00064 if (errno) PLFATAL("Could not open '%s' for writing", fname.c_str()); 00065 else LFATAL("No memory to open '%s' for writing", fname.c_str()); 00066 } 00067 } 00068 00069 // ###################################################################### 00070 MgzEncoder::~MgzEncoder() 00071 { 00072 this->close(); 00073 } 00074 00075 // ###################################################################### 00076 int MgzEncoder::close() 00077 { 00078 GVX_TRACE(__PRETTY_FUNCTION__); 00079 00080 int err = 0; 00081 00082 if (itsFile) 00083 { 00084 //LDEBUG("Closing and flushing output buffers..."); 00085 err = gzclose(itsFile); 00086 if (err == Z_ERRNO) 00087 PLERROR("Error closing file"); 00088 else if (err) 00089 LERROR("Error closing file: %s", gzerror(itsFile, &err)); 00090 00091 itsFile = NULL; 00092 } 00093 00094 return err; 00095 } 00096 00097 // ###################################################################### 00098 void MgzEncoder::writeFrame(const GenericFrame& frame) 00099 { 00100 GVX_TRACE(__PRETTY_FUNCTION__); 00101 00102 if (itsFile == NULL) LFATAL("No file open for writing"); 00103 const size_t siz = frame.getDims().sz(); 00104 00105 // NOTE: This is not portable! 00106 uint32 wht[3]; 00107 wht[0] = frame.getDims().w(); wht[1] = frame.getDims().h(); 00108 wht[2] = uint32(frame.nativeType()); 00109 00110 // write the dims and native type: 00111 if (gzwrite(itsFile, wht, 3 * sizeof(uint32)) != 3 * sizeof(uint32)) 00112 PLFATAL("Error writing to file"); 00113 00114 switch(frame.nativeType()) 00115 { 00116 00117 case GenericFrame::GRAY_F32: 00118 { 00119 // first write the float flags: 00120 int32 flags = int32(frame.floatFlags()); 00121 if (gzwrite(itsFile, &flags, sizeof(int32)) != int(sizeof(int32))) 00122 PLFATAL("Error writing to file"); 00123 00124 // now the image data: 00125 Image<float> f = frame.asFloat(); 00126 const size_t s = siz * sizeof(float); 00127 if (gzwrite(itsFile, f.getArrayPtr(), s) != int(s)) 00128 PLFATAL("Error writing to file"); 00129 } 00130 break; 00131 00132 case GenericFrame::GRAY_U8: 00133 { 00134 Image<byte> f = frame.asGray(); 00135 const size_t s = siz * sizeof(byte); 00136 if (gzwrite(itsFile, f.getArrayPtr(), s) != int(s)) 00137 PLFATAL("Error writing to file"); 00138 } 00139 break; 00140 00141 case GenericFrame::RGB_U8: 00142 { 00143 Image< PixRGB<byte> > f = frame.asRgb(); 00144 const size_t s = siz * 3 * sizeof(byte); 00145 if (gzwrite(itsFile, f.getArrayPtr(), s) != int(s)) 00146 PLFATAL("Error writing to file"); 00147 } 00148 break; 00149 00150 case GenericFrame::RGB_F32: 00151 { 00152 // first write the float flags: 00153 int32 flags = int32(frame.floatFlags()); 00154 if (gzwrite(itsFile, &flags, sizeof(int32)) != int(sizeof(int32))) 00155 PLFATAL("Error writing to file"); 00156 00157 // now the image data: 00158 Image< PixRGB<float> > f = frame.asRgbF32(); 00159 const size_t s = siz * sizeof(PixRGB<float>); 00160 if (gzwrite(itsFile, f.getArrayPtr(), s) != int(s)) 00161 PLFATAL("Error writing to file"); 00162 } 00163 break; 00164 00165 case GenericFrame::VIDEO: 00166 { 00167 const VideoFrame f = frame.asVideo(); 00168 00169 int32 vidformat = int32(f.getMode()); 00170 if (gzwrite(itsFile, &vidformat, sizeof(vidformat)) != 00171 int(sizeof(vidformat))) 00172 PLFATAL("Error writing video format to file"); 00173 00174 int32 byteswap = int32(f.getByteSwap()); 00175 if (gzwrite(itsFile, &byteswap, sizeof(byteswap)) != 00176 int(sizeof(byteswap))) 00177 PLFATAL("Error writing byteswap to file"); 00178 00179 if (gzwrite(itsFile, (void*)(f.getBuffer()), f.getBufSize()) != 00180 int(f.getBufSize())) 00181 PLFATAL("Error writing video data to file"); 00182 } 00183 break; 00184 00185 case GenericFrame::NONE: 00186 // nothing to do herexo 00187 break; 00188 00189 default: 00190 LFATAL("Cannot write frames of type %s", frame.nativeTypeName().c_str()); 00191 } 00192 } 00193 00194 // ###################################################################### 00195 /* So things look consistent in everyone's emacs... */ 00196 /* Local Variables: */ 00197 /* mode: c++ */ 00198 /* indent-tabs-mode: nil */ 00199 /* End: */ 00200 00201 #endif // MEDIA_MGZENCODER_C_DEFINED