コード例 #1
0
ファイル: y4munsharp.c プロジェクト: AquaSoftGmbH/mjpeg
void y4munsharp(void)
	{
	int	i, row, col, diff, value;
	u_char	*i_ptr, *o_ptr;

	mjpeg_debug("Blurring Luma rows frame %d", frameno);

	for	(row = 0; row < yheight; row++)
		{
		blur_line(ctable_y, cmatrix_y, cmatrix_y_len, 
			&i_yuv[0][row * ywidth],
			&o_yuv[0][row * ywidth],
			ywidth);
		}

	if	(uv_radius != -1.0)
		{
		mjpeg_debug("Blurring Chroma rows frame %d", frameno);
		for	(row = 0; row < uvheight; row++)
			{
			blur_line(ctable_uv, cmatrix_uv, cmatrix_uv_len,
				&i_yuv[1][row * uvwidth],
				&o_yuv[1][row * uvwidth],
				uvwidth);
			blur_line(ctable_uv, cmatrix_uv, cmatrix_uv_len,
				&i_yuv[2][row * uvwidth],
				&o_yuv[2][row * uvwidth],
				uvwidth);
			}
		}
	else
		{
		memcpy(o_yuv[1], i_yuv[1], uvlen);
		memcpy(o_yuv[2], i_yuv[2], uvlen);
		}

	mjpeg_debug("Blurring Luma columns frame %d", frameno);
	for	(col = 0; col < ywidth; col++)
		{
/*
 * Do the entire frame if progressive, otherwise this does the only
 * the first field.
*/
		get_column(&o_yuv[0][col], cur_col,
			interlaced ? 2 * ywidth : ywidth,
			interlaced ? yheight / 2 : yheight);
		blur_line(ctable_y, cmatrix_y, cmatrix_y_len,
			cur_col,
			dest_col,
			interlaced ? yheight / 2 : yheight);
		put_column(dest_col, &o_yuv[0][col],
			interlaced ? 2 * ywidth : ywidth,
			interlaced ? yheight / 2 : yheight);

/*
 * If interlaced now process the second field (data source is offset 
 * by 'ywidth').
*/
		if	(interlaced)
			{
			get_column(&o_yuv[0][col + ywidth], cur_col,
				2 * ywidth,
				yheight / 2);
			blur_line(ctable_y, cmatrix_y, cmatrix_y_len,
				cur_col,
				dest_col,
				interlaced ? yheight / 2 : yheight);
			put_column(dest_col, &o_yuv[0][col + ywidth],
				2 * ywidth,
				yheight / 2);
			}
		}

	if	(uv_radius == -1)
		goto merging;

	mjpeg_debug("Blurring chroma columns frame %d", frameno);
	for	(col = 0; col < uvwidth; col++)
		{
/* U */
		get_column(&o_yuv[1][col], cur_col,
			interlaced ? 2 * uvwidth : uvwidth,
			interlaced ? uvheight / 2 : uvheight);
		blur_line(ctable_uv, cmatrix_uv, cmatrix_uv_len,
			cur_col,
			dest_col,
			interlaced ? uvheight / 2 : uvheight);
		put_column(dest_col, &o_yuv[1][col],
			interlaced ? 2 * uvwidth : uvwidth,
			interlaced ? uvheight / 2 : uvheight);
		if	(interlaced)
			{
			get_column(&o_yuv[1][col + uvwidth], cur_col,
				2 * uvwidth,
				uvheight / 2);
			blur_line(ctable_uv, cmatrix_uv, cmatrix_uv_len,
				cur_col,
				dest_col,
				interlaced ? uvheight / 2 : uvheight);
			put_column(dest_col, &o_yuv[1][col + uvwidth],
				2 * uvwidth,
				uvheight / 2);
			}
/* V */
		get_column(&o_yuv[2][col], cur_col,
			interlaced ? 2 * uvwidth : uvwidth,
			interlaced ? uvheight / 2 : uvheight);
		blur_line(ctable_uv, cmatrix_uv, cmatrix_uv_len,
			cur_col,
			dest_col,
			interlaced ? uvheight / 2 : uvheight);
		put_column(dest_col, &o_yuv[2][col],
			interlaced ? 2 * uvwidth : uvwidth,
			interlaced ? uvheight / 2 : uvheight);
		if	(interlaced)
			{
			get_column(&o_yuv[2][col + uvwidth], cur_col,
				2 * uvwidth,
				uvheight / 2);
			blur_line(ctable_uv, cmatrix_uv, cmatrix_uv_len,
				cur_col,
				dest_col,
				interlaced ? uvheight / 2 : uvheight);
			put_column(dest_col, &o_yuv[2][col + uvwidth],
				2 * uvwidth,
				uvheight / 2);
			}
		}
merging:
	mjpeg_debug("Merging luma frame %d", frameno);
	for	(row = 0, i_ptr = i_yuv[0], o_ptr = o_yuv[0]; row < yheight; row++)
		{
		for	(i = 0; i < ywidth; i++, i_ptr++, o_ptr++)
			{
			diff = *i_ptr - *o_ptr;
			if	(abs(2 * diff) < y_threshold)
				diff = 0;
			value = *i_ptr + (y_amount * diff);
/*
 * For video the limits are 16 and 235 for the luma rather than 0 and 255!
*/
			if	(value < lowy)
				value = lowy;
			else if	(value > highy)
				value = highy;
			*o_ptr = value;
			}
		}

	if	(uv_radius == -1.0)
		goto done;

	mjpeg_debug("Merging chroma frame %d", frameno);
	for	(row = 0, i_ptr = i_yuv[1], o_ptr = o_yuv[1]; row < uvheight; row++)
		{
		for	(i = 0; i < uvwidth; i++, i_ptr++, o_ptr++)
			{
			diff = *i_ptr - *o_ptr;
			if	(abs(2 * diff) < uv_threshold)
				diff = 0;
			value = *i_ptr + (uv_amount * diff);
/*
 * For video the limits are 16 and 240 for the chroma rather than 0 and 255!
*/
			if	(value < lowuv)
				value = lowuv;
			else if	(value > highuv)
				value = highuv;
			*o_ptr = value;
			}
		}
	for	(row = 0, i_ptr = i_yuv[2], o_ptr = o_yuv[2]; row < uvheight; row++)
		{
		for	(i = 0; i < uvwidth; i++, i_ptr++, o_ptr++)
			{
			diff = *i_ptr - *o_ptr;
			if	(abs(2 * diff) < uv_threshold)
				diff = 0;
			value = *i_ptr + (uv_amount * diff);
/*
 * For video the limits are 16 and 240 for the chroma rather than 0 and 255!
*/
			if	(value < 16)
				value = 16;
			else if	(value > highuv)
				value = highuv;
			*o_ptr = value;
			}
		}
done:
	return;
	}
