S3C6410 FrameBuffer编程(六) --- 利用FrameBuffer显示图片,并实现左右、上下、180度翻转

/*********wzk_fb.h*************/
/********************************
/*  定义了屏幕信息结构体 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/fb.h>
#include <fcntl.h>
#include <sys/mman.h>

int fb;

struct screen_info{

        unsigned int smem_size;
        unsigned int line_size;
        unsigned int xres;
        unsigned int yres;
        unsigned int bits_per_pixel;
	
};

struct screen_info h43_info;
/*************** fb.h ******************/
/***************************************/
/***************************************/
/**** 操作FrameBuffer的相关函数 ****/


#include <math.h>

#include "wzk_fb.h"
//#include "wzk_jpeg.h"

int open_fb(void)
{
    fb = open ("/dev/fb0",O_RDWR);  
    if (fb < 0) 
    {   
        printf("Error : Can not open framebuffer device\n");   
        return -1;  
    }

    printf("open framebuffer device sccuess!\n");

    return 0;	  
}

void close_fb(void)
{
	close(fb);
	
	return;
}

int get_screen_info(void)
{
	struct fb_var_screeninfo vinfo;
	struct fb_fix_screeninfo finfo;

	if (ioctl(fb,FBIOGET_FSCREENINFO,&finfo)) 
    	{   
        	printf("Error reading fixed information\n");   
        	return -1;
    	}
   
    	if (ioctl(fb,FBIOGET_VSCREENINFO,&vinfo)) 
    	{   
        	printf("Error reading variable information\n");   
        	return -1;
    	}

	h43_info.smem_size = finfo.smem_len;
	h43_info.line_size = finfo.line_length;
	h43_info.xres = vinfo.xres;
	h43_info.yres = vinfo.yres;
	h43_info.bits_per_pixel = vinfo.bits_per_pixel;
  
    	printf("The mem is :%d\n",h43_info.smem_size);  
    	printf("The line_length is :%d\n",h43_info.line_size);  
    	printf("The xres is :%d\n",h43_info.xres);  
    	printf("The yres is :%d\n",h43_info.yres);  
    	printf("bits_per_pixel is :%d\n",h43_info.bits_per_pixel);  

	return 0;
}


int clear_screen(void)
{
	char *fpb;
	size_t screen_size;
	long int location;
	int x,y;
	int i;

	x = 0;
	y = 0;
	
	
	screen_size = h43_info.smem_size/2;
	location = h43_info.line_size * y + h43_info.bits_per_pixel / 8 * x;

	fpb = (char *)mmap(NULL,screen_size,PROT_READ | PROT_WRITE,MAP_SHARED,fb,0);
	if((int)fpb < 0)
	{
		printf("mmap fail!\n");
		return -1;
	}

	for(i = 0; i < h43_info.xres * h43_info.yres; i++)
	{
		*(fpb + location) = 0x00;
		*(fpb + location + 1) = 0x00;
		location += 2;
	}		
	munmap(fpb,screen_size);	
	
}


int draw_point(int x,int y,unsigned char rg,unsigned gb)
{
	char *fpb;
	size_t screen_size;
	long int location;
	
	screen_size = h43_info.smem_size/2;
	location = h43_info.line_size * y + h43_info.bits_per_pixel / 8 * x;

	fpb = (char *)mmap(NULL,screen_size,PROT_READ | PROT_WRITE,MAP_SHARED,fb,0);
	if((int)fpb < 0)
	{
		printf("mmap fail!\n");
		return -1;
	}

	*(fpb + location) = gb;
	*(fpb + location + 1) = rg;

	munmap(fpb,screen_size);

	return 0;	
}

