void BC_Xfer::init( uint8_t **output_rows, int out_colormodel, int out_x, int out_y, int out_w, int out_h, uint8_t *out_yp, uint8_t *out_up, uint8_t *out_vp, uint8_t *out_ap, int out_rowspan, uint8_t **input_rows, int in_colormodel, int in_x, int in_y, int in_w, int in_h, uint8_t *in_yp, uint8_t *in_up, uint8_t *in_vp, uint8_t *in_ap, int in_rowspan, int bg_color) { this->bg_color = bg_color; if( bg_color >= 0 ) { this->bg_r = (bg_color>>16) & 0xff; this->bg_g = (bg_color>>8) & 0xff; this->bg_b = (bg_color>>0) & 0xff; } else { // bg_color < 0, no src blending switch( in_colormodel ) { case BC_RGBA8888: in_colormodel = BC_RGBX8888; break; case BC_RGBA16161616: in_colormodel = BC_RGBX16161616; break; case BC_YUVA8888: in_colormodel = BC_YUVX8888; break; case BC_YUVA16161616: in_colormodel = BC_YUVX16161616; break; case BC_RGBA_FLOAT: in_colormodel = BC_RGBX_FLOAT; break; } } // prevent bounds errors on poorly dimensioned macro pixel formats switch( in_colormodel ) { case BC_UVY422: case BC_YUV422: in_w &= ~1; break; // 2x1 case BC_YUV420P: case BC_YUV420PI: in_w &= ~1; in_h &= ~1; break; // 2x2 case BC_YUV422P: in_w &= ~1; break; // 2x1 case BC_YUV410P: in_w &= ~3; in_h &= ~3; break; // 4x4 case BC_YUV411P: in_w &= ~3; break; // 4x1 } switch( out_colormodel ) { case BC_UVY422: case BC_YUV422: out_w &= ~1; break; case BC_YUV420P: case BC_YUV420PI: out_w &= ~1; out_h &= ~1; break; case BC_YUV422P: out_w &= ~1; break; case BC_YUV410P: out_w &= ~3; out_h &= ~3; break; case BC_YUV411P: out_w &= ~3; break; } this->output_rows = output_rows; this->input_rows = input_rows; this->out_yp = out_yp; this->out_up = out_up; this->out_vp = out_vp; this->out_ap = out_ap; this->in_yp = in_yp; this->in_up = in_up; this->in_vp = in_vp; this->in_ap = in_ap; this->in_x = in_x; this->in_y = in_y; this->in_w = in_w; this->in_h = in_h; this->out_x = out_x; this->out_y = out_y; this->out_w = out_w; this->out_h = out_h; this->in_colormodel = in_colormodel; switch( in_colormodel ) { case BC_GBRP: in_rowspan = in_w * sizeof(uint8_t); break; case BC_RGB_FLOATP: case BC_RGBA_FLOATP: if( !BC_CModels::has_alpha(out_colormodel) ) this->in_colormodel = BC_RGB_FLOATP; in_rowspan = in_w * sizeof(float); break; } this->total_in_w = in_rowspan; this->out_colormodel = out_colormodel; switch( out_colormodel ) { case BC_GBRP: out_rowspan = out_w * sizeof(uint8_t); break; case BC_RGB_FLOATP: case BC_RGBA_FLOATP: out_rowspan = out_w * sizeof(float); break; } this->total_out_w = out_rowspan; this->in_pixelsize = BC_CModels::calculate_pixelsize(in_colormodel); this->out_pixelsize = BC_CModels::calculate_pixelsize(out_colormodel); this->scale = (out_w != in_w) || (in_x != 0); /* + 1 so we don't overflow when calculating in advance */ column_table = new int[out_w+1]; double hscale = (double)in_w/out_w; for( int i=0; i max_slices ) slices = max_slices; if( slices < 1 ) slices = 1; Slicer *active[slices]; unsigned y0 = 0, y1 = out_h; int slices1 = slices-1; if( slices1 > 0 ) { slicers.lock("BC_Xfer::xfer_slices"); for( int i=0; islice(this, y0, y1); } slicers.unlock(); } (this->*xfn)(y0, out_h); if( slices1 > 0 ) { for( int i=0; icomplete->lock("BC_Xfer::xfer_slices"); slicers.lock("BC_Xfer::xfer_slices"); for( int i=0; ixp = xp; init = new Condition(0, "BC_Xfer::Slicer::init", 0); complete = new Condition(0, "BC_Xfer::Slicer::complete", 0); done = 0; start(); } BC_Xfer::Slicer::~Slicer() { done = 1; init->unlock(); join(); delete complete; delete init; } void BC_Xfer::Slicer::slice(BC_Xfer *xp, unsigned y0, unsigned y1) { this->xp = xp; this->y0 = y0; this->y1 = y1; init->unlock(); } void BC_Xfer::Slicer::run() { while( !done ) { init->lock("Slicer::run"); if( done ) break; xfer_fn xfn = xp->xfn; (xp->*xfn)(y0, y1); complete->unlock(); } } void BC_CModels::bcxfer_stop_slicers() { BC_Xfer::slicers.reset(); }