2 fbv -- simple image viewer for the linux framebuffer
3 Copyright (C) 2000 Tomasz Sterna
4 Copyright (C) 2003 Mateusz Golicz
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include <sys/types.h>
27 #include <sys/ioctl.h>
29 #include <asm/types.h>
35 /* Public Use Functions:
37 * extern void fb_display(unsigned char *rgbbuff,
38 * int x_size, int y_size,
39 * int x_pan, int y_pan,
40 * int x_offs, int y_offs);
42 * extern void getCurrentRes(int *x,int *y);
46 unsigned short red
[256], green
[256], blue
[256];
47 struct fb_cmap map332
= {0, 256, red
, green
, blue
, NULL
};
48 unsigned short red_b
[256], green_b
[256], blue_b
[256];
49 struct fb_cmap map_back
= {0, 256, red_b
, green_b
, blue_b
, NULL
};
52 int openFB(const char *name
);
54 void getVarScreenInfo(int fh
, struct fb_var_screeninfo
*var
);
55 void setVarScreenInfo(int fh
, struct fb_var_screeninfo
*var
);
56 void getFixScreenInfo(int fh
, struct fb_fix_screeninfo
*fix
);
57 void set332map(int fh
);
58 void* convertRGB2FB(int fh
, unsigned char *rgbbuff
, unsigned long count
, int bpp
, int *cpp
);
59 void blit2FB(int fh
, void *fbbuff
, unsigned char *alpha
,
60 unsigned int pic_xs
, unsigned int pic_ys
,
61 unsigned int scr_xs
, unsigned int scr_ys
,
62 unsigned int xp
, unsigned int yp
,
63 unsigned int xoffs
, unsigned int yoffs
,
66 void fb_display(unsigned char *rgbbuff
, unsigned char * alpha
, int x_size
, int y_size
, int x_pan
, int y_pan
, int x_offs
, int y_offs
)
68 struct fb_var_screeninfo var
;
69 struct fb_fix_screeninfo fix
;
70 unsigned short *fbbuff
= NULL
;
72 unsigned long x_stride
;
74 /* get the framebuffer device handle */
77 /* read current video mode */
78 getVarScreenInfo(fh
, &var
);
79 getFixScreenInfo(fh
, &fix
);
81 x_stride
= (fix
.line_length
* 8) / var
.bits_per_pixel
;
84 if(x_pan
> x_size
- x_stride
) x_pan
= 0;
85 if(y_pan
> y_size
- var
.yres
) y_pan
= 0;
87 if(x_offs
+ x_size
> x_stride
) x_offs
= 0;
88 if(y_offs
+ y_size
> var
.yres
) y_offs
= 0;
90 /* blit buffer 2 fb */
91 fbbuff
= convertRGB2FB(fh
, rgbbuff
, x_size
* y_size
, var
.bits_per_pixel
, &bp
);
93 blit2FB(fh
, fbbuff
, alpha
, x_size
, y_size
, x_stride
, var
.yres
, x_pan
, y_pan
, x_offs
, y_offs
, bp
);
95 blit2FB(fh
, fbbuff
, alpha
, x_size
, y_size
, x_stride
, var
.yres_virtual
, x_pan
, y_pan
, x_offs
, y_offs
+ var
.yoffset
, bp
);
103 void getCurrentRes(int *x
, int *y
)
105 struct fb_var_screeninfo var
;
108 getVarScreenInfo(fh
, &var
);
114 int openFB(const char *name
)
120 dev
= getenv("FRAMEBUFFER");
122 else name
= DEFAULT_FRAMEBUFFER
;
125 if ((fh
= open(name
, O_RDWR
)) == -1){
126 fprintf(stderr
, "open %s: %s\n", name
, strerror(errno
));
137 void getVarScreenInfo(int fh
, struct fb_var_screeninfo
*var
)
139 if (ioctl(fh
, FBIOGET_VSCREENINFO
, var
)){
140 fprintf(stderr
, "ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno
));
145 void setVarScreenInfo(int fh
, struct fb_var_screeninfo
*var
)
147 if (ioctl(fh
, FBIOPUT_VSCREENINFO
, var
)){
148 fprintf(stderr
, "ioctl FBIOPUT_VSCREENINFO: %s\n", strerror(errno
));
153 void getFixScreenInfo(int fh
, struct fb_fix_screeninfo
*fix
)
155 if (ioctl(fh
, FBIOGET_FSCREENINFO
, fix
)){
156 fprintf(stderr
, "ioctl FBIOGET_FSCREENINFO: %s\n", strerror(errno
));
161 void make332map(struct fb_cmap
*map
)
164 int r
= 8, g
= 8, b
= 4;
174 for (i
= 0; i
< 256; i
++) {
175 map
->red
[i
] = (rs
* ((i
/ (g
* b
)) % r
)) * 255;
176 map
->green
[i
] = (gs
* ((i
/ b
) % g
)) * 255;
177 map
->blue
[i
] = (bs
* ((i
) % b
)) * 255;
181 void set8map(int fh
, struct fb_cmap
*map
)
183 if (ioctl(fh
, FBIOPUTCMAP
, map
) < 0) {
184 fprintf(stderr
, "Error putting colormap");
189 void get8map(int fh
, struct fb_cmap
*map
)
191 if (ioctl(fh
, FBIOGETCMAP
, map
) < 0) {
192 fprintf(stderr
, "Error getting colormap");
197 void set332map(int fh
)
200 set8map(fh
, &map332
);
203 void blit2FB(int fh
, void *fbbuff
, unsigned char *alpha
,
204 unsigned int pic_xs
, unsigned int pic_ys
,
205 unsigned int scr_xs
, unsigned int scr_ys
,
206 unsigned int xp
, unsigned int yp
,
207 unsigned int xoffs
, unsigned int yoffs
,
213 unsigned char *fbptr
;
214 unsigned char *imptr
;
216 xc
= (pic_xs
> scr_xs
) ? scr_xs
: pic_xs
;
217 yc
= (pic_ys
> scr_ys
) ? scr_ys
: pic_ys
;
219 fb
= mmap(NULL
, scr_xs
* scr_ys
* cpp
, PROT_WRITE
| PROT_READ
, MAP_SHARED
, fh
, 0);
229 get8map(fh
, &map_back
);
233 fbptr
= fb
+ (yoffs
* scr_xs
+ xoffs
) * cpp
;
234 imptr
= fbbuff
+ (yp
* pic_xs
+ xp
) * cpp
;
238 unsigned char * alphaptr
;
241 alphaptr
= alpha
+ (yp
* pic_xs
+ xp
);
243 for(i
= 0; i
< yc
; i
++, fbptr
+= scr_xs
* cpp
, imptr
+= pic_xs
* cpp
, alphaptr
+= pic_xs
)
245 for(x
= 0; x
<xc
; x
++)
250 for(v
= x
; v
<xc
; v
++)
254 if(alphaptr
[v
] > 0x80) from
= v
;
258 if(alphaptr
[v
] < 0x80)
268 if(to
== -1) to
= xc
;
270 memcpy(fbptr
+ (from
* cpp
), imptr
+ (from
* cpp
), (to
- from
- 1) * cpp
);
276 for(i
= 0; i
< yc
; i
++, fbptr
+= scr_xs
* cpp
, imptr
+= pic_xs
* cpp
)
277 memcpy(fbptr
, imptr
, xc
* cpp
);
280 set8map(fh
, &map_back
);
282 munmap(fb
, scr_xs
* scr_ys
* cpp
);
285 inline static unsigned char make8color(unsigned char r
, unsigned char g
, unsigned char b
)
288 (((r
>> 5) & 7) << 5) |
289 (((g
>> 5) & 7) << 2) |
293 inline static unsigned short make15color(unsigned char r
, unsigned char g
, unsigned char b
)
296 (((r
>> 3) & 31) << 10) |
297 (((g
>> 3) & 31) << 5) |
301 inline static unsigned short make16color(unsigned char r
, unsigned char g
, unsigned char b
)
304 (((r
>> 3) & 31) << 11) |
305 (((g
>> 2) & 63) << 5) |
309 void* convertRGB2FB(int fh
, unsigned char *rgbbuff
, unsigned long count
, int bpp
, int *cpp
)
321 c_fbbuff
= (unsigned char *) malloc(count
* sizeof(unsigned char));
322 for(i
= 0; i
< count
; i
++)
323 c_fbbuff
[i
] = make8color(rgbbuff
[i
*3], rgbbuff
[i
*3+1], rgbbuff
[i
*3+2]);
324 fbbuff
= (void *) c_fbbuff
;
328 s_fbbuff
= (unsigned short *) malloc(count
* sizeof(unsigned short));
329 for(i
= 0; i
< count
; i
++)
330 s_fbbuff
[i
] = make15color(rgbbuff
[i
*3], rgbbuff
[i
*3+1], rgbbuff
[i
*3+2]);
331 fbbuff
= (void *) s_fbbuff
;
335 s_fbbuff
= (unsigned short *) malloc(count
* sizeof(unsigned short));
336 for(i
= 0; i
< count
; i
++)
337 s_fbbuff
[i
] = make16color(rgbbuff
[i
*3], rgbbuff
[i
*3+1], rgbbuff
[i
*3+2]);
338 fbbuff
= (void *) s_fbbuff
;
343 i_fbbuff
= (unsigned int *) malloc(count
* sizeof(unsigned int));
344 for(i
= 0; i
< count
; i
++)
345 i_fbbuff
[i
] = ((rgbbuff
[i
*3] << 16) & 0xFF0000) |
346 ((rgbbuff
[i
*3+1] << 8) & 0xFF00) |
347 (rgbbuff
[i
*3+2] & 0xFF);
348 fbbuff
= (void *) i_fbbuff
;
351 fprintf(stderr
, "Unsupported video mode! You've got: %dbpp\n", bpp
);