简单的framebuffer的实现

由于时间的的仓促,没来及注释;

1、Makefile文件:

main_fb:main_fb.o myfb.o
    gcc -ljpeg main_fb.o myfb.o -o main_fb
main_fb.o:main_fb.c myfb.h
    gcc -c main_fb.c  
myfb.o:myfb.c myfb.h
    gcc -c myfb.c

.PHONY:clean

clean:
    rm -f a.out *~ *.o 

2、framebuffer的头文件myfb.h:

#ifndef  MYFB_H
#define  MYFB_H

#include <stdio.h>
#include <stdlib.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <jpeglib.h>
#include <jerror.h>
#include <string.h>

typedef struct
{
    int fb;
    struct fb_var_screeninfo vinfo;
    //struct fb_fix_screeninfo finfo;
    long screensize;
    unsigned char *fbp;

}fb_type;

int initilize_fb(fb_type *myfb);
void clean_screen(fb_type *myfb);
int destroy_fb(fb_type *myfb);
void draw_fb(fb_type *myfb, char *imagename);

#endif

3、framebuffer的源文件myfb.c:

#include "myfb.h"


static int set_pixel(void *memoff, int width, int height, int x, int y, unsigned short color);
static int set_pixel32(void *memoff, int width, int height, int x, int y, unsigned int color);
static unsigned short tocolor16(unsigned char red, unsigned char green, unsigned char blue);
static unsigned int tocolor24(unsigned char blue, unsigned char green, unsigned char red);


int initilize_fb(fb_type *myfb)
{
    int fid;
    
    if((fid = open("/dev/fb0", O_RDWR)) < 0)
    {
        return -1;
    }
    myfb->fb = fid;
#if 0
    if(ioctl(fid, FBIOGET_FSCREENINFO, &(myfb->finfo)) < 0)
    {
        exit(-2);
    }
#endif
    if(ioctl(fid, FBIOGET_VSCREENINFO, &(myfb->vinfo)))
    {
        return -2;
    }

    myfb->screensize = myfb->vinfo.xres * myfb->vinfo.yres * myfb->vinfo.bits_per_pixel / 8;
    //printf("screensize=%ld\n", myfb->screensize);
    if((myfb->fbp = mmap(NULL, myfb->screensize, PROT_READ|PROT_WRITE, MAP_SHARED, fid, 0)) == (void *)-1)
    {
        return -3;
    }
    return 0;
}
void clean_screen(fb_type *myfb)
{
    memset(myfb->fbp, 0, myfb->screensize);
}


int destroy_fb(fb_type *myfb)
{
    if(munmap((void *)myfb->fbp, (size_t)myfb->screensize) < 0)
    {
        exit(-1);
    }
    close(myfb->fb);

    return 0;
}

void draw_fb(fb_type *myfb, char *imagename)
{
    FILE *fid;    

    //for jpeg decompress
    struct jpeg_decompress_struct image_info;
    struct jpeg_error_mgr image_err;
    unsigned char *buffer;
    unsigned int x;
    unsigned int y;
    
    //fb attribute
    unsigned int width = myfb->vinfo.xres;
    unsigned int height = myfb->vinfo.yres;
    unsigned int pixels = myfb->vinfo.bits_per_pixel;
    unsigned char *fbp = myfb->fbp;

    if((fid = fopen(imagename, "rb")) == NULL)
    {
        exit(1);
    }
    //init jpeg decompress
    image_info.err = jpeg_std_error(&image_err);
    jpeg_create_decompress(&image_info);

    //bind object to image_info
    jpeg_stdio_src(&image_info, fid);

    //read jpeg header
    jpeg_read_header(&image_info, TRUE);

    //decompress process
    jpeg_start_decompress(&image_info);

    if((image_info.output_width > width) || (image_info.output_height > height))    
    {
        exit(-11);
    }

    //initilize buffer to store decompress image
    if((buffer = malloc(image_info.output_width * image_info.output_components)) == NULL)
    {
        exit(-1);
    }

    y = 0;
    while(image_info.output_scanline < image_info.output_height)
    {
        jpeg_read_scanlines(&image_info, &buffer, 1);
        if(pixels == 16)
        {
            unsigned short color16;
            for(x = 0; x < image_info.output_width; ++x)
            {
                color16 = tocolor16(buffer[x * 3], buffer[x * 3 + 1], buffer[x * 3 + 2]);
                set_pixel(fbp, width, height, x, y, color16);
            }
        }
        else if(pixels == 24)
           {
            memcpy(fbp + y * width * 3, buffer, image_info.output_width * image_info.output_components);
        }
        else if(pixels == 32)
           {
            unsigned int color32;    
            
            for(x = 0; x < image_info.output_width; ++x)
            {
                color32 = tocolor24(buffer[x * 3], buffer[x * 3 + 1], buffer[x * 3 + 2]);
                set_pixel32(fbp, width, height, x, y, color32);
            }
        }

        y++;
    }
    
    //finish decompress and destroy decompress object
    jpeg_finish_decompress(&image_info);
    jpeg_destroy_decompress(&image_info);

    //ralease memory buffer
    free(buffer);
    
    fclose(fid);
}

static unsigned short tocolor16(unsigned char red, unsigned char green, unsigned char blue)
{
    unsigned short ablue = (blue >> 3) & 0x001F;
    unsigned short agreen =((green >> 2) << 5) & 0x07E0;
    unsigned short ared = ((red >> 3) << 11) & 0xF800;

    return(unsigned short)(ablue | agreen | ared);
}

