00001
00002
00003
00004
00005
00006
00007
00008
00009
00013 #include <map>
00014 #include <cstdlib>
00015 #include <cstdio>
00016 #include <cstring>
00017 #include <SeExpression.h>
00018 #include <png.h>
00019 #include <fstream>
00020
00022 class ImageSynthExpr:public SeExpression
00023 {
00024 public:
00026 ImageSynthExpr(const std::string& expr)
00027 :SeExpression(expr)
00028 {}
00029
00031 struct Var:public SeExprScalarVarRef
00032 {
00033 Var(const double val):val(val){}
00034 Var(){}
00035 double val;
00036 void eval(const SeExprVarNode* ,SeVec3d& result)
00037 {result[0]=val;}
00038 };
00040 mutable std::map<std::string,Var> vars;
00041
00043 SeExprVarRef* resolveVar(const std::string& name) const
00044 {
00045 std::map<std::string,Var>::iterator i=vars.find(name);
00046 if(i != vars.end()) return &i->second;
00047 return 0;
00048 }
00049 };
00050
00051
00052 double clamp(double x){return std::max(0.,std::min(255.,x));}
00053
00054 int main(int argc,char *argv[]){
00055 if(argc != 5){
00056 std::cerr<<"Usage: "<<argv[0]<<" <image file> <width> <height> <exprFile>"<<std::endl;
00057 return 1;
00058 }
00059
00060
00061 const char* imageFile=argv[1];
00062 const char* exprFile=argv[4];
00063 int width=atoi(argv[2]),height=atoi(argv[3]);
00064 if(width<0 || height<0){
00065 std::cerr<<"invalid width/height"<<std::endl;
00066 return 1;
00067 }
00068
00069 std::ifstream istream(exprFile);
00070 if(!istream){
00071 std::cerr<<"Cannot read file "<<exprFile<<std::endl;
00072 return 1;
00073 }
00074 std::string exprStr((std::istreambuf_iterator<char>(istream)),std::istreambuf_iterator<char>());
00075 ImageSynthExpr expr(exprStr);
00076
00077
00078 expr.vars["u"]=ImageSynthExpr::Var(0.);
00079 expr.vars["v"]=ImageSynthExpr::Var(0.);
00080 expr.vars["w"]=ImageSynthExpr::Var(width);
00081 expr.vars["h"]=ImageSynthExpr::Var(height);
00082
00083
00084 bool valid=expr.isValid();
00085 if(!valid){
00086 std::cerr<<"Invalid expression "<<std::endl;
00087 std::cerr<<expr.parseError()<<std::endl;
00088 }
00089
00090
00091 std::cerr<<"Evaluating expresion...from "<<exprFile<<std::endl;
00092 unsigned char* image=new unsigned char[width*height*4];
00093 double one_over_width=1./width,one_over_height=1./height;
00094 double& u=expr.vars["u"].val;
00095 double& v=expr.vars["v"].val;
00096 unsigned char* pixel=image;
00097 for(int row=0;row<height;row++){
00098 for(int col=0;col<width;col++){
00099 u=one_over_width*(col+.5);
00100 v=one_over_height*(row+.5);
00101 SeVec3d result=expr.evaluate();
00102 pixel[0]=clamp(result[0]*256.);
00103 pixel[1]=clamp(result[1]*256.);
00104 pixel[2]=clamp(result[2]*256.);
00105 pixel[3]=255;
00106 pixel+=4;
00107 }
00108 }
00109
00110
00111 std::cerr<<"Writing image..."<<imageFile<<std::endl;
00112 FILE *fp=fopen(imageFile,"wb");
00113 if(!fp){
00114 perror("fopen");
00115 return 1;
00116 }
00117 png_structp png_ptr;
00118 png_infop info_ptr;
00119 png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0);
00120 info_ptr=png_create_info_struct(png_ptr);
00121 png_init_io(png_ptr,fp);
00122 int color_type=PNG_COLOR_TYPE_RGBA;
00123 png_set_IHDR(png_ptr,info_ptr,width,height,8,color_type,PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_DEFAULT);
00124 const unsigned char *ptrs[height];
00125 for(int i=0;i<height;i++){
00126 ptrs[i]=&image[width*i*4];
00127 }
00128 png_set_rows(png_ptr,info_ptr,(png_byte**)ptrs);
00129 png_write_png(png_ptr,info_ptr,PNG_TRANSFORM_IDENTITY,0);
00130
00131 fclose(fp);
00132 }