00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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:
00148 case GenericFrame::VIDEO:
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
00203
00204
00205
00206
00207
00208 #endif // RASTER_CCODEWRITER_C_DEFINED