static unsigned int tocolor24(unsigned char red, unsigned char green, unsigned char blue)
{
    //unsigned int aalpha = 0x00000000;
    unsigned int ablue  = blue  & 0x000000FF;
    unsigned int agreen =(green & 0x000000FF) << 8;
    unsigned int ared   = (red  & 0x000000FF) << 16;

    return((unsigned int)(ablue | agreen | ared));
}

/*
 * Display a pixel on the framebuffer device, memoff is the starting memory of framebuffer,
 * width and height are dimension of framebuffer, x and y are the coordinates to display
 * color is the pixel's color value, return 0 if successly,oterwise return -1
 */
static int set_pixel(void *memoff, int width, int height, int x, int y, unsigned short color)
{
    if((x > width) || (y > height))
    {
        exit(-1);
    }

    unsigned short *dst = ((unsigned short *)memoff + y * width + x);
    *dst = color;

    return 0;
}

static int set_pixel32(void *memoff, int width, int height, int x, int y, unsigned int color)
{
    if((x > width) || (y > height))
    {
        exit(-1);
    }

    unsigned int *dst = ((unsigned int *)memoff + y * width + x);
    *dst = color;

    return 0;
}

4、Main 文件main_fb.c:

#include <errno.h>
#include <sys/mount.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include "myfb.h"

char imgbuf[256][256] = {0};
int length = 0;

int usb_init(const char *path);
void usb_destory(const char *path);
void usb_traversaldir(char *filename);

int main(int argc, char **argv)
{
    char path[256] = "/mnt/myusb";
    char cwd[256];
    int i;
    char ch;
     int usb_flag = 0;
    fb_type *myfb;
#if 0
    if(argc != 2)
    {
        fprintf(stderr, "Usage: %s <imagename>\n", argv[0]);
        exit(1);
    }
#endif
    if(usb_init(path) < 0)
    {
        fprintf(stdout, "no usb device \n");
        if(getcwd(path, sizeof(path)) == NULL)
        {
            fprintf(stderr, "getcwd() failed:%s\n", strerror(errno));
            exit(1);
        }
    }
    else
    {
        usb_flag = 1;
    }
    fprintf(stdout, "%s\n", path);
    usb_traversaldir(path);
    

    if((myfb = malloc(sizeof(fb_type))) == NULL)
    {
        fprintf(stderr, "malloc() failed:%s\n", strerror(errno));
        exit(1);
    }
    memset(myfb, 0, sizeof(fb_type));

    int ret;
    if((ret = initilize_fb(myfb)) < 0)
    {
        fprintf(stderr, "initilize fb device failed:%d\n", ret);
        exit(1);
    }

    //fprintf(stdout, "x:%d,y:%d,pixel:%d\n", myfb->vinfo.xres, myfb->vinfo.yres, myfb->vinfo.bits_per_pixel);
    if(length > 0)
    {
        for(i = 0; i < length; ++i)
         {
            clean_screen(myfb);
            draw_fb(myfb, imgbuf[i]);
            //scanf("%1c", &ch);
            sleep(5);
        }
    }
    else
    {
        fprintf(stderr, "no image to display\n");
    }
    clean_screen(myfb);
    destroy_fb(myfb);
    free(myfb);
    if(usb_flag)
    {
        usb_destory(path);
    }
    return 0;
}

int usb_init(const char *path)
{
    if(mkdir(path, 0777) < 0)
    {
        //fprintf(stderr, "mkdir() failed:%s\n", strerror(errno));
        return(-1);
    }
    if(mount("/dev/sdb1", path, "vfat", MS_SYNCHRONOUS, NULL ) != 0)
    {
          //fprintf(stderr, "mount() failed:%s\n", strerror(errno));
          return(-2);
    }

    return 0;
}

void usb_destory(const char *path)
{
    if(umount(path) < 0)
    {
        fprintf(stderr, "umount() failed:%s\n", strerror(errno));
        exit(1);
    }
    if(rmdir(path) < 0)
    {
        fprintf(stderr, "rmdir() failed:%s\n", strerror(errno));
        exit(1);
        }
}

void usb_traversaldir(char *filename)
{
    char *ch;
//int lstat(const char *path, struct stat *buf);
    struct stat status;
    DIR *dp;
    struct dirent *dirp;
    
    if(lstat(filename, &status) < 0)
    {
        fprintf(stderr, "lstat %s failed: %s\n", filename, strerror(errno));
        exit(1);
    }
    
    if(!S_ISDIR(status.st_mode))
    {
        if(S_ISREG(status.st_mode))
        {
            if((ch = strrchr(filename, '.')) != NULL)
            {
                if(strcmp(ch, ".jpg") == 0|| strcmp(ch, ".jpeg") == 0)
                {
                    strcpy(imgbuf[length], filename);
                    ++length;
                    //printf("%s\n",filename);
                }
            }
        }

        return;
    }
    else
    {
        
        //fprintf(stdout, "%s\n", filename);
//DIR *opendir(const char *name);
        if((dp = opendir(filename)) == NULL)
        {
            fprintf(stderr, "opendir(%s) failed: %s\n", filename, strerror(errno));
            exit(1);
        }

//DIR *fdopendir(int fd);
        while((dirp = readdir(dp)) != NULL)
        {
            char buf[1024];
    
            memset(buf, 0, 1024);
            memcpy(buf, filename, strlen(filename));
            strcat(buf, "/");
            strcat(buf, dirp->d_name);

            //fprintf(stdout, "%s\n",  dirp->d_name);
            if(memcmp(dirp->d_name, ".", 1) == 0 || memcmp(dirp->d_name, "..", 2) == 0)
            {
                continue;
            }
            usb_traversaldir(buf);
        }
    }

    
    free(dirp);
    closedir(dp);

    return;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值