int draw_image(unsigned short *buf)
{
	char *fpb;
	size_t screen_size;
	long int location;
	int i;
	
	location = 0;	

	screen_size = h43_info.smem_size/2;
//	location = h43_info.line_size * y + h43_info.bits_per_pixel / 8 * x;

	fpb = (char *)mmap(NULL,screen_size,PROT_READ | PROT_WRITE,MAP_SHARED,fb,0);
	if((int)fpb < 0)
	{
		printf("mmap fail!\n");
		return -1;
	}

	for(i = 0; i < 480 * 272; i++)
	{
		*(fpb + location) = (unsigned char)(buf[i] & 0x00ff);
		*(fpb + location + 1) = (unsigned char)((buf[i] >> 8) & 0x00ff);
		location += 2;
	}

	munmap(fpb,screen_size);

	return 0;	
}





/**************************************************/
/**************** bmp.h **************************/
/*** 定义了bmp格式图片的相关结构体********/
typedef struct bmp_file{

	unsigned short map_id; //type
	unsigned int file_size;	//size
	unsigned int reserved;   //reserved,set 0
	unsigned int offset; //offset

}__attribute__((packed)) BMPFILEHEADER;

typedef struct bmp_info{

	unsigned int cur_size;
	unsigned int width;
	unsigned int hight;
	unsigned short reserved;
	unsigned short bpp;
	unsigned int compression;
	unsigned int map_size;
	
	unsigned int x_ppm;
	unsigned int y_ppm;
	unsigned int palette;
	unsigned int bitmapdata;
/*
	unsigned int R;
	unsigned int G;
	unsigned int B;
	unsigned int A;
*/

}__attribute__((packed))BMPINFOHEADER;

typedef struct pixel{

	unsigned char blue;
	unsigned char green;
	unsigned char red;
}__attribute__((packed))PIXEL;

BMPFILEHEADER FileHead;
BMPINFOHEADER InfoHead;
//PIXEL pix;


/******************** convert.h*********************/
/****************************************************/
/******* 实现屏幕的上下、左右、180度翻转 *******/

#define BUF_SIZE 480*272
#define BUF_WIDTH 480
#define BUF_HEIGHT 272

unsigned short  *rotate_180(unsigned short *buf)
{
	unsigned short tmp[BUF_SIZE];
	int i,j;

	j = 0;

	for(i = BUF_SIZE - 1; i >= 0; i--)
	{
		tmp[j] = buf[i];
		j++;
	}

	for(i = 0;i < BUF_SIZE; i++)
	{
		buf[i] = tmp[i];
	}

	return buf;
}

unsigned short  *left_to_right(unsigned short *buf)
{
	unsigned short tmp[BUF_SIZE];
	int i,j,m;
	unsigned long int count;

	count = 0;
	m = 0;

	for(j = 1;j <= BUF_HEIGHT;j++)
	{
		count = j * BUF_WIDTH - 1;

		for(i = 0; i < BUF_WIDTH; i++)
		{
			tmp[m] = buf[count];
			count --;
			m++;		
		}
	}	

	for(i = 0; i < BUF_SIZE; i++)
	{
		buf[i] = tmp[i];		
	}

	return buf;
}

unsigned short  *up_to_down(unsigned short *buf)
{
	unsigned short tmp[BUF_SIZE];
	int i,j,m;
	unsigned long int count;

	m = 0;
//	count = BUF_SIZE - BUF_WIDTH;

	for(j = 1;j <= BUF_HEIGHT;j++)
	{
		count = BUF_SIZE - j * BUF_WIDTH;

		for(i = 0; i < BUF_WIDTH; i++)
		{
			tmp[count] = buf[m];
			count ++;
			m++;		
		}
	}	

	for(i = 0; i < BUF_SIZE; i++)
	{
		buf[i] = tmp[i];		
	}

	return buf;
}




