예제 #1
0
void image_node_renderer_t::render( const Imath::Box2i& roi)
{
	RAMEN_ASSERT( has_context_);
	RAMEN_ASSERT( !roi.isEmpty());

    n_->set_interest( roi);
    breadth_first_inputs_apply( *n_, boost::bind( &image_node_t::calc_inputs_interest_fun, _1, new_context_));
    depth_first_inputs_search(  *n_, boost::bind( &image_node_t::calc_defined_fun, _1, new_context_));
    depth_first_inputs_search(  *n_, boost::bind( &image_node_t::subsample_areas_fun, _1, new_context_));

    if( do_log)
        depth_first_inputs_search( *n_, test_empty_images());

    depth_first_inputs_search( *n_, boost::bind( &node_t::clear_hash, _1));
    depth_first_inputs_search( *n_, boost::bind( &node_t::calc_hash_str, _1, new_context_));

    if( do_log)
        depth_first_inputs_search( *n_, print_areas());

	try
	{
	    n_->recursive_process( new_context_);
		render_done_ = true;
	}
	catch( std::bad_alloc&)
	{
		throw boost::enable_error_info( std::bad_alloc());
	}
}
예제 #2
0
AcesOutputFile::AcesOutputFile
    (const std::string &name,
     const Imath::Box2i &displayWindow,
     const Imath::Box2i &dataWindow,
     RgbaChannels rgbaChannels,
     float pixelAspectRatio,
     const Imath::V2f screenWindowCenter,
     float screenWindowWidth,
     LineOrder lineOrder,
     Compression compression,
     int numThreads)
:
    _data (new Data)
{
    checkCompression (compression);

    Header newHeader (displayWindow,
		      dataWindow.isEmpty()? displayWindow: dataWindow,
		      pixelAspectRatio,
		      screenWindowCenter,
		      screenWindowWidth,
		      lineOrder,
		      compression);

    addChromaticities (newHeader, acesChromaticities());
    addAdoptedNeutral (newHeader, acesChromaticities().white);

    _data->rgbaFile = new RgbaOutputFile (name.c_str(),
					  newHeader,
					  rgbaChannels,
					  numThreads);

    _data->rgbaFile->setYCRounding (7, 6);
}
예제 #3
0
void exposure_node_t::do_process( const image::const_image_view_t& src, const image::image_view_t& dst, const render::render_context_t& context)
{
    image::const_image_view_t src_view;
    image::image_view_t dst_view;
    Imath::Box2i area;

    if( input(1))
    {
	boost::gil::copy_pixels( src, dst);
	area = intersect( input(1)->defined(), defined());

	if( area.isEmpty())
	    return;

	src_view = input(0)->const_subimage_view( area);
	dst_view = subimage_view( area);
    }
    else
    {
	src_view = src;
	dst_view = dst;
    }

    boost::gil::tbb_transform_pixels( src_view, dst_view, exposure_fun( get_value<float>( param( "exp"))));

    if( input(1))
        image::key_mix( src_view, dst_view, boost::gil::nth_channel_view( input(1)->const_subimage_view( area), 3), dst_view);
}
예제 #4
0
TiledRgbaOutputFile::TiledRgbaOutputFile
    (const char name[],
     int tileXSize,
     int tileYSize,
     LevelMode mode,
     LevelRoundingMode rmode,
     const Imath::Box2i &displayWindow,
     const Imath::Box2i &dataWindow,
     RgbaChannels rgbaChannels,
     float pixelAspectRatio,
     const Imath::V2f screenWindowCenter,
     float screenWindowWidth,
     LineOrder lineOrder,
     Compression compression,
     int numThreads)
