static int output_file (int argc, const char *argv[]) { ASSERT (argc == 2 && !strcmp(argv[0],"-o")); std::string filename = argv[1]; if (! ot.curimg.get()) { std::cerr << "oiiotool ERROR: -o " << filename << " did not have any current image to output.\n"; return 0; } if (ot.noclobber && Filesystem::exists(filename)) { std::cerr << "oiiotool ERROR: Output file \"" << filename << "\" already exists, not overwriting.\n"; return 0; } if (ot.verbose) std::cout << "Writing " << argv[1] << "\n"; ImageOutput *out = ImageOutput::create (filename.c_str()); if (! out) { std::cerr << "oiiotool ERROR: " << geterror() << "\n"; return 0; } bool supports_displaywindow = out->supports ("displaywindow"); ot.read (); ImageRecRef saveimg = ot.curimg; ImageRecRef ir (ot.curimg); if (! supports_displaywindow && ot.output_autocrop && (ir->spec()->x != ir->spec()->full_x || ir->spec()->y != ir->spec()->full_y || ir->spec()->width != ir->spec()->full_width || ir->spec()->height != ir->spec()->full_height)) { const char *argv[] = { "croptofull" }; int action_croptofull (int argc, const char *argv[]); // forward decl action_croptofull (1, argv); ir = ot.curimg; } ImageOutput::OpenMode mode = ImageOutput::Create; // initial open for (int s = 0, send = ir->subimages(); s < send; ++s) { for (int m = 0, mend = ir->miplevels(s); m < mend; ++m) { ImageSpec spec = *ir->spec(s,m); adjust_output_options (spec, ot); if (! out->open (filename, spec, mode)) { std::cerr << "oiiotool ERROR: " << out->geterror() << "\n"; return 0; } if (! (*ir)(s,m).write (out)) { std::cerr << "oiiotool ERROR: " << (*ir)(s,m).geterror() << "\n"; return 0; } if (mend > 1) { if (out->supports("mipmap")) { mode = ImageOutput::AppendMIPLevel; // for next level } else if (out->supports("multiimage")) { mode = ImageOutput::AppendSubimage; } else { std::cout << "oiiotool WARNING: " << out->format_name() << " does not support MIP-maps for " << filename << "\n"; break; } } } mode = ImageOutput::AppendSubimage; // for next subimage if (send > 1 && ! out->supports("multiimage")) { std::cout << "oiiotool WARNING: " << out->format_name() << " does not support multiple subimages for " << filename << "\n"; break; } } out->close (); delete out; if (ot.output_adjust_time) { std::string metadatatime = ir->spec(0,0)->get_string_attribute ("DateTime"); std::time_t in_time = ir->time(); if (! metadatatime.empty()) DateTime_to_time_t (metadatatime.c_str(), in_time); boost::filesystem::last_write_time (filename, in_time); } ot.curimg = saveimg; return 0; }
static void write_mipmap (ImageBuf &img, const ImageSpec &outspec_template, std::string outputfilename, std::string outformat, TypeDesc outputdatatype, bool mipmap) { ImageSpec outspec = outspec_template; outspec.set_format (outputdatatype); // Find an ImageIO plugin that can open the output file, and open it Timer writetimer; ImageOutput *out = ImageOutput::create (outformat.c_str()); if (! out) { std::cerr << "maketx ERROR: Could not find an ImageIO plugin to write " << outformat << " files:" << geterror() << "\n"; exit (EXIT_FAILURE); } if (! out->supports ("tiles")) { std::cerr << "maketx ERROR: \"" << outputfilename << "\" format does not support tiled images\n"; exit (EXIT_FAILURE); } if (mipmap && !out->supports ("multiimage") && !out->supports ("mipmap")) { std::cerr << "maketx ERROR: \"" << outputfilename << "\" format does not support multires images\n"; exit (EXIT_FAILURE); } if (! mipmap && ! strcmp (out->format_name(), "openexr")) { // Send hint to OpenEXR driver that we won't specify a MIPmap outspec.attribute ("openexr:levelmode", 0 /* ONE_LEVEL */); } if (mipmap && ! strcmp (out->format_name(), "openexr")) { outspec.attribute ("openexr:roundingmode", 0 /* ROUND_DOWN */); } // OpenEXR always uses border sampling for environment maps if ((envlatlmode || envcubemode) && !strcmp(out->format_name(), "openexr")) { src_samples_border = true; outspec.attribute ("oiio:updirection", "y"); outspec.attribute ("oiio:sampleborder", 1); } if (envlatlmode && src_samples_border) fix_latl_edges (img); if (! out->open (outputfilename.c_str(), outspec)) { std::cerr << "maketx ERROR: Could not open \"" << outputfilename << "\" : " << out->geterror() << "\n"; exit (EXIT_FAILURE); } // Write out the image if (verbose) { std::cout << " Writing file: " << outputfilename << std::endl; std::cout << " Filter \"" << filter->name() << "\" width = " << filter->width() << "\n"; } bool ok = true; ok &= img.write (out); stat_writetime += writetimer(); if (mipmap) { // Mipmap levels: if (verbose) std::cout << " Mipmapping...\n" << std::flush; ImageBuf tmp; ImageBuf *big = &img, *small = &tmp; while (ok && (outspec.width > 1 || outspec.height > 1)) { Timer miptimer; // Resize a factor of two smaller ImageSpec smallspec = outspec; smallspec.width = big->spec().width; smallspec.height = big->spec().height; smallspec.depth = big->spec().depth; if (smallspec.width > 1) smallspec.width /= 2; if (smallspec.height > 1) smallspec.height /= 2; smallspec.full_width = smallspec.width; smallspec.full_height = smallspec.height; smallspec.full_depth = smallspec.depth; smallspec.set_format (TypeDesc::FLOAT); small->alloc (smallspec); // Realocate with new size if (filtername == "box" && filter->width() == 1.0f) parallel_image (resize_block, small, big, smallspec.x, smallspec.x+smallspec.width, smallspec.y, smallspec.y+smallspec.height, nthreads); else parallel_image (resize_block_HQ, small, big, smallspec.x, smallspec.x+smallspec.width, smallspec.y, smallspec.y+smallspec.height, nthreads); stat_miptime += miptimer(); outspec = smallspec; outspec.set_format (outputdatatype); if (envlatlmode && src_samples_border) fix_latl_edges (*small); Timer writetimer; // If the format explicitly supports MIP-maps, use that, // otherwise try to simulate MIP-mapping with multi-image. bool ok = false; ImageOutput::OpenMode mode = out->supports ("mipmap") ? ImageOutput::AppendMIPLevel : ImageOutput::AppendSubimage; if (! out->open (outputfilename.c_str(), outspec, mode)) { std::cerr << "maketx ERROR: Could not append \"" << outputfilename << "\" : " << out->geterror() << "\n"; exit (EXIT_FAILURE); } ok &= small->write (out); stat_writetime += writetimer(); if (verbose) std::cout << " " << smallspec.width << 'x' << smallspec.height << "\n" << std::flush; std::swap (big, small); } } if (verbose) std::cout << " Wrote file: " << outputfilename << std::endl; writetimer.reset (); writetimer.start (); if (ok) ok &= out->close (); stat_writetime += writetimer (); delete out; if (! ok) { std::cerr << "maketx ERROR writing \"" << outputfilename << "\" : " << out->geterror() << "\n"; exit (EXIT_FAILURE); } }
static bool convert_file (const std::string &in_filename, const std::string &out_filename) { if (noclobber && Filesystem::exists(out_filename)) { std::cerr << "iconvert ERROR: Output file already exists \"" << out_filename << "\"\n"; return false; } if (verbose) std::cout << "Converting " << in_filename << " to " << out_filename << "\n"; std::string tempname = out_filename; if (tempname == in_filename) { tempname = out_filename + ".tmp" + Filesystem::extension (out_filename); } // Find an ImageIO plugin that can open the input file, and open it. ImageInput *in = ImageInput::open (in_filename.c_str()); if (! in) { std::string err = geterror(); std::cerr << "iconvert ERROR: " << (err.length() ? err : Strutil::format("Could not open \"%s\"", in_filename)) << "\n"; delete in; return false; } ImageSpec inspec = in->spec(); std::string metadatatime = inspec.get_string_attribute ("DateTime"); // Find an ImageIO plugin that can open the output file, and open it ImageOutput *out = ImageOutput::create (tempname.c_str()); if (! out) { std::cerr << "iconvert ERROR: Could not find an ImageIO plugin to write \"" << out_filename << "\" :" << geterror() << "\n"; delete in; return false; } // In order to deal with formats that support subimages, but not // subimage appending, we gather them all first. std::vector<ImageSpec> subimagespecs; if (out->supports("multiimage") && !out->supports("appendsubimage")) { ImageCache *imagecache = ImageCache::create (); int nsubimages = 0; ustring ufilename (in_filename); imagecache->get_image_info (ufilename, 0, 0, ustring("subimages"), TypeDesc::TypeInt, &nsubimages); if (nsubimages > 1) { subimagespecs.resize (nsubimages); for (int i = 0; i < nsubimages; ++i) { ImageSpec inspec = *imagecache->imagespec (ufilename, i, 0, true /*native*/); subimagespecs[i] = inspec; adjust_spec (in, out, inspec, subimagespecs[i]); } } ImageCache::destroy (imagecache); } bool ok = true; bool mip_to_subimage_warning = false; for (int subimage = 0; ok && in->seek_subimage(subimage,0,inspec); ++subimage) { if (subimage > 0 && !out->supports ("multiimage")) { std::cerr << "iconvert WARNING: " << out->format_name() << " does not support multiple subimages.\n"; std::cerr << "\tOnly the first subimage has been copied.\n"; break; // we're done } int miplevel = 0; do { // Copy the spec, with possible change in format ImageSpec outspec = inspec; bool nocopy = adjust_spec (in, out, inspec, outspec); if (miplevel > 0) { // Moving to next MIP level ImageOutput::OpenMode mode; if (out->supports ("mipmap")) mode = ImageOutput::AppendMIPLevel; else if (out->supports ("multiimage") && out->supports ("appendsubimage")) { mode = ImageOutput::AppendSubimage; // use if we must if (! mip_to_subimage_warning && strcmp(out->format_name(),"tiff")) { std::cerr << "iconvert WARNING: " << out->format_name() << " does not support MIPmaps.\n"; std::cerr << "\tStoring the MIPmap levels in subimages.\n"; } mip_to_subimage_warning = true; } else { std::cerr << "iconvert WARNING: " << out->format_name() << " does not support MIPmaps.\n"; std::cerr << "\tOnly the first level has been copied.\n"; break; // on to the next subimage } ok = out->open (tempname.c_str(), outspec, mode); } else if (subimage > 0) { // Moving to next subimage ok = out->open (tempname.c_str(), outspec, ImageOutput::AppendSubimage); } else { // First time opening if (subimagespecs.size()) ok = out->open (tempname.c_str(), int(subimagespecs.size()), &subimagespecs[0]); else ok = out->open (tempname.c_str(), outspec, ImageOutput::Create); } if (! ok) { std::string err = out->geterror(); std::cerr << "iconvert ERROR: " << (err.length() ? err : Strutil::format("Could not open \"%s\"", out_filename)) << "\n"; ok = false; break; } if (! nocopy) { ok = out->copy_image (in); if (! ok) std::cerr << "iconvert ERROR copying \"" << in_filename << "\" to \"" << out_filename << "\" :\n\t" << out->geterror() << "\n"; } else { // Need to do it by hand for some reason. Future expansion in which // only a subset of channels are copied, or some such. std::vector<char> pixels ((size_t)outspec.image_bytes(true)); ok = in->read_image (outspec.format, &pixels[0]); if (! ok) { std::cerr << "iconvert ERROR reading \"" << in_filename << "\" : " << in->geterror() << "\n"; } else { ok = out->write_image (outspec.format, &pixels[0]); if (! ok) std::cerr << "iconvert ERROR writing \"" << out_filename << "\" : " << out->geterror() << "\n"; } } ++miplevel; } while (ok && in->seek_subimage(subimage,miplevel,inspec)); } out->close (); delete out; in->close (); delete in; // Figure out a time for the input file -- either one supplied by // the metadata, or the actual time stamp of the input file. std::time_t in_time; if (metadatatime.empty() || ! DateTime_to_time_t (metadatatime.c_str(), in_time)) in_time = Filesystem::last_write_time (in_filename); if (out_filename != tempname) { if (ok) { Filesystem::remove (out_filename); Filesystem::rename (tempname, out_filename); } else Filesystem::remove (tempname); } // If user requested, try to adjust the file's modification time to // the creation time indicated by the file's DateTime metadata. if (ok && adjust_time) Filesystem::last_write_time (out_filename, in_time); return ok; }
// Function to write an image using OpenImageIO that reads and stores the pixel bein g displayed on screen using OpenGL void writeImage() { // Store the Output File Type in outfiletype, example .ppm or .jpg string outfiletype = outfilename.substr(outfilename.find(".")); // Create ImageOutput instance using the outfilename & exit if error in creating ImageOutput *out = ImageOutput::create(outfilename); if (!out) { cerr << "Could not create an ImageOutput for " << outfilename << "\nError: " << geterror()<<endl; exit(-1); } // Set outputchannels to 3 if outputfiletype is either ppm/pnm/pgm/pbm/hdr/rgbe else let it be equal to the number of channels of the input image (either 3 or 4) int outputchannels = (outfiletype==".ppm" || outfiletype==".pnm" || outfiletype==".pgm" || outfiletype==".pbm" || outfiletype==".hdr" || outfiletype==".rgbe" ? 3 : channels1 ); // Allocate memory based on the number of channels unsigned char *oiio_pixels = new unsigned char[xresWarped*yresWarped*outputchannels]; // Check if memory has been allocated successfully if (oiio_pixels==0) { // Memory not allocated successfully! Display message and Exit cout<<"Couldn't allocate memory. Exiting!"<<endl; exit(-1); delete out; } // If number of channels is 4 then read in RGBA format using GL_RGBA if(outputchannels==4) { for(int i=0, k=0; i<yresWarped && k<(xresWarped*yresWarped*outputchannels); i++) { for(int j=0; j<xresWarped; j++, k+=4) { oiio_pixels[k] = pixmapWarped[i][j].red; oiio_pixels[k+1] = pixmapWarped[i][j].green; oiio_pixels[k+2] = pixmapWarped[i][j].blue; oiio_pixels[k+3] = pixmapWarped[i][j].alpha; } } } // If number of channels is 3 then read in RGB format using GL_RGB else if(outputchannels==3) { for(int i=0, k=0; i<yresWarped && k<(xresWarped*yresWarped*outputchannels); i++) { for(int j=0; j<xresWarped; j++, k+=3) { oiio_pixels[k] = pixmapWarped[i][j].red; oiio_pixels[k+1] = pixmapWarped[i][j].green; oiio_pixels[k+2] = pixmapWarped[i][j].blue; } } } // Create ImageSpec for the output image with name outfile ImageSpec spec(xresWarped,yresWarped,outputchannels,TypeDesc::UINT8); if (! out->open (outfilename, spec)) { cerr << "Could not open " << outfilename << "\nError: " << out->geterror()<< endl; delete out; delete [] oiio_pixels; exit(-1); } // This particular call to write flips the image for us int scanlinesize = xresWarped * outputchannels * sizeof(oiio_pixels[0]); if(! out->write_image (TypeDesc::UINT8, (unsigned char*)oiio_pixels+(yresWarped-1)*scanlinesize, AutoStride, -scanlinesize, AutoStride)) { cerr << "Could not write pixels to " << outfilename << "\nError: " << out->geterror()<< endl; delete out; delete [] oiio_pixels; exit(-1); } // Close the output file if(! out->close ()) { std::cerr << "Error closing " << outfilename << "\nError: " << out->geterror() << endl; delete out; delete [] oiio_pixels; exit(-1); } delete out; delete [] oiio_pixels; }
OIIO_NAMESPACE_USING #include <algorithm> #include "Perlin.h" int main(int argc, char* argv[]) { try { options_description desc("Allowed options"); desc.add_options() ("help,h", "produce help message") ("xres,x", value<int>()->default_value(255), "x resolution") ("yres,y", value<int>()->default_value(255), "y resolution") ("sample-size,s", value<int>()->default_value(256), "sample size") ("seed,r", value<int>()->default_value(0), "psuedo-random seed") ("persistence,p", value<float>()->default_value(0.5f), "persistence value") ("octaves,o", value<int>()->default_value(2), "number of octaves") ; options_description hidden("Hidden options"); hidden.add_options() ("output-file", value<string>()->required(), "output file") ; options_description all("Allowed options"); all.add(desc).add(hidden); positional_options_description p; p.add("output-file", 1); variables_map vm; store(command_line_parser(argc, argv).options(all) .positional(p).run(), vm); if (vm.count("help")) { cout << "Usage: " << argv[0] << " [options] output-file" << endl; cout << desc << endl; return 0; } notify(vm); string outputfile = vm["output-file"].as<string>(); ImageOutput* out = ImageOutput::create(outputfile); if (!out) { cerr << "Could not create an ImageOutput for " << outputfile << ", error = " << OpenImageIO::geterror() << endl; return 0; } const int xres = vm["xres"].as<int>(); const int yres = vm["yres"].as<int>(); const int channels = 3; // RGB ImageSpec outspec(xres, yres, channels, TypeDesc::UINT8); if (!out->open(outputfile, outspec)) { cerr << "Could not open " << outputfile << ", error = " << out->geterror() << endl; ImageOutput::destroy(out); return 0; } const int sample_size = vm["sample-size"].as<int>(); const int seed = vm["seed"].as<int>(); Perlin perlin(sample_size, seed); float persistence = vm["persistence"].as<float>(); int octaves = vm["octaves"].as<int>(); unsigned char pixels[xres * yres * channels]; for (int y = 0; y < yres; y++) { for (int x = 0; x < xres; x++) { float frequency, amplitude; float total = 0.0f; for (int i = 1; i <= octaves; ++i) { frequency = pow(2.0f, i); amplitude = pow(persistence, i); total += (perlin.Noise2(frequency * x / sample_size, frequency * y / sample_size) + 1)/ 2.0f * amplitude; } total = min<float>(1.0f, max<float>(0.0f, total)); unsigned int noise = (unsigned int) (total * 255); pixels[y * xres * channels + x * channels] = noise; pixels[y * xres * channels + x * channels + 1] = noise; pixels[y * xres * channels + x * channels + 2] = noise; } } if (!out->write_image(TypeDesc::UINT8, pixels)) { cerr << "Could not write pixels to " << outputfile << ", error = " << out->geterror() << endl; ImageOutput::destroy(out); return 0; } ImageOutput::destroy(out); } catch (exception& e) { cerr << e.what() << endl; } }