コード例 #2
0
ファイル: unsharp.C プロジェクト: knutj/cinelerra
void UnsharpUnit::process_package(LoadPackage *package)
{
	UnsharpPackage *pkg = (UnsharpPackage*)package;
//	int w = server->src->get_w();
//	int h = server->src->get_h();
	int color_model = server->src->get_color_model();
	int components = BC_CModels::components(color_model);
	double *cmatrix = 0;
	int cmatrix_length = 0;
	int padded_y1 = pkg->y1;
	int padded_y2 = pkg->y2;

	cmatrix_length = calculate_convolution_matrix(
		plugin->config.radius, 
		&cmatrix);


	if(padded_y2 < server->src->get_h())
	{
		padded_y2 += cmatrix_length / 2;
		padded_y2 = MIN(server->src->get_h(), padded_y2);
	}
	if(padded_y1 > 0)
	{
		padded_y1 -= cmatrix_length / 2;
		padded_y1 = MAX(0, padded_y1);
	}

	int padded_rows = padded_y2 - padded_y1;

	if(!temp || temp->get_h() != padded_rows)
	{
		delete temp;
		temp = 0;
	}

	if(!temp)
	{
		temp = new VFrame;
		temp->set_use_shm(0);
		temp->reallocate(0,
			-1,
			0,
			0,
			0,
			server->src->get_w(),
			padded_rows,
			components == 3 ? BC_RGB_FLOAT : BC_RGBA_FLOAT,
			-1);
	}

	float *temp_in = new float[MAX(temp->get_w(), padded_rows) * components];
	float *temp_out = new float[MAX(temp->get_w(), padded_rows) * components];

// Blur rows
	for(int i = padded_y1; i < padded_y2; i++)
	{
		get_row(temp_in, server->src, i);
		blur_pixels(cmatrix, 
			cmatrix_length,
			temp_in,
			temp_out,
			temp->get_w(),
			components);
// printf("UnsharpUnit::process_package %d %p %p %p %d %d\n", 
// __LINE__, 
// temp, 
// temp->get_rows()[0], 
// temp_out,
// i - padded_y1,
// temp->get_bytes_per_line());
		memcpy(temp->get_rows()[i - padded_y1],
		 	temp_out,
			temp->get_bytes_per_line());
	}

//Now we're 100% floating point.  Blur the columns
	for(int i = 0; i < temp->get_w(); i++)
	{
		get_column(temp_in, temp, i);
		blur_pixels(cmatrix,
			cmatrix_length,
			temp_in,
			temp_out,
			padded_rows,
			components);
		put_column(temp_out, temp, i);
	}


//printf("%f %f %d\n", plugin->config.radius,plugin->config.amount, plugin->config.threshold);


#define UNSHARPEN(type, components, max) \
{ \
	float threshold = (float)plugin->config.threshold * max / 0xff; \
	float amount = plugin->config.amount; \
 \
	for(int i = pkg->y1; i < pkg->y2; i++) \
	{ \
		float *blurry_row = (float*)temp->get_rows()[i - padded_y1]; \
		type *orig_row = (type*)server->src->get_rows()[i]; \
		for(int j = 0; j < server->src->get_w(); j++) \
		{ \
			for(int k = 0; k < components; k++) \
			{ \
				float diff = *orig_row - *blurry_row; \
				if(fabsf(2 * diff) < threshold) \
					diff = 0; \
				float value = *orig_row + amount * diff; \
				if(sizeof(type) == 4) \
					*orig_row = (type)value; \
				else \
					*orig_row = (type)CLIP(value, 0, max); \
				blurry_row++; \
				orig_row++; \
			} \
		} \
	} \
}

// Apply unsharpening
	switch(color_model)
	{
		case BC_RGB888:
		case BC_YUV888:
			UNSHARPEN(unsigned char, 3, 0xff);
			break;
		case BC_RGBA8888:
		case BC_YUVA8888:
			UNSHARPEN(unsigned char, 4, 0xff);
			break;
		case BC_RGB_FLOAT:
			UNSHARPEN(float, 3, 1.0);
			break;
		case BC_RGBA_FLOAT:
			UNSHARPEN(float, 4, 1.0);
			break;
		case BC_YUV161616:
			UNSHARPEN(uint16_t, 3, 0xffff);
			break;
		case BC_YUVA16161616:
			UNSHARPEN(uint16_t, 4, 0xffff);
			break;
	}

	delete [] temp_in;
	delete [] temp_out;
	delete [] cmatrix;
}