:
    _outputFile (0),
    _toYa (0)
{
    Header hd (displayWindow,
	       dataWindow.isEmpty()? displayWindow: dataWindow,
	       pixelAspectRatio,
	       screenWindowCenter,
	       screenWindowWidth,
	       lineOrder,
	       compression);

    insertChannels (hd, rgbaChannels, name);
    hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode));
    _outputFile = new TiledOutputFile (name, hd, numThreads);

    if (rgbaChannels & WRITE_Y)
	_toYa = new ToYa (*_outputFile, rgbaChannels);
}
예제 #5
0
RgbaOutputFile::RgbaOutputFile (const char name[],
				const Imath::Box2i &displayWindow,
				const Imath::Box2i &dataWindow,
				RgbaChannels rgbaChannels,
				float pixelAspectRatio,
				const Imath::V2f screenWindowCenter,
				float screenWindowWidth,
				LineOrder lineOrder,
				Compression compression):
    _outputFile (0)
{
    Header hd (displayWindow,
	       dataWindow.isEmpty()? displayWindow: dataWindow,
	       pixelAspectRatio,
	       screenWindowCenter,
	       screenWindowWidth,
	       lineOrder,
	       compression);

    ChannelList ch;

    if (rgbaChannels & WRITE_R)
	ch.insert ("R", Channel (HALF, 1, 1));
    if (rgbaChannels & WRITE_G)
	ch.insert ("G", Channel (HALF, 1, 1));
    if (rgbaChannels & WRITE_B)
	ch.insert ("B", Channel (HALF, 1, 1));
    if (rgbaChannels & WRITE_A)
	ch.insert ("A", Channel (HALF, 1, 1));

    hd.channels() = ch;
    _outputFile = new OutputFile (name, hd);
}
예제 #6
0
파일: flipbook.cpp 프로젝트: kmac5/ramen
void flipbook_t::set_format( const Imath::Box2i& f, float aspect, int subsample)
{
    RAMEN_ASSERT( !f.isEmpty());

    format_ = ImathExt::scale( f, 1.0f / subsample);
    buffer_ = image::buffer_t( format_, 4);
    aspect_ = aspect;
}
예제 #7
0
void expand_node_t::do_process( const render::context_t& context)
{
    Imath::Box2i area = ImathExt::intersect( input_as<image_node_t>()->defined(), defined());

    if( area.isEmpty())
        return;

    boost::gil::copy_pixels( input_as<image_node_t>()->const_subimage_view( area), subimage_view( area));
}
예제 #8
0
파일: crop_node.cpp 프로젝트: apextw/Ramen
void crop_node_t::do_process( const render::render_context_t& context)
{
    Imath::Box2i area = intersect( input()->defined(), defined());

    if( area.isEmpty())
	return;

    boost::gil::copy_pixels( input()->const_subimage_view( area), subimage_view( area));
}
예제 #9
0
void copy_channels_node_t::do_calc_bounds( const render::render_context_t& context)
{
    Imath::Box2i rod1 = input(0)->bounds();
    Imath::Box2i rod2 = input(1)->bounds();

    int ch_r = get_value<int>( param( "red"));
    int ch_g = get_value<int>( param( "green"));
    int ch_b = get_value<int>( param( "blue"));
    int ch_a = get_value<int>( param( "alpha"));

    // use alpha from input 1
    if( ch_a == copy_source)
    {
	set_bounds( rod1);
	return;
    }

    // alpha comes from input2
    if( ch_a != set_one && ch_a != set_zero)
    {
	set_bounds( rod2);
	return;
    }

    // alpha is zero or one, look at the other channels
    Imath::Box2i rod;

    if( ch_r == copy_source)
	rod = rod1;
    else
    {
	if( ch_r != set_zero && ch_r != set_one)
	    rod = rod2;
    }

    if( ch_g == copy_source)
	rod.extendBy( rod1);
    else
    {
	if( ch_g != set_zero && ch_r != set_one)
	    rod.extendBy( rod2);
    }

    if( ch_b == copy_source)
	rod.extendBy( rod1);
    else
    {
	if( ch_b != set_zero && ch_r != set_one)
	    rod.extendBy( rod2);
    }

    if( rod.isEmpty())
	rod = rod1;

    set_bounds( rod);
}
예제 #10
0
void copy_channels_node_t::do_calc_defined( const render::render_context_t& context)
{
    Imath::Box2i def1 = input(0)->defined();
    Imath::Box2i def2 = input(1)->defined();

    int ch_r = get_value<int>( param( "red"));
    int ch_g = get_value<int>( param( "green"));
    int ch_b = get_value<int>( param( "blue"));
    int ch_a = get_value<int>( param( "alpha"));

    // use alpha from input 1
    if( ch_a == copy_source)
    {
	set_defined( def1);
	return;
    }

    // alpha comes from input2
    if( ch_a != set_one && ch_a != set_zero)
    {
	set_defined( def2);
	return;
    }

    // alpha is zero or one, look at the other channels
    Imath::Box2i def;

    if( ch_r == copy_source)
	def = def1;
    else
    {
	if( ch_r != set_zero && ch_r != set_one)
	    def = def2;
    }

    if( ch_g == copy_source)
	def.extendBy( def1);
    else
    {
	if( ch_g != set_zero && ch_r != set_one)
	    def.extendBy( def2);
    }

    if( ch_b == copy_source)
	def.extendBy( def1);
    else
    {
	if( ch_b != set_zero && ch_r != set_one)
	    def.extendBy( def2);
    }

    if( def.isEmpty())
	def = def1;

    set_defined( def);
}
예제 #11
0
파일: clip.cpp 프로젝트: JohanAberg/Ramen
image_t *clip_t::get_output_image( OfxTime time, OfxRectD *optionalBounds)
{
    RAMEN_ASSERT( node());
    RAMEN_ASSERT( node()->composition());
    RAMEN_ASSERT( !node()->image_empty());
    RAMEN_ASSERT( time == node()->composition()->frame());
    RAMEN_ASSERT( getComponents() == kOfxImageComponentRGBA);
    RAMEN_ASSERT( getPixelDepth() == kOfxBitDepthFloat);

    Imath::Box2i area;

    if( optionalBounds)
    {
        area = Imath::Box2i( Imath::V2i( optionalBounds->x1, optionalBounds->y1), Imath::V2i( optionalBounds->x2 - 1, optionalBounds->y2 - 1));
        area = Imath::scale( area, 1.0f / node()->render_context().subsample);
        area = node()->vertical_flip( area);
    }
    else
        area = node()->defined();

    if( area.isEmpty())
    {
#ifndef NDEBUG
        DLOG( INFO) << "clip_t::getOutputImage, node = " << node()->name() << ", area == empty";
#endif

        return 0;
    }

    image::const_image_view_t view( node()->const_subimage_view( area));

    int rowbytes;
    void *ptr = view_get_ptr_and_stride( view, rowbytes);

    // convert to OFX coordinate sys
    area = node()->vertical_flip( area);

    OfxRectI bounds;
    bounds.x1 = area.min.x;
    bounds.y1 = area.min.y;
    bounds.x2 = area.max.x + 1;
    bounds.y2 = area.max.y + 1;

#ifndef NDEBUG
    DLOG( INFO) << "clip_t::getOutputImage, node = " << node()->name();
#endif

    return new image_t( *this, node()->image(), 1.0 / node()->render_context().subsample, ptr, bounds, bounds, rowbytes, std::string( ""));
}
예제 #12
0
void set_matte_node_t::do_process( const render::context_t& context)
{
    if( defined().isEmpty())
	return;

    boost::gil::tbb_transform_pixels( input_as<image_node_t>( 0)->const_subimage_view( defined()), image_view(),
					  copy_rgb_and_clear_alpha());

    Imath::Box2i area = ImathExt::intersect( defined(), input_as<image_node_t>( 1)->defined());

    if( !area.isEmpty())
	boost::gil::tbb_copy_pixels( boost::gil::nth_channel_view( input_as<image_node_t>( 1)->const_subimage_view( area), 3),
					    boost::gil::nth_channel_view( subimage_view( area), 3));

    if( get_value<bool>( param( "premultiply")))
	image::premultiply( image_view(), image_view());
}
예제 #13
0
void keyer_node_t::sample_input( const Imath::Box2i& area, std::vector<Imath::Color3f>& colors) const
{
	if( input_pixels_.empty())
		return;

	Imath::Box2i subarea = Imath::intersect( area, input_data_window_);

	if( subarea.isEmpty())
		return;

	Imath::V2i p;
	
	for( p.y = subarea.min.y; p.y <= subarea.max.y; ++p.y)
	{
		for( p.x = subarea.min.x; p.x <= subarea.max.x; ++p.x)
		{
			image::pixel_t px( input_pixels_.const_rgba_view()( p.x - input_data_window_.min.x, p.y - input_data_window_.min.y));
			colors.push_back( Imath::Color3f( boost::gil::get_color( px, boost::gil::red_t()),
											   boost::gil::get_color( px, boost::gil::green_t()),
											   boost::gil::get_color( px, boost::gil::blue_t())));
		}
	}
}
예제 #14
0
파일: clip.cpp 프로젝트: JohanAberg/Ramen
image_t *clip_t::get_input_image( OfxTime time, OfxRectD *optionalBounds)
{
    RAMEN_ASSERT( node());
    RAMEN_ASSERT( node()->composition());
    RAMEN_ASSERT( port_ != -1);
    RAMEN_ASSERT( getPixelDepth() == kOfxBitDepthFloat);

    image_node_t *in = node()->input_as<image_node_t>( port());

    if( !in)
    {
#ifndef NDEBUG
        DLOG( INFO) << "clip_t::getImage, node = " << node()->name() << ", port = " << port() << ", result = 0";
#endif

        return 0;
    }

    render::context_t context = node()->render_context();
    context.composition = node()->composition();
    context.result_node = in;
    context.frame = time;

    render::context_guard_t guard( node()->composition()->current_context(), in);
    render::image_node_renderer_t r( context);

    Imath::Box2i area;

    if( optionalBounds)
    {
        // TODO: is this correct if the effect does not support tiles?
        area = Imath::Box2i( Imath::V2i( optionalBounds->x1, optionalBounds->y1), Imath::V2i( optionalBounds->x2 - 1, optionalBounds->y2 - 1));
        area = node()->vertical_flip( area);
        r.render( area);

        area.min.x = optionalBounds->x1;
        area.min.y = optionalBounds->y1;
        area.max.x = optionalBounds->x2 - 1;
        area.max.y = optionalBounds->y2 - 1;
        area = node()->vertical_flip( area);
        area = intersect( in->defined(), area);
    }
    else
    {
        r.render();
        area = in->defined();
    }

    if( area.isEmpty())
    {
#ifndef NDEBUG
        DLOG( INFO) << "clip_t::getImage, node = " << node()->name() << ", port = " << port() << ", area == empty";
#endif

        return 0;
    }

    image::buffer_t pixels = in->image();
    image::const_image_view_t view( in->const_subimage_view( area));

    area = node()->vertical_flip( area);

    OfxRectI bounds;
    bounds.x1 = area.min.x;
    bounds.y1 = area.min.y;
    bounds.x2 = area.max.x + 1;
    bounds.y2 = area.max.y + 1;

    std::stringstream s;
    for( int i = 0; i < 16; ++i)
        s << (int) in->digest()[i];


#ifndef NDEBUG
    if( optionalBounds)
        DLOG( INFO) << "clip_t::getImage, node = " << node()->name() << ", port = " << port() << ", bounds = " << *optionalBounds;
    else
        DLOG( INFO) << "clip_t::getImage, node = " << node()->name() << ", port = " << port();
#endif

    image_t *result = 0;

    if( getComponents() == kOfxImageComponentRGBA)
    {
        int rowbytes;
        void *ptr = view_get_ptr_and_stride( view, rowbytes);
        result = new image_t( *this, pixels, 1.0 / node()->render_context().subsample, ptr, bounds, bounds, rowbytes, s.str());
    }
    else
    {
        // TODO: create an gray scale image and copy the alpha channel
        RAMEN_ASSERT( 0);
    }

    in->release_image();
    return result;
}
예제 #15
0
파일: clip.cpp 프로젝트: JohanAberg/Ramen
OfxRectD clip_t::getRegionOfDefinition( OfxTime time) const
{
    RAMEN_ASSERT( node());

    const image_node_t *in = 0;
    bool use_default = false;
    bool restore_time = false;
    float saved_frame;

    // calling getRoD for the output clip does not make a lot of sense, but some plugins do...
    if( port_ == -1)
        in = node();
    else // normal case
        in = node()->input_as<const image_node_t>( port_);

    if( !in)
    {
        in = node();
        use_default = true;
    }

    if( node()->composition())
    {
        saved_frame = node()->composition()->frame();

        if( saved_frame != time)
        {
            restore_time = true;
            composition_t *c = const_cast<composition_t*>( node()->composition());
            c->set_frame( time);
        }
    }

    Imath::Box2i b;

    if( use_default)
    {
        for( int i = 0; i < in->num_inputs(); ++i)
        {
            if( const image_node_t *src = in->input_as<const image_node_t>( i))
                b.extendBy( src->bounds());
        }

        if( b.isEmpty())
        {
            if( in->composition())
                b = node()->composition()->default_format().area();
            else
                b = preferences_t::Instance().default_format().area();
        }
    }
    else
        b = in->bounds();

    b = node()->vertical_flip( b);

    OfxRectD v;
    v.x1 = b.min.x;
    v.y1 = b.min.y;
    v.x2 = b.max.x + 1;
    v.y2 = b.max.y + 1;

    if( restore_time)
    {
        composition_t *c = const_cast<composition_t*>( node()->composition());
        c->set_frame( saved_frame);
    }

#ifndef NDEBUG
    DLOG( INFO) << "clip_t::getRoD, node = " << node()->name() << ", port = " << port() << ", result = " << v;
#endif

    return v;
}
예제 #16
0
파일: clip.cpp 프로젝트: JohanAberg/Ramen
OFX::Host::ImageEffect::Image* clip_t::get_input_image( OfxTime time, OfxRectD *optionalBounds)
{
    assert( node());
    assert( node()->composition());

    node_t *in = node()->input( port());

    if( !in)
	return 0;

    render::render_context_t context = node()->render_context();

    context.composition = node()->composition();
    context.result_node = in;
    context.time = time;

    Imath::Box2i area;

    if( optionalBounds)
    {
        // TODO: is this correct if the effect does not support tiles?
	area = Imath::Box2i( Imath::V2i( optionalBounds->x1, optionalBounds->y1), Imath::V2i( optionalBounds->x2 - 1, optionalBounds->y2 - 1));
	area = node()->vertical_flip_box( area);
    }
    else
        area = scale( node()->defined(), context.subsample);

    render::renderer_t r( context, true, false);
    r.render( area);

    if( optionalBounds)
    {
	area.min.x = optionalBounds->x1;
	area.min.y = optionalBounds->y1;
	area.max.x = optionalBounds->x2 - 1;
	area.max.y = optionalBounds->y2 - 1;
	area = node()->vertical_flip_box( area);
	area = intersect( in->defined(), area);
    }
    else
	area = in->defined();

    if( area.isEmpty())
	return 0;

    image::image_buffer_t pixels = in->image();
    image::const_image_view_t view( in->const_subimage_view( area));

    int rowbytes;
    void *ptr = view_get_ptr_and_stride( view, rowbytes);

    area = node()->vertical_flip_box( area);

    OfxRectI bounds;
    bounds.x1 = area.min.x;
    bounds.y1 = area.min.y;
    bounds.x2 = area.max.x + 1;
    bounds.y2 = area.max.y + 1;

    std::stringstream s;
    for( int i = 0; i < 16; ++i)
	s << (int) in->digest()[i];

    input_image_t *result = new input_image_t( *this, pixels, 1.0 / node()->render_context().subsample, ptr, bounds, bounds, rowbytes, s.str());
    in->release_image();
    return result;
}