フレームバッファとGD
フレームバッファの使い方。
備忘録としてサンプルプログラム。
gd経由で画像ファイル開いてフレームバッファに表示する。
...ところでvinfo->bits_per_pixel == 32の時ってR,G,BそれぞれのMAXって255でいいのかな?
キニシナイ。
#include <stdio.h> #include <stdlib.h> #include <gd.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <linux/fb.h> #include <sys/mman.h> #include <sys/ioctl.h> #define MIN(aa,bb) (((aa)<(bb))?(aa):(bb)) #define MAX(aa,bb) (((aa)>(bb))?(aa):(bb)) void pset( char* fbp, struct fb_fix_screeninfo* finfo, struct fb_var_screeninfo* vinfo, int x, int y, int r, int g, int b ) { long int location = (x + vinfo->xoffset) * (vinfo->bits_per_pixel / 8) + (y + vinfo->yoffset) * finfo->line_length; if ( vinfo->bits_per_pixel == 16 ) { unsigned short int t = (32 * r / 256) << 11 | (64 * g / 256) << 5 | (32 * b / 256); *((unsigned short int*)(fbp + location)) = t; } else if ( vinfo->bits_per_pixel == 32 ) { *(fbp + location) = b; *(fbp + location + 1) = g; *(fbp + location + 2) = b; *(fbp + location + 3) = 0; } } int main( int argc, char** argv ) { if( argc < 2 ) { fprintf( stderr, "usage: %s file\n", argv[0] ); exit( 1 ); } FILE* fp = fopen( argv[1], "r" ); if( !fp ) { exit( 1 ); } gdImagePtr im = NULL; if( strcasestr( argv[1], ".jpeg" ) || strcasestr( argv[1], ".jpe" ) || strcasestr( argv[1], ".jpg" ) ) { im = gdImageCreateFromJpeg( fp ); } else if( strcasestr( argv[1], ".png" ) ) { im = gdImageCreateFromPng( fp ); } else if( strcasestr( argv[1], ".gif" ) ) { im = gdImageCreateFromGif( fp ); } if( !im ) { fprintf( stderr, "Could NOT create image\n" ); exit( 1 ); } int fbfd; struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; long int screensize; char* fbp; fbfd = open( "/dev/fb0", O_RDWR ); if( !fbfd ) { perror( "open" ); exit( 1 ); } if( ioctl( fbfd, FBIOGET_FSCREENINFO, &finfo ) ) { perror( "ioctl" ); exit( 1 ); } if( ioctl( fbfd, FBIOGET_VSCREENINFO, &vinfo ) ) { perror( "ioctl" ); exit( 1 ); } screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; fbp = (char *)mmap( 0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0 ); if( (int)fbp == -1 ) { perror( "mmap" ); exit( 1 ); } for( unsigned int y = 0; y < MIN((unsigned)gdImageSY( im ), vinfo.yres); y++ ) { for( unsigned int x = 0; x < MIN((unsigned)gdImageSX( im ), vinfo.xres); x ++ ) { int index = gdImageGetPixel( im, x, y ); int rr = gdImageRed( im, index ); int gg = gdImageGreen( im, index ); int bb = gdImageBlue( im, index ); pset( fbp, &finfo, &vinfo, x, y, rr, gg, bb ); } } if( munmap( fbp, screensize ) == -1 ) { perror( "munmap" ); } close( fbfd ); gdImageDestroy( im ); fclose( fp ); }