⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vframe.c

📁 用你的语音Modem实现像电话一样通话的程序
💻 C
字号:
#include "vframe.h"VFrame::VFrame(int w, int h){	this->w = w; this->h = h;	rows = new VPixel*[h + 1];	for(int i = 0; i < h + 1; i++)	{		rows[i] = new VPixel[w + 1];//printf("%x\n", rows[i]);	}}VFrame::~VFrame(){//printf("VFrame::~VFrame\n");	for(int i = 0; i < h + 1; i++)	{//printf("%x\n", rows[i]);		delete rows[i];	}	delete rows;}VFrame::transfer_from(VFrame *frame, long position, int center_x, int center_y, float zoom, float opacity, int fast){// get boundaries	int in_row1 = (int)(center_y - frame->h / 2 / zoom);	int in_row2 = (int)(center_y + frame->h / 2 / zoom);	int in_column1 = (int)(center_x - frame->w / 2 / zoom);	int in_column2 = (int)(center_x + frame->w / 2 / zoom);	int out_row1 = 0;	int out_row2 = 0;	int out_column1 = 0;	int out_column2 = 0;// correct boundaries	if(in_row1 < 0) { out_row1 += -(int)(in_row1 * zoom); in_row1 = 0; }	if(in_row2 > frame->h) { out_row2 -= (int)((in_row2 - frame->h) * zoom); in_row2 = frame->h; }	if(in_column1 < 0) { out_column1 += -(int)(in_column1 * zoom); in_column1 = 0; }	if(in_column2 > frame->w) { out_column2 -= (int)((in_column2 - frame->w) * zoom); in_column2 = frame->w; }	if(out_row1 < 0) { in_row1 += -(int)(out_row1 / zoom); out_row1 = 0; }	if(out_row2 > frame->h) { in_row2 -= (int)((out_row2 - frame->h) / zoom); out_row2 = frame->h; }	if(out_column1 < 0) { in_column1 += -(int)(out_column1 / zoom); out_column1 = 0; }	if(out_column2 > frame->w) { in_column2 -= (int)((out_column2 - frame->w) / zoom); out_column2 = frame->w; }	if(zoom > 1)	{		transfer_enlarge(frame, in_row1, out_row1, in_row2 - in_row1, out_row2 - out_row1,				in_column1, out_column1, in_column2 - in_column1, out_column2 - out_column1, opacity, fast);	}	else	if(zoom == 1)	{		for(int i = out_row1, j = in_row1; i < out_row2; i++, j++)		{			transfer_row_direct(&rows[i][out_column1], &(frame->rows[j][in_column1]), out_column2 - out_column1, opacity);		}	}	else	{		transfer_reduce(frame, in_row1, out_row1, in_row2 - in_row1, out_row2 - out_row1,				in_column1, out_column1, in_column2 - in_column1, out_column2 - out_column1, opacity, fast);	}}VFrame::transfer_enlarge(VFrame *input, int in_row1, int out_row1, int in_height, int out_height,				int in_column1, int out_column1, int in_width, int out_width, float opacity, int fast){	int input_table_x[out_width];	int input_table_y[out_height];	float input_fraction_table_x[out_width];	float input_fraction_table_y[out_height];	get_enlarge_tables(input_table_x, 		input_table_y, 		input_fraction_table_x, 		input_fraction_table_y, 		in_width, 		out_width, 		in_height, 		out_height);	if(fast)	{		VPixel new_row[out_width];		int last_input_row = input_table_y[0];		VPixel **input_rows, **output_rows;				input_rows = &(input->rows[in_row1]);		output_rows = &rows[out_row1];		enlarge_row_fast(new_row, &input_rows[last_input_row][in_column1], out_width, input_table_x);		for(int i = 0; i < out_height; i++)		{			if(last_input_row != input_table_y[i])			{				last_input_row = input_table_y[i];				enlarge_row_fast(new_row, &input_rows[last_input_row][in_column1], out_width, input_table_x);			}			transfer_row_direct(&output_rows[i][out_column1], new_row, out_width, opacity);		}	}	else	{		VPixel *next_row, *previous_row;		VPixel **input_rows, **output_rows;		VPixel *temp;		int i = 0, j = 0;		int next_row_number;		input_rows = &(input->rows[in_row1]);		output_rows = &rows[out_row1];		next_row = new VPixel[out_width];		previous_row = new VPixel[out_width];		next_row_number = input_table_y[i];		enlarge_row(next_row, &input_rows[next_row_number][in_column1], out_width, input_table_x, input_fraction_table_x);		for(i = 0; i < out_height; i++)		{			if(input_table_y[i] >= next_row_number)			{// swap fake rows				temp = previous_row;				previous_row = next_row;				next_row = temp;// get a new row				next_row_number = input_table_y[i] + 1;				enlarge_row(next_row, &input_rows[next_row_number][in_column1], out_width, input_table_x, input_fraction_table_x);			}			transfer_row_enlarge(&output_rows[i][out_column1], previous_row, next_row, out_width, input_fraction_table_y[i], opacity);		}				delete next_row;		delete previous_row;	}}VFrame::get_enlarge_tables(int *input_table_x, 	int *input_table_y, 	float *input_fraction_table_x, 	float *input_fraction_table_y, 	int in_width, 	int out_width, 	int in_height, 	int out_height){	int output_pixel;	float input_pixel;	float input_advance = in_width / out_width;	for(output_pixel = 0, input_pixel = 0; 		output_pixel < out_width; 		input_pixel += input_advance, output_pixel++)	{		input_table_x[output_pixel] = (int)input_pixel;		input_fraction_table_x[output_pixel] = input_pixel - (int)input_pixel;	}	input_advance = in_height / out_height;	for(output_pixel = 0, input_pixel = 0; 		output_pixel < out_height; 		input_pixel += input_advance, output_pixel++)	{		input_table_y[output_pixel] = (int)input_pixel;		input_fraction_table_y[output_pixel] = input_pixel - (int)input_pixel;	}}VFrame::transfer_reduce(VFrame *input, int in_row1, int out_row1, int in_height, int out_height,				int in_column1, int out_column1, int in_width, int out_width, float opacity, int fast){	if(fast)	{		int input_table_x[out_width];		int input_table_y[out_height];				get_fast_reduce_tables(input_table_x,			input_table_y,			in_width,			out_width,			in_height,			out_height);		VPixel **input_rows, **output_rows;				input_rows = &(input->rows[in_row1]);		output_rows = &rows[out_row1];		for(int i = 0; i < in_height; i++)		{			reduce_row_fast(&output_rows[i][out_column1], &input_rows[input_table_y[i]][in_column1], input_table_x, out_width, opacity);		}	}	else	{		int output_table_x[in_width];		int output_table_y[in_height];		float output_fraction_table_x[in_width];		float output_fraction_table_y[in_height];		get_reduce_tables(output_table_x, 			output_table_y, 			output_fraction_table_x, 			output_fraction_table_y, 			in_width, 			out_width, 			in_height, 			out_height);		int output_pixel_old;		VPixel new_row[out_width];		VPixel **input_rows, **output_rows;		input_rows = &(input->rows[in_row1]);		output_rows = &rows[out_row1];		clear_row(new_row, out_width);		for(int i = 0, output_pixel_old = output_table_y[0]; i < in_height; i++)		{			if(output_pixel_old != output_table_y[i])			{				transfer_row_direct(&output_rows[output_pixel_old][out_column1], new_row, out_width, opacity);				output_pixel_old = output_table_y[i];				clear_row(new_row, out_width);			}			reduce_row(new_row, &input_rows[i][in_column1], in_width, output_table_x, output_fraction_table_x, output_fraction_table_y[i]);		}	}}VFrame::clear_row(VPixel *row, int width){	for(int i = 0; i < width; i++)	{		row[i].red = row[i].green = row[i].blue = row[i].alpha = 0;	}}VFrame::get_reduce_tables(int *output_table_x, 	int *output_table_y, 	float *output_fraction_table_x,	float *output_fraction_table_y,	int in_width, 	int out_width, 	int in_height, 	int out_height){	int input_pixel;	int output_fraction_pixel, output_fraction_total, output_pixel_old;	float output_pixel;	float output_advance = out_width / in_width;	int i;	for(output_pixel = 0, input_pixel = 0, output_fraction_pixel = 0, output_fraction_total = 0, output_pixel_old = 0; 		input_pixel < in_width; 		input_pixel++, output_pixel += output_advance, output_fraction_total++)	{		if((int)output_pixel != output_pixel_old)		{			for( ; output_fraction_pixel < input_pixel; output_fraction_pixel++)				output_fraction_table_x[output_fraction_pixel] = (float)1 / output_fraction_total;			output_fraction_total = 0;			output_pixel_old = (int)output_pixel;		}		output_table_x[input_pixel] = (int)output_pixel;	}	output_advance = out_height / in_height;	for(output_pixel = 0, input_pixel = 0, output_fraction_pixel = 0, output_fraction_total = 0, output_pixel_old = 0; 		input_pixel < in_height; 		input_pixel++, output_pixel += output_advance, output_fraction_total++)	{		if((int)output_pixel != output_pixel_old)		{			for( ; output_fraction_pixel < input_pixel; output_fraction_pixel++)				output_fraction_table_y[output_fraction_pixel] = (float)1 / output_fraction_total;			 output_fraction_total = 0;			 output_pixel_old = (int)output_pixel;		}		output_table_y[input_pixel] = (int)output_pixel;	}}		VFrame::get_fast_reduce_tables(int *output_table_x,	int *output_table_y,	int in_width,	int out_width,	int in_height,	int out_height){	float input_pixel;	int output_pixel;	float input_advance = in_width / out_width;		for(input_pixel = 0, output_pixel = 0; output_pixel < out_width; input_pixel += input_advance, output_pixel++)	{		output_table_x[output_pixel] = (int)input_pixel;	}		input_advance = in_height / out_height;	for(input_pixel = 0, output_pixel = 0; output_pixel < out_height; input_pixel += input_advance, output_pixel++)	{		output_table_y[output_pixel] = (int)input_pixel;	}}VFrame::reduce_row(VPixel *output, VPixel *input, int in_width, int *output_table_x, float *output_fraction_table_x, float y_fraction){	float fraction;	int pixel;	for(int i = 0; i < in_width; i++)	{		fraction = output_fraction_table_x[i] * y_fraction;		pixel = output_table_x[i];		output[pixel].red += (int)(input[i].red * fraction);		output[pixel].green += (int)(input[i].green * fraction);		output[pixel].blue += (int)(input[i].blue * fraction);		output[pixel].alpha += (int)(input[i].alpha * fraction);	}}VFrame::reduce_row_fast(VPixel *output, VPixel *input, int *input_table_x, int out_width, float opacity){	for(int i = 0; i < out_width; i++)	{		overlay_pixel(&output[i], &input[input_table_x[i]], opacity);	}}VFrame::enlarge_row(VPixel *output, VPixel *input, int out_columns, int *input_table_x, float *input_fraction_table_x){	VPixel *left_pixel, *right_pixel;	float ratio, inv_ratio;	int right_pixel_number, i = 0;	right_pixel_number = input_table_x[i];	right_pixel = &input[right_pixel_number];	for(i = 0; i < out_columns; i++)	{		if(input_table_x[i] >= right_pixel_number)		{			left_pixel = right_pixel;			right_pixel_number = input_table_x[i] + 1;			right_pixel = &input[right_pixel_number];		}		ratio = input_fraction_table_x[i];		inv_ratio = 1 - ratio;		output[i].red = (int)(left_pixel->red * inv_ratio + right_pixel->red * ratio);		output[i].green = (int)(left_pixel->green * inv_ratio + right_pixel->green * ratio);		output[i].blue = (int)(left_pixel->blue * inv_ratio + right_pixel->blue * ratio);		output[i].alpha = (int)(left_pixel->alpha * inv_ratio + right_pixel->alpha * ratio);	}}VFrame::enlarge_row_fast(VPixel *output, VPixel *input, int out_columns, int *input_table_x){	int input_pixel;	for(int i = 0; i < out_columns; i++)	{		input_pixel = input_table_x[i];		output[i].red = input[input_table_x[input_pixel]].red;		output[i].green = input[input_table_x[input_pixel]].green;		output[i].blue = input[input_table_x[input_pixel]].blue;		output[i].alpha = input[input_table_x[input_pixel]].alpha;	}}VFrame::transfer_row_enlarge(VPixel *output_row, VPixel *previous_row, VPixel *next_row, int columns, float input_ratio, float opacity){	float inv_ratio = 1 - input_ratio;	int i = 0;	VPixel new_pixel;		for(i = 0; i < columns; i++)	{		new_pixel.red = (int)(previous_row[i].red * inv_ratio + next_row[i].red * input_ratio);		new_pixel.green = (int)(previous_row[i].green * inv_ratio + next_row[i].green * input_ratio);		new_pixel.blue = (int)(previous_row[i].blue * inv_ratio + next_row[i].blue * input_ratio);		new_pixel.alpha = (int)(previous_row[i].alpha * inv_ratio + next_row[i].alpha * input_ratio);		overlay_pixel(&output_row[i], &new_pixel, opacity);	}}VFrame::transfer_row_direct(VPixel *output, VPixel *input, int out_columns, float opacity){	for(int i = 0; i < out_columns; i++)	{		overlay_pixel(&output[i], &input[i], opacity);	}}VFrame::overlay_pixel(VPixel *output, VPixel *input, float opacity){	float input_opacity = (float)input->alpha / VMAX;	input_opacity *= opacity;	float output_opacity = (float)output->alpha / VMAX * (1 - input_opacity);	output->red = (int)(output->red * output_opacity + input->red * input_opacity);	output->green = (int)(output->green * output_opacity + input->green * input_opacity);	output->blue = (int)(output->blue * output_opacity + input->blue * input_opacity);	output->alpha = (int)(output->alpha * output_opacity + input->alpha * input_opacity);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -