28 ImageSynthExpr(
const std::string &expr)
47 void eval(
double *result)
override
52 void eval(
const char **)
override
58 mutable std::map<std::string, Var> vars;
63 auto i = vars.find(name);
71 constexpr
double clamp(
double x)
78 int main(
int argc,
char *argv[])
81 std::cerr <<
"Usage: " << argv[0] <<
" <image file> <width> <height> <exprFile>" << std::endl;
86 const char *imageFile = argv[1];
87 const char *exprFile = argv[4];
88 size_t width = std::strtoul(argv[2],
nullptr, 10);
89 size_t height = std::strtoul(argv[3],
nullptr, 10);
90 if (!width || !height) {
91 std::cerr <<
"invalid width/height" << std::endl;
95 std::ifstream istream(exprFile);
97 std::cerr <<
"Cannot read file " << exprFile << std::endl;
100 std::string exprStr((std::istreambuf_iterator<char>(istream)), std::istreambuf_iterator<char>());
101 ImageSynthExpr expr(exprStr);
104 expr.vars[
"u"] = ImageSynthExpr::Var(0.);
105 expr.vars[
"v"] = ImageSynthExpr::Var(0.);
106 expr.vars[
"w"] = ImageSynthExpr::Var(width);
107 expr.vars[
"h"] = ImageSynthExpr::Var(height);
110 bool valid = expr.isValid();
112 std::cerr <<
"Invalid expression " << std::endl;
113 std::cerr << expr.parseError() << std::endl;
116 if (!expr.returnType().isFP(3)) {
117 std::cerr <<
"Expected color FP[3] got type " << expr.returnType().toString() << std::endl;
122 std::cerr <<
"Evaluating expresion...from " << exprFile << std::endl;
123 std::vector<unsigned char> image(width * height * 4);
127 double one_over_width = 1. / width;
128 double one_over_height = 1. / height;
129 double &u = expr.vars[
"u"].val;
130 double &v = expr.vars[
"v"].val;
131 for (
size_t row {}; row < height; row++) {
132 for (
size_t col {}; col < width; col++) {
133 auto i = (row * width + col) * 4;
134 u = one_over_width * (col + .5);
135 v = one_over_height * (row + .5);
137 const double *result = expr.evalFP();
140 image[i] =
clamp(result[0] * 256.);
141 image[i + 1] =
clamp(result[1] * 256.);
142 image[i + 2] =
clamp(result[2] * 256.);
149 std::cerr <<
"Writing image..." << imageFile << std::endl;
150 std::unique_ptr<std::FILE, decltype(&std::fclose)> fp {fopen(imageFile,
"wb"), &std::fclose};
155 png_structp png_ptr {png_create_write_struct(PNG_LIBPNG_VER_STRING,
nullptr,
nullptr,
nullptr)};
156 png_infop info_ptr {png_create_info_struct(png_ptr)};
157 png_init_io(png_ptr, fp.get());
158 png_set_IHDR(png_ptr,
165 PNG_COMPRESSION_TYPE_DEFAULT,
166 PNG_FILTER_TYPE_DEFAULT);
167 std::vector<png_byte *> ptrs(height);
168 for (
size_t i {}; i < height; i++) {
169 ptrs[i] = &image[width * i * 4];
171 png_set_rows(png_ptr, info_ptr, ptrs.data());
172 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY,
nullptr);
void eval(ArgHandle args) override
abstract class for implementing variable references
virtual ExprVarRef * resolveVar(const std::string &) const
int main(int argc, char *argv[])
constexpr double clamp(double x)
double max(double x, double y)
double min(double x, double y)
double clamp(double x, double lo, double hi)