Example #1
0
File: win32.c Project: yydaor/LCUI
LCUI_API int
LCUIScreen_PutGraph (LCUI_Graph *graph, LCUI_Pos des_pos )
{
	int total, y, n, des_row_x, src_row_x, des_x, src_x;
	LCUI_Graph *src;
	LCUI_Rect cut, src_rect;
	LCUI_Size screen_size;
	uchar_t *des_ptr;
	
	src = Graph_GetQuote( graph );
	src_rect = Graph_GetValidRect( graph );
	screen_size = LCUIScreen_GetSize();
	
	if(!Graph_IsValid(src)) {
		return -1;
	}
	if(des_pos.x >= screen_size.w || des_pos.y >= screen_size.h) {
		return -1;
	}
	des_ptr = pixel_mem;
	Graph_Lock( src );
	/* 获取图像的截取区域 */ 
	if( LCUIRect_GetCutArea( screen_size,
		Rect( des_pos.x, des_pos.y, src_rect.width, src_rect.height ),
		&cut
	)) {
		des_pos.x += cut.x;
		des_pos.y += cut.y;
	}
	/* 根据二维坐标和图像尺寸,计算源图像的起始读取点的一维坐标 */
	src_row_x = (cut.y + src_rect.y) * src->width + cut.x + src_rect.x;
	/* 根据二维坐标和屏幕尺寸,计算帧缓冲的起始写入点的一维坐标 */
	des_row_x = des_pos.y * screen_size.w + des_pos.x;

	for(y=0; y<cut.height; ++y) {
		src_x = src_row_x;
		des_x = des_row_x;
		total = src_x + cut.width;
		for (; src_x < total; ++des_x,++src_x) {
			n = des_x << 2;
			des_ptr[n++] = src->rgba[2][src_x];
			des_ptr[n++] = src->rgba[1][src_x];
			des_ptr[n++] = src->rgba[0][src_x];
		}
		src_row_x += src->width;
		/* DIB扫描行是上下颠倒的,因此是从行尾到行首递减 */
		des_row_x += screen_size.w;
	}
	Graph_Unlock( src );
	return 0;
}
Example #2
0
File: jpeg.c Project: dwdcth/LCUI
int load_jpeg(const char *filepath, LCUI_Graph *out)
/* 功能:载入并解码jpg图片 */
{
#ifdef USE_LIBJPEG
	FILE *fp;
	fp = fopen(filepath,"r");
	if(fp == NULL) {
		return -1;
	}
	
	int row_stride,jaka;
	int x,y, m, n, k;
	short int JPsyg;
	
	struct jpeg_decompress_struct cinfo;
	struct my_error_mgr jerr;
	JSAMPARRAY buffer;

	if( fread( &JPsyg, sizeof(short int), 1, fp ) ) {
		if ( JPsyg != -9985 ) {  /* 如果不是jpg图片 */
			return 1; 
		}
	} 
	rewind(fp);
	cinfo.err = jpeg_std_error(&jerr.pub);
	jerr.pub.error_exit = my_error_exit;
	if (setjmp(jerr.setjmp_buffer)) {
		jpeg_destroy_decompress(&cinfo);
		return 2;
	}
	
	jpeg_create_decompress(&cinfo);
	jpeg_stdio_src(&cinfo,fp);
	(void) jpeg_read_header(&cinfo,IS_TRUE);
	(void) jpeg_start_decompress(&cinfo);    

	jaka = cinfo.num_components;
	
	//if (jaka==3) printf("color\n"); else printf("grayscale\n");
	out->have_alpha = IS_FALSE; /* 设置为无透明度 */
	n = Graph_Create(out, cinfo.output_width, cinfo.output_height);
	if( n != 0 ){
		printf("load_jpeg(): error: "MALLOC_ERROR);
		return 1;
	}
	
	row_stride = cinfo.output_width * cinfo.output_components;
	buffer = (*cinfo.mem->alloc_sarray)(
			(j_common_ptr) &cinfo,JPOOL_IMAGE,row_stride,1);
	
	Graph_Lock( out, 1 );
	for(y=0; cinfo.output_scanline <cinfo.output_height; ++y) {
		(void) jpeg_read_scanlines(&cinfo, buffer, 1);
		m = y*out->width;
		if ( jaka == 3 ) {
			for (x=0;x<out->width;x++) {
				n = x+m;
				k=x*3;
				out->rgba[0][n]=buffer[0][k++];
				out->rgba[1][n]=buffer[0][k++];
				out->rgba[2][n]=buffer[0][k++];
			}
		} else {
			for (x=0;x<out->width;x++) {
				n = x+m;
				out->rgba[0][n]=buffer[0][x];
				out->rgba[1][n]=buffer[0][x];
				out->rgba[2][n]=buffer[0][x];
			}
		} 
	}
	out->type = TYPE_JPG;//图片类型为jpg
	Graph_Unlock( out );
	
	(void) jpeg_finish_decompress(&cinfo);
	jpeg_destroy_decompress(&cinfo);
	fclose(fp);
#else
	printf("warning: not JPEG support!"); 
#endif
	return 0;
}
Example #3
0
File: border.c Project: dwdcth/LCUI
int Graph_Draw_Border(LCUI_Graph *src,LCUI_RGB color, LCUI_Border border)
/* 功能:为图形边缘绘制矩形边框 */
{
	int x,y,count, k, start_x,start_y;
	if(Graph_Valid(src)) {
		/* 绘制上边的线 */
		Graph_Lock(src, 1);
		for(y=0;y<border.top;++y) {
			k = y * src->width;
			for(x = 0; x < src->width; ++x) {
				count = k + x;
				src->rgba[0][count] = color.red;
				src->rgba[1][count] = color.green;
				src->rgba[2][count] = color.blue;
				if(Graph_Have_Alpha(src)) 
					src->rgba[3][count] = 255;
			}
		}
		start_y = src->height - border.bottom;
		/* 绘制下边的线 */
		for(y=0;y<border.bottom;++y) {
			k = (start_y+y) * src->width;
			for(x=0;x<src->width;++x) {
				count = k + x;
				src->rgba[0][count] = color.red;
				src->rgba[1][count] = color.green;
				src->rgba[2][count] = color.blue;
				if(Graph_Have_Alpha(src)) 
					src->rgba[3][count] = 255;
			}
		}
		/* 绘制左边的线 */
		for(y=0;y<src->height;++y) {
			k = y * src->width;
			for(x=0;x<border.left;++x) {
				count = k + x;
				src->rgba[0][count] = color.red;
				src->rgba[1][count] = color.green;
				src->rgba[2][count] = color.blue;
				if(Graph_Have_Alpha(src)) 
					src->rgba[3][count] = 255;
			}
		}
		/* 绘制右边的线 */
		start_x = src->width - border.right;
		for(y=0;y<src->height;++y) {
			k = y * src->width + start_x;
			for(x=0;x<border.right;++x) {
				count = k + x;
				src->rgba[0][count] = color.red;
				src->rgba[1][count] = color.green;
				src->rgba[2][count] = color.blue;
				if(Graph_Have_Alpha(src)) 
					src->rgba[3][count] = 255;
			}
		}
		/* 边框线绘制完成 */
		Graph_Unlock(src);
	}
	else return -1;
	return 0;
}
Example #4
0
LCUI_EXPORT(int) write_png(const char *file_name, LCUI_Graph *graph)
/* 将图像数据写入至png文件 */
{
#ifdef USE_LIBPNG
	FILE *fp;
	int j, i, temp, pos;
	png_byte color_type; 
	png_structp png_ptr;
	png_infop info_ptr; 
	png_bytep * row_pointers;
	
	if(!Graph_IsValid(graph)) {
		printf("write_png(): graph is not valid\n");
		return -1;
	}
	
	/* create file */
	fp = fopen(file_name, "wb");
	if (!fp) {
		printf("write_png(): File %s could not be opened for writing\n", file_name);
		return -1;
	}
	/* initialize stuff */
	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

	if (!png_ptr) {
		printf("write_png(): png_create_write_struct failed\n");
		return -1;
	}
	info_ptr = png_create_info_struct(png_ptr);
	if (!info_ptr) {
		printf("write_png(): png_create_info_struct failed\n");
		return -1;
	}
	if (setjmp(png_jmpbuf(png_ptr))) {
		printf("write_png(): Error during init_io\n");
		return -1;
	}
	png_init_io(png_ptr, fp);


	/* write header */
	if (setjmp(png_jmpbuf(png_ptr))) {
		printf("write_png(): Error during writing header\n");
		return -1;
	}
	Graph_Lock(graph);
	if(Graph_HaveAlpha(graph)) {
		color_type = PNG_COLOR_TYPE_RGB_ALPHA;
	} else {
		color_type = PNG_COLOR_TYPE_RGB;
	}
	
	png_set_IHDR(png_ptr, info_ptr, graph->width, graph->height,
		graph->bit_depth, color_type, PNG_INTERLACE_NONE,
		PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
		
	png_write_info(png_ptr, info_ptr);

	/* write bytes */
	if (setjmp(png_jmpbuf(png_ptr)))
	{
		printf("write_png(): Error during writing bytes\n");
		Graph_Unlock(graph);
		return -1;
	}
	if(Graph_HaveAlpha(graph)) {
		temp = (4 * graph->width);
	} else {
		temp = (3 * graph->width);
	}
	
	row_pointers = (png_bytep*)malloc(graph->height*sizeof(png_bytep));
	for(i=0,pos=0; i < graph->height; i++) {
		row_pointers[i] = (png_bytep)malloc(sizeof(unsigned char)*temp);
		for(j=0; j < temp; ++pos) {
			row_pointers[i][j++] = graph->rgba[0][pos]; // red
			row_pointers[i][j++] = graph->rgba[1][pos]; // green
			row_pointers[i][j++] = graph->rgba[2][pos];   // blue
			if(Graph_HaveAlpha(graph)) {
				row_pointers[i][j++] = graph->rgba[3][pos]; // alpha 
			}
		}
	}
	png_write_image(png_ptr, row_pointers);

	/* end write */
	if (setjmp(png_jmpbuf(png_ptr))) {
		printf("write_png(): Error during end of write\n");
		Graph_Unlock(graph);
		return -1;
	}
	png_write_end(png_ptr, NULL);

    /* cleanup heap allocation */
	for (j=0; j<graph->height; j++) {
		free(row_pointers[j]);
	}
	free(row_pointers);

	fclose(fp);
	Graph_Unlock(graph);
#else
	printf("warning: not PNG support!"); 
#endif
	return 0;
}
Example #5
0
int GaussianSmooth( LCUI_Graph *src, LCUI_Graph *des, double sigma )
/* 对图像进行高斯模糊处理 */
{
	LCUI_Graph temp;
	
	int32_t kcenter, i;
	uint_t x, y, ksize;
	uint_t temp_pos, temp_start_pos;
	uint_t a_src_pos, b_src_pos, src_start_pos;
	double amul, bmul, gmul, rmul, *kvalue_ptr;
	double *kernel, scale, cons, sum = 0;
	const double PI = 3.141592653;
	
	sigma = sigma > 0 ? sigma : -sigma;
	//ksize为奇数 
	ksize = ceil(sigma * 3) * 2 + 1; 
	if(ksize == 1) {
		Graph_Copy( des, src );
		return 0;
	}

	//计算一维高斯核 
	scale = -0.5/(sigma*sigma);
	cons = 1/sqrt(-scale / PI); 
	kcenter = ksize/2; 
	kernel = (double*) malloc( ksize*sizeof(double) );
	for(i = 0; i < ksize; ++i) {
		int x = i - kcenter;
		*(kernel+i) = cons * exp(x * x * scale);//一维高斯函数
		sum += *(kernel+i);
	} 
	//归一化,确保高斯权值在[0,1]之间
	for(i = 0; i < ksize; i++) {
		*(kernel+i) /= sum;
	}
	
	des->have_alpha = src->have_alpha;
	if( Graph_Create( des, src->width, src->height ) != 0 ) {
		return -1;
	}
	
	Graph_Init( &temp );
	temp.have_alpha = src->have_alpha;
	if( Graph_Create( &temp, src->width, src->height ) != 0 ) {
		return -2;
	}
	
	Graph_Lock( src, RWLOCK_READ );
	Graph_Lock( &temp, RWLOCK_WRITE );
	
	//x方向一维高斯模糊
	temp_start_pos = 0;
	src_start_pos = 0 - kcenter;
	for(y = 0; y < src->height; y++) {
		temp_pos = temp_start_pos;
		b_src_pos = src_start_pos;
		for(x = 0; x < src->width; x++) { 
			sum = amul = bmul = gmul = rmul = 0;
			a_src_pos = b_src_pos;
			kvalue_ptr = kernel;
			for(i = -kcenter; i <= kcenter; i++) {
				if((x+i) >= 0 && (x+i) < src->width) {
					rmul += src->rgba[0][a_src_pos]*(*kvalue_ptr);
					gmul += src->rgba[1][a_src_pos]*(*kvalue_ptr);
					bmul += src->rgba[2][a_src_pos]*(*kvalue_ptr);
					if(src->have_alpha) {
						amul += src->rgba[3][a_src_pos]*(*kvalue_ptr);
					}
					sum += (*kvalue_ptr);
				}
				++a_src_pos;
				++kvalue_ptr;
			}
			temp.rgba[0][temp_pos] = rmul/sum;
			temp.rgba[1][temp_pos] = gmul/sum;
			temp.rgba[2][temp_pos] = bmul/sum;
			if(temp.have_alpha) {
				temp.rgba[3][temp_pos] = amul/sum;
			}
			++temp_pos;
			++b_src_pos;
		}
		temp_start_pos += temp.width;
		src_start_pos += src->width;
	}
	Graph_Unlock( &temp );
	
	Graph_Lock( des, RWLOCK_WRITE );
	Graph_Lock( &temp, RWLOCK_READ );
	//y方向一维高斯模糊
	src_start_pos = 0 - kcenter*temp.width;
	src_start_pos = 0 - kcenter*temp.width;
	for(x = 0; x < temp.width; x++) {
		temp_start_pos = x;
		b_src_pos = src_start_pos;
		for(y = 0; y < temp.height; y++) { 
			sum = amul = bmul = gmul = rmul = 0;
			a_src_pos = b_src_pos;
			kvalue_ptr = kernel;
			for(i = -kcenter; i <= kcenter; i++) {
				if((y+i) >= 0 && (y+i) < temp.height) { 
					rmul += temp.rgba[0][a_src_pos]*(*kvalue_ptr);
					gmul += temp.rgba[1][a_src_pos]*(*kvalue_ptr);
					bmul += temp.rgba[2][a_src_pos]*(*kvalue_ptr);
					if(temp.have_alpha) {
						amul += temp.rgba[3][a_src_pos]*(*kvalue_ptr);
					}
					sum += (*kvalue_ptr);
				}
				a_src_pos += temp.width;
				++kvalue_ptr;
			}
			des->rgba[0][temp_start_pos] = rmul/sum;
			des->rgba[1][temp_start_pos] = gmul/sum;
			des->rgba[2][temp_start_pos] = bmul/sum;
			if(des->have_alpha) {
				des->rgba[3][temp_start_pos] = amul/sum; 
			}
			temp_start_pos += des->width;
			b_src_pos += temp.width;
		}
		++src_start_pos;
	}
	
	Graph_Unlock( &temp );
	Graph_Unlock( des );
	Graph_Unlock( src );
	
	Graph_Free( &temp );
	free(kernel);
	return 0;
}
Example #6
0
LCUI_API int GraphLayer_GetGraph(	LCUI_GraphLayer *ctnr, 
					LCUI_Graph *graph_buff,
					LCUI_Rect rect )
{
	int i, total; 
	uchar_t tmp_alpha, alpha;
	LCUI_Pos pos, glayer_pos;
	LCUI_GraphLayer *glayer;
	LCUI_Queue glayerQ;
	LCUI_Rect valid_area;
	LCUI_Graph tmp_graph;
	
	/* 检测这个区域是否有效 */
	if (rect.x < 0 || rect.y < 0) {
		return -1; 
	}
	if (rect.x + rect.width > ctnr->graph.w
	 || rect.y + rect.height > ctnr->graph.h ) {
		 return -1;
	}
	if (rect.width <= 0 || rect.height <= 0) {
		return -2;
	}
	
	Graph_Init( &tmp_graph );
	Queue_Init( &glayerQ, 0, NULL);
	Queue_UsingPointer( &glayerQ );
	
	graph_buff->color_type = COLOR_TYPE_RGB;
	/* 为graph_buff分配合适尺寸的内存空间 */
	Graph_Create( graph_buff, rect.width, rect.height );
	/* 获取rect区域内的图层列表 */
	GraphLayer_GetLayers( ctnr, rect, &glayerQ ); 
	total = Queue_GetTotal( &glayerQ ); 
	//_DEBUG_MSG( "total: %d\n", total );
	/* 若记录数为零,则表明该区域没有图层 */
	if( total <= 0 ) {
		/* 若没有父图层,则填充白色 */
		if( ctnr == NULL ) {
			Graph_FillColor( graph_buff, RGB(255,255,255) );
		} else { /* 否则使用父图层的图形 */
			Graph_Cut( &ctnr->graph, rect, graph_buff );
		}
		/* 销毁记录 */
		Queue_Destroy( &glayerQ );
		return 0;
	}
	/* 从顶层到底层遍历图层,排除被其它图层完全遮挡或者自身完全透明的图层 */
	for(i=total-1; i>=0; --i) {
		glayer = (LCUI_GraphLayer*)Queue_Get( &glayerQ, i );
		valid_area = GraphLayer_GetValidRect( ctnr, glayer );
		glayer_pos = GraphLayer_GetGlobalPos( ctnr, glayer );
		valid_area.x += glayer_pos.x;
		valid_area.y += glayer_pos.y;
		alpha = GraphLayer_GetRealAlpha( glayer );
		/* 当前图层的透明度小于255的话,就跳过 */
		if( alpha < 255 ) {
			continue;
		}
		/* 如果色彩类型为RGB,没有alpha通道 */
		if( glayer->graph.color_type == COLOR_TYPE_RGB ) {
			/* 如果该图层的有效区域包含目标区域 */
			if( LCUIRect_IncludeRect(valid_area, rect) ) { 
				/* 移除底层的图层,因为已经被完全遮挡 */
				for(total=i-1;total>=0; --total) {
					Queue_DeletePointer( &glayerQ, 0 );
				}
				goto skip_loop;
			}
		}
	}
skip_loop:
	total = Queue_GetTotal( &glayerQ );
	//_DEBUG_MSG( "total: %d\n", total );
	if(i <= 0) {
		if( ctnr == NULL ) {
			Graph_FillColor( graph_buff, RGB(255,255,255) );
		} else {
			Graph_Cut ( &ctnr->graph, rect, graph_buff );
		}
	}
	/* 获取图层列表中的图层 */
	for(i=0; i<total; ++i) {
		glayer = (LCUI_GraphLayer*)Queue_Get( &glayerQ, i );
		//_DEBUG_MSG("%p = Queue_Get( %p, %d )\n", glayer, &glayerQ, i);
		if( !glayer ) {
			continue;
		}
		/* 锁上该图层的互斥锁 */
		Graph_Lock( &glayer->graph );
		/* 获取该图层的有效区域及全局坐标 */
		pos = GraphLayer_GetGlobalPos( ctnr, glayer );
		valid_area = GraphLayer_GetValidRect( ctnr, glayer );
		/* 引用该图层的有效区域内的图像 */
		Graph_Quote( &tmp_graph, &glayer->graph, valid_area ); 
		//_DEBUG_MSG("valid area: %d,%d,%d,%d, pos: %d,%d, size: %d,%d\n", 
		//	valid_area.x, valid_area.y, valid_area.width, valid_area.height,
		//	pos.x, pos.y, glayer->graph.w, glayer->graph.h
		//	);
		/* 获取相对坐标 */
		pos.x = pos.x - rect.x + valid_area.x;
		pos.y = pos.y - rect.y + valid_area.y;
		//_DEBUG_MSG("mix pos: %d,%d\n", pos.x, pos.y);
		/* 如果该图层没有继承父图层的透明度 */
		if( !glayer->inherit_alpha ) {
			/* 直接叠加至graph_buff */
			Graph_Mix( graph_buff, &tmp_graph, pos );
		} else {
			/* 否则,计算该图层应有的透明度 */
			alpha = GraphLayer_GetRealAlpha( glayer );
			/* 备份该图层的全局透明度 */
			tmp_alpha = glayer->graph.alpha;
			/* 将实际透明度作为全局透明度,参与图像叠加 */
			glayer->graph.alpha = alpha;
			Graph_Mix( graph_buff, &tmp_graph, pos );
			/* 还原全局透明度 */
			glayer->graph.alpha = tmp_alpha;
		}
		/* 解锁图层 */
		Graph_Unlock( &glayer->graph );
	}
	Queue_Destroy( &glayerQ );
	return 0;
}