void Generate(int cubesize, int maxwidth, const std::string & outputfile, const std::string & configfile, const std::string & incolorspace, const std::string & outcolorspace) { int width = 0; int height = 0; int numchannels = 3; GetLutImageSize(width, height, cubesize, maxwidth); std::vector<float> img; img.resize(width*height*numchannels, 0); GenerateIdentityLut3D(&img[0], cubesize, numchannels, LUT3DORDER_FAST_RED); if(!incolorspace.empty() || !outcolorspace.empty()) { OCIO::ConstConfigRcPtr config = OCIO::Config::Create(); if(!configfile.empty()) { config = OCIO::Config::CreateFromFile(configfile.c_str()); } else if(getenv("OCIO")) { config = OCIO::Config::CreateFromEnv(); } else { std::ostringstream os; os << "You must specify an ocio configuration "; os << "(either with --config or $OCIO)."; throw Exception(os.str().c_str()); } OCIO::ConstProcessorRcPtr processor = config->getProcessor(incolorspace.c_str(), outcolorspace.c_str()); OCIO::PackedImageDesc imgdesc(&img[0], width, height, 3); processor->apply(imgdesc); } OIIO::ImageOutput* f = OIIO::ImageOutput::create(outputfile); if(!f) { throw Exception( "Could not create output image."); } OIIO::ImageSpec spec(width, height, numchannels, OIIO::TypeDesc::TypeFloat); // TODO: If DPX, force 16-bit output? f->open(outputfile, spec); f->write_image(OIIO::TypeDesc::FLOAT, &img[0]); f->close(); delete f; }
///< The function evaluates SH functions and dumps values to latitude-longitude map void ShEvaluateAndDump(ImageIo& io, std::string const& filename, int width, int height, int lmax, float3 const* coeffs) { // Prepare image memory std::vector<float> imagedata(width * height * 3); // Allocate space for SH functions std::vector<float> ylm(NumShTerms(lmax)); // Precalculate sin and cos terms std::vector<float> sintheta(height); std::vector<float> costheta(height); std::vector<float> sinphi(width); std::vector<float> cosphi(width); float thetastep = PI / height; float phistep = 2.f*PI / width; float theta0 = PI / height / 2; float phi0= 2.f*PI / width / 2; for (int i = 0; i < width; ++i) { sinphi[i] = std::sin(phi0 + i * phistep); cosphi[i] = std::cos(phi0 + i * phistep); } for (int i = 0; i < height; ++i) { sintheta[i] = std::sin(theta0 + i * thetastep); costheta[i] = std::cos(theta0 + i * thetastep); } // Iterate thru image pixels for (int phi = 0; phi < width; ++phi) { for (int theta = 0; theta < height; ++theta) { // Calculate direction float3 w = normalize(float3(sintheta[theta] * cosphi[phi], costheta[theta], sintheta[theta] * sinphi[phi])); // Evaluate SH functions at w up to lmax band ShEvaluate(w, lmax, &ylm[0]); // Evaluate function injecting SH coeffs for (int i = 0; i < NumShTerms(lmax); ++i) { imagedata[theta * width * 3 + phi * 3] += ylm[i] * coeffs[i].x; imagedata[theta * width * 3 + phi * 3 + 1] += ylm[i] * coeffs[i].y; imagedata[theta * width * 3 + phi * 3 + 2] += ylm[i] * coeffs[i].z; } } } // Write image to file ImageIo::ImageDesc imgdesc(width, height, 3); io.Write(filename, imagedata, imgdesc); }