void colorx_node_t::do_process( const render::context_t& context) { if( !expr_.get() || !expr_->isValid()) { image::make_color_bars( image_view()); return; } Imath::Box2i area( Imath::intersect( input_as<image_node_t>()->defined(), defined())); if( area.isEmpty()) return; if( expr_->isThreadSafe()) // multi-threaded { tbb::parallel_for( tbb::blocked_range<int>( 0, area.size().y + 1), boost::bind( &colorx_node_t::do_expression, this, _1, area, boost::cref( context)), tbb::auto_partitioner()); } else { tbb::blocked_range<int> range( 0, area.size().y + 1); do_expression( range, area, context); } }
void blur_channels_node_t::blur_channel( int ch, const Imath::Box2i& area, const boost::gil::gray32f_view_t& tmp, const Imath::V2f& radius, int iters, blur_border_mode border) { if( border != border_black) { int hradius = std::ceil( radius.x); int vradius = std::ceil( radius.y); int border_x0 = std::min( area.min.x - defined().min.x, hradius); int border_y0 = std::min( area.min.y - defined().min.y, vradius); int border_x1 = std::min( defined().max.x - area.max.x, hradius); int border_y1 = std::min( defined().max.y - area.max.y, vradius); Imath::Box2i box( area); box.min.x -= border_x0; box.min.y -= border_y0; box.max.x += border_x1; box.max.y += border_y1; if( border == border_repeat) boost::gil::repeat_border_pixels( boost::gil::nth_channel_view( subimage_view( box), ch), border_x0, border_y0, border_x1, border_y1); else boost::gil::reflect_border_pixels( boost::gil::nth_channel_view( subimage_view( box), ch), border_x0, border_y0, border_x1, border_y1); } image::box_blur_channel( boost::gil::nth_channel_view( const_image_view(), ch), tmp, boost::gil::nth_channel_view( image_view(), ch), radius.x, radius.y, iters); }
void lens_distort_node_t::do_process( const render::context_t& context) { image_node_t *in = input_as<image_node_t>(); switch( get_value<int>( param( "model"))) { case syntheyes_model: { float k = get_value<float>( param( "synth_k")); float k3 = get_value<float>( param( "synth_k3")); if( get_value<int>( param( "mode")) == undistort) { if( k3 == 0) { camera::syntheyes_quadratic_undistort dist( k, in->format(), in->aspect_ratio()); if( get_value<int>( param( "filter")) == bilinear) image::warp_bilinear( in->defined(), in->const_image_view(), defined(), image_view(), dist, false, false); else image::warp_bicubic( in->defined(), in->const_image_view(), defined(), image_view(), dist, false, false); } else { camera::syntheyes_undistort dist( k, k3, in->format(), in->aspect_ratio()); if( get_value<int>( param( "filter")) == bilinear) image::warp_bilinear( in->defined(), in->const_image_view(), defined(), image_view(), dist, false, false); else image::warp_bicubic( in->defined(), in->const_image_view(), defined(), image_view(), dist, false, false); } } else { if( k3 == 0) { camera::syntheyes_quadratic_redistort dist( k, in->format(), in->aspect_ratio()); if( get_value<int>( param( "filter")) == bilinear) image::warp_bilinear( in->defined(), in->const_image_view(), defined(), image_view(), dist, false, false); else image::warp_bicubic( in->defined(), in->const_image_view(), defined(), image_view(), dist, false, false); } else { camera::syntheyes_redistort dist( k, k3, in->format(), in->aspect_ratio()); if( get_value<int>( param( "filter")) == bilinear) image::warp_bilinear( in->defined(), in->const_image_view(), defined(), image_view(), dist, false, false); else image::warp_bicubic( in->defined(), in->const_image_view(), defined(), image_view(), dist, false, false); } } } break; }; }
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()); }
void flip_node_t::do_process( const render::context_t& context) { if( defined().isEmpty()) return; calc_transform_matrix(); image::affine_warp_nearest( input_as<image_node_t>()->defined(), input_as<image_node_t>()->const_image_view(), defined(), image_view(), xform_, inv_xform_); }
void distortx_node_t::do_process( const render::context_t& context) { if( !expr_.get() || !expr_->isValid()) { image::make_color_bars( image_view()); return; } bool thread_safe = true; // while testing //bool thread_safe = expr_->isThreadSafe(); std::string warp_expr = get_value<std::string>( param( expr_param_name())); Imath::V2f amp( get_value<Imath::V2f>( param( "amplitude"))); amp /= context.subsample; se_expr_warp_fun f( this, warp_expr, amp, context); image_node_t *in = input_as<image_node_t>( 0); image_node_t *msk = input_as<image_node_t>( 1); if( msk) { mask_fun m( msk->const_image_view(), msk->defined()); masked_warp_fun<se_expr_warp_fun, mask_fun> mf( f, m); switch( get_value<int>( param( "borders"))) { case border_black: image::warp_bilinear( in->defined(), in->const_image_view(), defined(), image_view(), mf, false, thread_safe); break; case border_tile: image::warp_bilinear_tile( in->defined(), in->const_image_view(), defined(), image_view(), mf, false, thread_safe); break; case border_mirror: image::warp_bilinear_mirror( in->defined(), in->const_image_view(), defined(), image_view(), mf, false, thread_safe); break; } } else { switch( get_value<int>( param( "borders"))) { case border_black: image::warp_bilinear( in->defined(), in->const_image_view(), defined(), image_view(), f, false, thread_safe); break; case border_tile: image::warp_bilinear_tile( in->defined(), in->const_image_view(), defined(), image_view(), f, false, thread_safe); break; case border_mirror: image::warp_bilinear_mirror( in->defined(), in->const_image_view(), defined(), image_view(), f, false, thread_safe); break; } } }
// draw_view static void draw_view(image_view const& vw, wx_window * wxwin) { // create paint DC wxPaintDC dc(wxwin->win); // clip view if neccessary int w = vw.width(), h = vw.height(); image_view sub_vw; // clip view if (wxwin->is_toplevel) { sub_vw = vw; } else { if (wx_window * parent = static_cast<wx_window *>(wxwin->parent)) { w = std::min(w, parent->width - wxwin->x); h = std::min(h, parent->height - wxwin->y); } int tlx = 0, tly = 0; if (wxwin->x < 0) { tlx += -wxwin->x; w -= -wxwin->x; } if (wxwin->y < 0) { tly += -wxwin->y; w -= -wxwin->y; } sub_vw = image_view(w, h, vw.xy_at(tlx, tly)); } // FIXME: too slow // copy into wxBitmap wxImage wximg(sub_vw.width(), sub_vw.height()); boost::gil::copy_pixels( sub_vw, boost::gil::interleaved_view( wximg.GetWidth(), wximg.GetHeight(), (boost::gil::rgb8_pixel_t *) wximg.GetData(), wximg.GetWidth() * 3 ) ); wxBitmap bmp(wximg); // draw onto the screen dc.DrawBitmap(bmp, 0, 0, false); }
void invert_node_t::do_process( const render::context_t& context) { Imath::Box2i area( Imath::intersect( input_as<image_node_t>()->defined(), defined())); if( area.isEmpty()) return; if( get_value<int>( param( "channels"))) boost::gil::fill_pixels( image_view(), image::pixel_t( 0, 0, 0, 1)); do_process( input_as<image_node_t>()->const_subimage_view( area), subimage_view( area), context); }
void blur_channels_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; int iters = get_value<float>( param( "iters")); Imath::V2f r_radius = get_value<Imath::V2f>( param( "r_radius")) / iters; Imath::V2f g_radius = get_value<Imath::V2f>( param( "g_radius")) / iters; Imath::V2f b_radius = get_value<Imath::V2f>( param( "b_radius")) / iters; Imath::V2f a_radius = get_value<Imath::V2f>( param( "a_radius")) / iters; r_radius = adjust_blur_size( r_radius, context.subsample); g_radius = adjust_blur_size( g_radius, context.subsample); b_radius = adjust_blur_size( b_radius, context.subsample); a_radius = adjust_blur_size( a_radius, context.subsample); boost::gil::copy_pixels( input_as<image_node_t>()->const_subimage_view( area), subimage_view( area)); image::buffer_t buffer( image_view().height(), image_view().width(), 1); image::gray_image_view_t tmp = buffer.gray_view(); blur_border_mode bmode = ( blur_border_mode) get_value<int>( param( "border")); boost::gil::fill_pixels( tmp, 0.0f); blur_channel( 0, area, tmp, r_radius, iters, bmode); boost::gil::fill_pixels( tmp, 0.0f); blur_channel( 1, area, tmp, g_radius, iters, bmode); boost::gil::fill_pixels( tmp, 0.0f); blur_channel( 2, area, tmp, b_radius, iters, bmode); boost::gil::fill_pixels( tmp, 0.0f); blur_channel( 3, area, tmp, a_radius, iters, bmode); }
void blur_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)); int bmode = get_value<int>( param( "border")); if( bmode != border_black) { int border_x0 = area.min.x - defined().min.x; int border_y0 = area.min.y - defined().min.y; int border_x1 = defined().max.x - area.max.x; int border_y1 = defined().max.y - area.max.y; if( bmode == border_repeat) boost::gil::repeat_border_pixels( image_view(), border_x0, border_y0, border_x1, border_y1); else boost::gil::reflect_border_pixels( image_view(), border_x0, border_y0, border_x1, border_y1); } int channels = get_value<int>( param( "channels")); Imath::V2f radius = get_value<Imath::V2f>( param( "radius")); int iters = get_value<int>( param( "iters")); radius.x /= context.subsample; radius.y /= context.subsample; switch( channels) { case channels_rgba: image::box_blur_rgba( const_image_view(), image_view(), radius.x, radius.y, iters); break; case channels_rgb: { image::box_blur_rgba( const_image_view(), image_view(), radius.x, radius.y, iters); boost::gil::fill_pixels( boost::gil::nth_channel_view( image_view(), 3), boost::gil::gray32f_pixel_t( 0)); boost::gil::copy_pixels( boost::gil::nth_channel_view( input()->const_subimage_view( area), 3), boost::gil::nth_channel_view( subimage_view( area), 3)); } break; case channels_alpha: { image::box_blur_channel( boost::gil::nth_channel_view( const_image_view(), 3), boost::gil::nth_channel_view( image_view(), 3), radius.x, radius.y, iters); } break; } }
void grid_node_t::do_process( const render::context_t& context) { Imath::Color4f color( get_value<Imath::Color4f>( param( "bgcol"))); boost::gil::fill_pixels( image_view(), image::pixel_t( color.r, color.g, color.b, color.a)); Imath::V2f size( get_absolute_value<Imath::V2f>( param( "size"))); Imath::V2f translate( get_absolute_value<Imath::V2f>( param( "translate"))); Imath::V2f line_width( get_absolute_value<Imath::V2f>( param( "linewidth"))); color = get_value<Imath::Color4f>( param( "fgcol")); // adjust params size.x = size.x / context.subsample / aspect_ratio(); size.y /= context.subsample; if( size.x == 0 || size.y == 0) return; translate.x = translate.x / context.subsample / aspect_ratio(); translate.y /= context.subsample; line_width.x = line_width.x / context.subsample / aspect_ratio(); line_width.y /= context.subsample; if( line_width.x == 0 || line_width.y == 0) return; // setup agg typedef image::agg_rgba32f_renderer_t ren_base_type; typedef ren_base_type::color_type color_type; typedef agg::renderer_scanline_aa_solid<ren_base_type> renderer_type; ren_base_type ren_base( image_view()); renderer_type ren( ren_base); agg::rasterizer_scanline_aa<> ras; ras.gamma( agg::gamma_none()); agg::scanline_u8 sl; ras.reset(); agg::path_storage path; agg::conv_stroke<agg::path_storage> stroke_conv( path); // Vertical stroke_conv.width( line_width.x); int w = image_view().width(); int h = image_view().height(); Imath::Box2f area( defined().min - translate, defined().max - translate); float x = Imath::Math<float>::floor( area.min.x / size.x) * size.x; for( ; x < area.max.x + line_width.x; x += size.x) { path.move_to( x - area.min.x, 0); path.line_to( x - area.min.x, h); } ras.add_path( stroke_conv); ren.color( image::pixel_t( color.r, color.g, color.b, color.a)); agg::render_scanlines( ras, sl, ren); // Horizontal path.remove_all(); stroke_conv.width( line_width.y); float y = Imath::Math<float>::floor( area.min.y / size.y) * size.y; for( ; y < area.max.y + line_width.y; y += size.y) { path.move_to( 0, y - area.min.y); path.line_to( w, y - area.min.y); } ras.add_path( stroke_conv); ren.color( image::pixel_t( color.r, color.g, color.b, color.a)); agg::render_scanlines( ras, sl, ren); }
// buffer related functions ONLY manipulate the buffer static void set_buffer_view(wx_window * win) { win->buffer = image_view( win->width, win->height, boost::gil::view(*win->buff_impl).xy_at(win->tlx, win->tly) ); }
static void draw_view(image_view const& vw, msw_window * mswwin) { // create dc HDC hdc = ::GetDC(mswwin->handle); // clip view int w = vw.width(), h = vw.height(); image_view sub_vw; // clip view if (mswwin->is_toplevel) { sub_vw = vw; } else { if (msw_window * parent = static_cast<msw_window *>(mswwin->parent)) { w = std::min(w, parent->width - mswwin->x); h = std::min(h, parent->height - mswwin->y); } int tlx = 0, tly = 0; if (mswwin->x < 0) { tlx += -mswwin->x; w -= -mswwin->x; } if (mswwin->y < 0) { tly += -mswwin->y; w -= -mswwin->y; } sub_vw = image_view(w, h, vw.xy_at(tlx, tly)); } // create the BITMAPINFO structure BITMAPINFO bmi; memset(&bmi, 0, sizeof(BITMAPINFO)); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = sub_vw.width(); bmi.bmiHeader.biHeight = sub_vw.height(); bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 24; bmi.bmiHeader.biCompression = BI_RGB; // draw view ::StretchDIBits( hdc, 0, 0, sub_vw.width(), sub_vw.height(), 0, 0, sub_vw.width(), sub_vw.height(), boost::gil::interleaved_view_get_raw_data(sub_vw), &bmi, DIB_RGB_COLORS, SRCCOPY ); ::ReleaseDC(mswwin->handle, hdc); }