/****** *****************bmp.c ******************************/
/********************************************/
/********* 实现图片的显示******************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "bmp.h"
#include "fb.h"
#include "convert.h"

unsigned short frame_buffer[480*272];

unsigned short rgb24_2_rgb565(unsigned int r, unsigned int g, unsigned int b)
{
	unsigned short ret;
	
	ret = (r << 8)&0xf800 | (g << 3)&0x07e0 | (b >> 3);

	return ret;
}

int init_fb(void)
{
        int ret;
        ret = open_fb();
        if(ret < 0)
        {
                return -1;
        } 

        ret = get_screen_info();
        if(ret < 0)
        {
                return -1;
        }

        clear_screen();

	return 0;
        //draw_point(100,100,0x3f,0x7e);        
        //close_fb();
}


int main(int argc,char *argv[])
{

	FILE *fp;
	int rc;
	int Count;
	long int BytesPerLine;	
//	int x,y;
	int re;

	re = init_fb();	
	if(re < 0)
	{
		printf("init_fb error!\n");
		return 0;
	}
	Count = 0;	
//	x = 0;
//	y = 0;
	
	fp = fopen("./wzk.bmp","rb");
	if(fp == NULL)
	{
		goto CLOSE;
		return -1;
	}

	rc = fread(&FileHead,sizeof(BMPFILEHEADER),1,fp);
	if(rc != 1)
	{
		printf("read file header error!\n");
//		fclose(fp);
		goto CLOSE;
		
		return -2;
	}

	printf("type = %4x\n",FileHead.map_id);
//	printf("file size:%d,reserved:%d\n",FileHead.file_size,FileHead.reserved);
/*
	if(memcmp(FileHead.map_id,"BM",2) != 0)
	{
		printf("it is not a bmp file \n");
		fclose(fp);
		return -3;
	}	

*/
	rc = fread(&InfoHead,sizeof(BMPINFOHEADER),1,fp);
	if(rc != 1)
	{
		printf("read info header error!\n");
	//	fclose(fp);
		goto CLOSE;
		return -4;
	}

	fseek(fp,FileHead.offset,SEEK_SET);
	
	BytesPerLine = InfoHead.width * InfoHead.bpp/8;

	printf("width:%d,bpp:%d\n",InfoHead.width,InfoHead.bpp);

	while(!feof(fp))
	{
		PIXEL pix;
		unsigned short ret;

		rc = fread(&pix,sizeof(PIXEL),1,fp);
		if(rc != 1)
		{
			printf("read bmp file error!\n");
//			fclose(fp);
			goto CLOSE;
			return -1;
		}

		ret = rgb24_2_rgb565(pix.red,pix.green,pix.blue);
/*		draw_point(x,y,(unsigned char)((ret >> 8) & 0x00ff),(unsigned char)(ret & 0x00ff));
		x++;
		if(x == 480)
		{
			x = 0;
			y++;
			if(y == 272)
			{
				goto CLOSE;
			}
		}
*/					
//		printf("blue:%d,green:%d,red:%d\n",pix.blue,pix.green,pix.red);

		frame_buffer[Count] = ret;
		Count++;
		if(Count == 480*272)
		{	
			Count = 0;
			break;
		}			
	}

	draw_image(frame_buffer);			
	while(1)
	{
		int tmp;

		printf("1:rolate 180\n");
		printf("2:left to right\n");
		printf("3:up to down\n");
		printf("other:exit\n");

		scanf("%d",&tmp);
			
		if(tmp == 1)
		{
			draw_image(rotate_180(frame_buffer));
		} 
		else if(tmp == 2)
		{
			draw_image(left_to_right(frame_buffer));	
		}
		else if(tmp == 3)
		{
			draw_image(up_to_down(frame_buffer));
		}
		else
		{
			break;
		}
		
	}	

CLOSE:
	fclose(fp);
	close(fb);
}

S3C6410 FrameBuffer编程(六) --- 利用FrameBuffer显示图片,并实现左右、上下、180度翻转_第1张图片


你可能感兴趣的:(S3C6410 FrameBuffer编程(六) --- 利用FrameBuffer显示图片,并实现左右、上下、180度翻转)