/*********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);
}