00001 /*!@file Raster/CcodeWriter.C Writes images as C-language arrays, suitable for copy+paste back into source code */ 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/Raster/CcodeWriter.C $ 00035 // $Id: CcodeWriter.C 8334 2007-05-03 23:24:15Z rjpeters $ 00036 // 00037 00038 #ifndef RASTER_CCODEWRITER_C_DEFINED 00039 #define RASTER_CCODEWRITER_C_DEFINED 00040 00041 #include "Raster/CcodeWriter.H" 00042 00043 #include "Image/Image.H" 00044 #include "Image/Pixels.H" 00045 #include "Raster/GenericFrame.H" 00046 #include "Util/log.H" 00047 00048 #include <cctype> 00049 #include <cstdio> 00050 00051 namespace 00052 { 00053 std::string makeCleanArrayName(const std::string& fname) 00054 { 00055 std::string s = "ccode_"; 00056 bool prev_underscore = true; 00057 for (size_t i = 0; i < fname.size(); ++i) 00058 { 00059 if (isalnum(fname[i])) 00060 { 00061 s += fname[i]; 00062 prev_underscore = false; 00063 } 00064 else if (!prev_underscore) 00065 { 00066 s += "_"; 00067 prev_underscore = true; 00068 } 00069 } 00070 return s; 00071 } 00072 00073 void dumpPixel(FILE* f, const byte* p) 00074 { fprintf(f, "%3d", int(*p)); } 00075 00076 void dumpPixel(FILE* f, const float* p) 00077 { fprintf(f, "%.9e", *p); } 00078 00079 void dumpPixel(FILE* f, const PixRGB<byte>* p) 00080 { fprintf(f, "PixRGB<byte>(%3d, %3d, %3d)", 00081 int(p->p[0]), int(p->p[1]), int(p->p[2])); } 00082 00083 void dumpPixel(FILE* f, const PixRGB<float>* p) 00084 { fprintf(f, "PixRGB<byte>(%.9e, %.9e, %.9e)", 00085 p->p[0], p->p[1], p->p[2]); } 00086 00087 const char* pixTypeName(byte*) { return "byte"; } 00088 const char* pixTypeName(float*) { return "float"; } 00089 const char* pixTypeName(PixRGB<byte>*) { return "PixRGB<byte>"; } 00090 const char* pixTypeName(PixRGB<float>*) { return "PixRGB<float>"; } 00091 00092 template <class T> 00093 void dumpImage(const Image<T>& img, 00094 const std::string& fname) 00095 { 00096 FILE* f = fopen(fname.c_str(), "w"); 00097 if (f == 0) 00098 LFATAL("couldn't open %s for writing", fname.c_str()); 00099 00100 const std::string aname = makeCleanArrayName(fname); 00101 00102 const int w = img.getWidth(); 00103 const int h = img.getHeight(); 00104 00105 fprintf(f, "const int w_%s = %d;\n", aname.c_str(), w); 00106 fprintf(f, "const int h_%s = %d;\n", aname.c_str(), h); 00107 fprintf(f, "const %s %s[%d] = {\n", 00108 pixTypeName((T*)0), aname.c_str(), w*h); 00109 00110 typename Image<T>::const_iterator itr = img.begin(); 00111 for (int y = 0; y < h; ++y) 00112 { 00113 fprintf(f, "\t/* row %6d */ ", y); 00114 for (int x = 0; x < w; ++x) 00115 { 00116 dumpPixel(f, &itr[0]); 00117 ++itr; 00118 if (x == w-1) 00119 { 00120 if (y == h-1) fprintf(f, "\n"); 00121 else fprintf(f, ",\n"); 00122 } 00123 else fprintf(f, ", "); 00124 } 00125 } 00126 00127 fprintf(f, "};\n"); 00128 00129 fclose(f); 00130 } 00131 } 00132 00133 // ###################################################################### 00134 CcodeWriter::CcodeWriter() 00135 {} 00136 00137 // ###################################################################### 00138 CcodeWriter::~CcodeWriter() 00139 {} 00140 00141 // ###################################################################### 00142 std::string CcodeWriter::writeFrame(const GenericFrame& image, 00143 const std::string& fname) 00144 { 00145 switch (image.nativeType()) 00146 { 00147 case GenericFrame::NONE: // fall-through 00148 case GenericFrame::VIDEO: // fall-through 00149 case GenericFrame::RGB_U8: 00150 writeCcodeRgbU8(image.asRgbU8(), fname); 00151 break; 00152 00153 case GenericFrame::RGB_F32: 00154 writeCcodeRgbF32(image.asRgbF32(), fname); 00155 break; 00156 00157 case GenericFrame::GRAY_U8: 00158 writeCcodeGrayU8(image.asGrayU8(), fname); 00159 break; 00160 00161 case GenericFrame::GRAY_F32: 00162 writeCcodeGrayF32(image.asGrayF32(), fname); 00163 break; 00164 00165 default: 00166 LFATAL("unknown GenericFrame::NativeType value %d", 00167 int(image.nativeType())); 00168 } 00169 00170 return fname; 00171 } 00172 00173 // ###################################################################### 00174 void CcodeWriter::writeCcodeRgbU8(const Image<PixRGB<byte> >& img, 00175 const std::string& fname) 00176 { 00177 dumpImage(img, fname); 00178 } 00179 00180 // ###################################################################### 00181 void CcodeWriter::writeCcodeRgbF32(const Image<PixRGB<float> >& img, 00182 const std::string& fname) 00183 { 00184 dumpImage(img, fname); 00185 } 00186 00187 // ###################################################################### 00188 void CcodeWriter::writeCcodeGrayU8(const Image<byte>& img, 00189 const std::string& fname) 00190 { 00191 dumpImage(img, fname); 00192 } 00193 00194 // ###################################################################### 00195 void CcodeWriter::writeCcodeGrayF32(const Image<float>& img, 00196 const std::string& fname) 00197 { 00198 dumpImage(img, fname); 00199 } 00200 00201 // ###################################################################### 00202 /* So things look consistent in everyone's emacs... */ 00203 /* Local Variables: */ 00204 /* mode: c++ */ 00205 /* indent-tabs-mode: nil */ 00206 /* End: */ 00207 00208 #endif // RASTER_CCODEWRITER_C_DEFINED