Beispiel #1
0
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;
}
Beispiel #2
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);
    }

}
Beispiel #3
0
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;
}
Beispiel #4
0
// 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;
}
Beispiel #5
0
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;
	}
}