FW: Query about Frame Buffer
"Nitin Mahajan" <[email protected]>
| Newsgroups | gmane.linux.fbdev.user,gmane.linux.fbdev.devel |
|---|---|
| Message-ID | <[email protected]> |
Nitin Mahajan Socrates Software India Pvt Ltd... mail:[email protected] Ph:51101667. Mobile : 9448260513 ====================================== The Lord gave us two ends -- one to sit on and the other to think with. Success depends on which one we use the most. -----Original Message----- From: Nitin Mahajan Sent: Tuesday, June 10, 2003 12:39 PM To: '[email protected]' Subject: Query about Frame Buffer Hello! Iam writing a simple program to display an RGB image with 24bpp depth,by directly programming the framebuffer driver. I am attaching the code and the RGB image file to be displayed here. I have the following major problems with it ,hope u would help me out 1.When I execute this program and set the mode by calling the SetMode function written by me,the finfo.visual becomes FB_VISUAL_DIRECTCOLOR. I want to set the video mode to (640,480,24bpp) and want to have the visual as FB_VISUAL_TRUECOLOR so that I need not get create and manage any color map.How can I achieve this?What all things or settings affect the finfo.visual? 2.As I got the visual as FB_VISUAL_DIRECTCOLOR,I created a colormap and tried to display the image under this visual. The Image is being displayed perfectly in gray scale, but no colors. How do I create and set a colormap to get true color, or how do I emulate TRUECOLOR from DIRECTCOLOR, please explain in detail. Thanking u in advance and waitnig for ur reply, regards Nitin Mahajan Socrates Software India Pvt Ltd... mail:[email protected] Ph:51101667. Mobile : 9448260513 ====================================== The Lord gave us two ends -- one to sit on and the other to think with. Success depends on which one we use the most.
VgaPutimage.c
(application/octet-stream, 7.5 KB)
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <errno.h>
#define IMAGE_WIDTH 239
#define IMAGE_HEIGHT 309
unsigned char buff[IMAGE_WIDTH * IMAGE_HEIGHT * 3];
int retval=0;
int count = 0;
int display();
int fbfd = 0;
void RestorePalette(int ,unsigned short *);
int main()
{
FILE *fp;
unsigned char *pos;
unsigned short new_entries[3*256];
struct fb_fix_screeninfo finfo;
int h=0,w=0;
pos = buff;
if((fp = fopen("ashRgb.rgb","rb"))==NULL)
{
perror((char *)strerror(errno));
printf("Error opening file ashRgb.\n");
exit(0);
return 1;
}
/***************************************************************/
for (h = 0; h < IMAGE_HEIGHT; h++)
{
for (w = 0; w < IMAGE_WIDTH; w++)
{
fread(pos++,1,1,fp);
fread(pos++,1,1,fp);
fread(pos++,1,1,fp);
/************************Commented by nitin***************/
//*pos++ = w - w % 32; /* Red. */
//*pos++ = (w / 32) * 4 + h - h % 32; /* Green. */
//*pos++ = w - w % 32; /* Blue. */
/*********************************************************/
}
}
/* if((fp = fopen("ashRgb.rgb","rb"))==NULL)
{
printf("Error opening file.\n");
return 1;
}
// buff = (char *)malloc(221553);
for(h=0;h<309;h++)
for(w=0;w<239*3;w++)
{
fread(&buff[h][w],1,1,fp);
}
*/
// Open the file for reading and writing
fbfd = open("/dev/fb0", O_RDWR);
if (!fbfd) {
perror((char *)strerror(errno));
printf("Error: cannot open framebuffer device.\n");
exit(1);
}
printf("The framebuffer device was opened successfully.\n");
retval=SetVideoMode(640,480,24);
if(retval < 0)
printf("Error setting the video mode.\n");
// Get fixed screen information
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
printf("Error reading fixed information.\n");
exit(2);
}
printf("\n%d",finfo.visual);
if(finfo.visual == FB_VISUAL_DIRECTCOLOR)
{
for(count = 0;count < 256;count++){
new_entries[(0*256)+count] =
new_entries[(1*256)+count] =
new_entries[(2*256)+count] = (count<<8)|count;
}
RestorePalette(256,new_entries);
}
/*Call the display function here.*/
retval = display();
}
void RestorePalette(int palette_len,unsigned short *area)
{
struct fb_cmap cmap;
cmap.start = 0;
cmap.len =palette_len;
cmap.red = &area[0*palette_len];
cmap.green = &area[1*palette_len];
cmap.blue = &area[2*palette_len];
cmap.transp = NULL;
ioctl(fbfd,FBIOPUTCMAP,&cmap);
}
int display()
{
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
long int screensize = 0;
char *fbp = 0;
int x = 0, y = 0;
long int location = 0;
// Get fixed screen information
if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
printf("Error reading fixed information.\n");
exit(2);
}
// Get variable screen information
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
printf("Error reading variable information.\n");
exit(3);
}
//vinfo.bits_per_pixel = 32;
#if 0
// put variable screen information
if (ioctl(fbfd, FBIOPUT_VSCREENINFO, &vinfo)) {
perror(strerror(errno));
printf("Error writing variable information.\n");
exit(3);
}
#endif
printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel );
// Figure out the size of the screen in bytes
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
// Map the device to memory
fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
fbfd, 0);
if ((int)fbp == -1) {
printf("Error: failed to map framebuffer device to memory.\n");
exit(4);
}
printf("The framebuffer device was mapped to memory successfully.\n");
x = 200; y = 200; // Where we are going to put the pixel
// Figure out where in memory to put the pixel
for ( y = 0; y < IMAGE_HEIGHT; y++ )
for ( x = 0; x < IMAGE_WIDTH;x++) {
location = finfo.line_length?finfo.line_length:vinfo.xres_virtual*3;
/**********Code for displaying Aish***************/
fbp[y*location+x*3]=buff[(y*IMAGE_WIDTH+x)*3];
fbp[y*location+x*3+1]=buff[(y*IMAGE_WIDTH+x)*3+1];
fbp[y*location+x*3+2]=buff[(y*IMAGE_WIDTH+x)*3+2];
/******************************************************/
/**********Commented for displaying Aish***************/
// fbp[y*location+x]=100;
/*fbp[y*location+x]=(x/32)*4+y-y%32;
fbp[y*location+x+1]=x-x%32;
fbp[y*location+x+2]=y-y%32;
fbp[y*location+x+3]=0;*/
/******************************************************/
/**********Seems to be wrong logic*********************/
/* location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
(y+vinfo.yoffset) * finfo.line_length;
if ( vinfo.bits_per_pixel = 32 ) {
*(fbp + location + 1) = 15; // A little green
*(fbp + location + 2) = 200; // A lot of red
*(fbp + location) = 100; // Some blue
*(fbp + location + 3) = 0; // No transparency
} else { //assume 16bpp
int r = 10;
int g = (x-100)/6; // A little green
int b = 31-(y-100)/16; // A lot of red
unsigned short int t = r<<11 | g << 5 | b;
*((unsigned short int*)(fbp + location)) = t;
}
*/
/*****************************************************/
}
munmap(fbp, screensize);
close(fbfd);
return 0;
}
int SetVideoMode(int width,int height,int bpp)
{
struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo vinfo;
int i;
char *surfaces_mem;
int surfaces_len;
int maxheight;
/* Set the terminal into graphics mode */
/* if ( FB_EnterGraphicsMode(this) < 0 ) {
* return(NULL);
* }
*/
/* Restore the original palette */
/*FB_RestorePalette(this);
*/
/* Set the video mode and get the final screen format */
if ( ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) {
perror((char *)strerror(errno));
printf("Couldn't get console screen info\n");
return(-1);
}
if ( (vinfo.xres != width) || (vinfo.yres != height) ||
(vinfo.bits_per_pixel != bpp)) {
vinfo.activate = FB_ACTIVATE_NOW;
vinfo.accel_flags = 0;
vinfo.bits_per_pixel = bpp;
vinfo.xres = width;
vinfo.xres_virtual = width;
vinfo.yres = height;
vinfo.yres_virtual = height;
vinfo.xoffset = 0;
vinfo.yoffset = 0;
vinfo.red.length = vinfo.red.offset = 0;
vinfo.green.length = vinfo.green.offset = 0;
vinfo.blue.length = vinfo.blue.offset = 0;
vinfo.transp.length = vinfo.transp.offset = 0;
if ( ioctl(fbfd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) {
vinfo.yres_virtual = height;
if ( ioctl(fbfd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) {
printf("Couldn't set console screen info");
return(-1);
}
}
} else {
maxheight = height;
/* Figure out how much video memory is available */
if ( vinfo.yres_virtual > maxheight ) {
vinfo.yres_virtual = maxheight;
}
}
/* Get the fixed information about the console hardware.
This is necessary since finfo.line_length changes.
*/
if ( ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) < 0 ) {
printf("Couldn't get console hardware info\n");
return(-1);
}
/* We're done */
return(0);
}
ashRgb.rgb
(application/octet-stream, 217.3 KB) - not displayed