fb_display.c
上传用户:hengzhunsh
上传日期:2013-09-07
资源大小:19k
文件大小:9k
源码类别:

浏览器

开发平台:

Unix_Linux

  1. /*`
  2.     fbv  --  simple image viewer for the linux framebuffer
  3.     Copyright (C) 2000  Tomasz Sterna
  4.     Copyright (C) 2003  Mateusz Golicz
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU General Public License for more details.
  13.     You should have received a copy of the GNU General Public License
  14.     along with this program; if not, write to the Free Software
  15.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #include <linux/fb.h>
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <fcntl.h>
  23. #include <unistd.h>
  24. #include <sys/ioctl.h>
  25. #include <sys/mman.h>
  26. #include <asm/types.h>
  27. #include <string.h>
  28. #include <errno.h>
  29. #include "config.h"
  30. /* Public Use Functions:
  31.  *
  32.  * extern void fb_display(unsigned char *rgbbuff,
  33.  *     int x_size, int y_size,
  34.  *     int x_pan, int y_pan,
  35.  *     int x_offs, int y_offs);
  36.  *
  37.  * extern void getCurrentRes(int *x,int *y);
  38.  *
  39.  */
  40. unsigned short red[256], green[256], blue[256];
  41. struct fb_cmap map332 = {0, 256, red, green, blue, NULL};
  42. unsigned short red_b[256], green_b[256], blue_b[256];
  43. struct fb_cmap map_back = {0, 256, red_b, green_b, blue_b, NULL};
  44. int openFB(const char *name);
  45. void closeFB(int fh);
  46. void getVarScreenInfo(int fh, struct fb_var_screeninfo *var);
  47. void setVarScreenInfo(int fh, struct fb_var_screeninfo *var);
  48. void getFixScreenInfo(int fh, struct fb_fix_screeninfo *fix);
  49. void set332map(int fh);
  50. void* convertRGB2FB(int fh, unsigned char *rgbbuff, unsigned long count, int bpp, int *cpp);
  51. void blit2FB(int fh, void *fbbuff, unsigned char *alpha,
  52. unsigned int pic_xs, unsigned int pic_ys,
  53. unsigned int scr_xs, unsigned int scr_ys,
  54. unsigned int xp, unsigned int yp,
  55. unsigned int xoffs, unsigned int yoffs,
  56. int cpp);
  57. 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)
  58. {
  59.     struct fb_var_screeninfo var;
  60.     struct fb_fix_screeninfo fix;
  61.     unsigned short *fbbuff = NULL;
  62.     int fh = -1, bp = 0;
  63.     unsigned long x_stride;
  64.     
  65.     /* get the framebuffer device handle */
  66.     fh = openFB(NULL);
  67.     
  68.     /* read current video mode */
  69.     getVarScreenInfo(fh, &var);
  70.     getFixScreenInfo(fh, &fix);
  71.     
  72.     x_stride = (fix.line_length * 8) / var.bits_per_pixel;
  73.    
  74.     /* correct panning */
  75.     if(x_pan > x_size - x_stride) x_pan = 0;
  76.     if(y_pan > y_size - var.yres) y_pan = 0;
  77.     /* correct offset */
  78.     if(x_offs + x_size > x_stride) x_offs = 0;
  79.     if(y_offs + y_size > var.yres) y_offs = 0;
  80.     
  81.     /* blit buffer 2 fb */
  82.     fbbuff = convertRGB2FB(fh, rgbbuff, x_size * y_size, var.bits_per_pixel, &bp);
  83. #if 0
  84.     blit2FB(fh, fbbuff, alpha, x_size, y_size, x_stride, var.yres, x_pan, y_pan, x_offs, y_offs, bp);
  85. #else
  86.     blit2FB(fh, fbbuff, alpha, x_size, y_size, x_stride, var.yres_virtual, x_pan, y_pan, x_offs, y_offs + var.yoffset, bp);
  87. #endif
  88.     free(fbbuff);
  89.    
  90.     /* close device */
  91.     closeFB(fh);
  92. }
  93. void getCurrentRes(int *x, int *y)
  94. {
  95.     struct fb_var_screeninfo var;
  96.     int fh = -1;
  97.     fh = openFB(NULL);
  98.     getVarScreenInfo(fh, &var);
  99.     *x = var.xres;
  100.     *y = var.yres;
  101.     closeFB(fh);
  102. }
  103. int openFB(const char *name)
  104. {
  105.     int fh;
  106.     char *dev;
  107.     if(name == NULL){
  108. dev = getenv("FRAMEBUFFER");
  109. if(dev) name = dev;
  110. else name = DEFAULT_FRAMEBUFFER;
  111.     }
  112.     
  113.     if ((fh = open(name, O_RDWR)) == -1){
  114.         fprintf(stderr, "open %s: %sn", name, strerror(errno));
  115. exit(1);
  116.     }
  117.     return fh;
  118. }
  119. void closeFB(int fh)
  120. {
  121.     close(fh);
  122. }
  123. void getVarScreenInfo(int fh, struct fb_var_screeninfo *var)
  124. {
  125.     if (ioctl(fh, FBIOGET_VSCREENINFO, var)){
  126.         fprintf(stderr, "ioctl FBIOGET_VSCREENINFO: %sn", strerror(errno));
  127. exit(1);
  128.     }
  129. }
  130. void setVarScreenInfo(int fh, struct fb_var_screeninfo *var)
  131. {
  132.     if (ioctl(fh, FBIOPUT_VSCREENINFO, var)){
  133.         fprintf(stderr, "ioctl FBIOPUT_VSCREENINFO: %sn", strerror(errno));
  134. exit(1);
  135.     }
  136. }
  137. void getFixScreenInfo(int fh, struct fb_fix_screeninfo *fix)
  138. {
  139.     if (ioctl(fh, FBIOGET_FSCREENINFO, fix)){
  140.         fprintf(stderr, "ioctl FBIOGET_FSCREENINFO: %sn", strerror(errno));
  141. exit(1);
  142.     }
  143. }
  144. void make332map(struct fb_cmap *map)
  145. {
  146. int rs, gs, bs, i;
  147. int r = 8, g = 8, b = 4;
  148. map->red = red;
  149. map->green = green;
  150. map->blue = blue;
  151. rs = 256 / (r - 1);
  152. gs = 256 / (g - 1);
  153. bs = 256 / (b - 1);
  154. for (i = 0; i < 256; i++) {
  155. map->red[i]   = (rs * ((i / (g * b)) % r)) * 255;
  156. map->green[i] = (gs * ((i / b) % g)) * 255;
  157. map->blue[i]  = (bs * ((i) % b)) * 255;
  158. }
  159. }
  160. void set8map(int fh, struct fb_cmap *map)
  161. {
  162.     if (ioctl(fh, FBIOPUTCMAP, map) < 0) {
  163.         fprintf(stderr, "Error putting colormap");
  164.         exit(1);
  165.     }
  166. }
  167. void get8map(int fh, struct fb_cmap *map)
  168. {
  169.     if (ioctl(fh, FBIOGETCMAP, map) < 0) {
  170.         fprintf(stderr, "Error getting colormap");
  171.         exit(1);
  172.     }
  173. }
  174. void set332map(int fh)
  175. {
  176.     make332map(&map332);
  177.     set8map(fh, &map332);
  178. }
  179. void blit2FB(int fh, void *fbbuff, unsigned char *alpha,
  180. unsigned int pic_xs, unsigned int pic_ys,
  181. unsigned int scr_xs, unsigned int scr_ys,
  182. unsigned int xp, unsigned int yp,
  183. unsigned int xoffs, unsigned int yoffs,
  184. int cpp)
  185. {
  186.     int i, xc, yc;
  187. unsigned char *fb;
  188. unsigned char *fbptr;
  189. unsigned char *imptr;
  190.     xc = (pic_xs > scr_xs) ? scr_xs : pic_xs;
  191.     yc = (pic_ys > scr_ys) ? scr_ys : pic_ys;
  192.     
  193. fb = mmap(NULL, scr_xs * scr_ys * cpp, PROT_WRITE | PROT_READ, MAP_SHARED, fh, 0);
  194. if(fb == MAP_FAILED)
  195. {
  196. perror("mmap");
  197. return;
  198. }
  199. if(cpp == 1)
  200. {
  201.     get8map(fh, &map_back);
  202.     set332map(fh);
  203. }
  204. fbptr = fb     + (yoffs * scr_xs + xoffs) * cpp;
  205. imptr = fbbuff + (yp * pic_xs + xp) * cpp;
  206. if(alpha)
  207. {
  208.   unsigned char * alphaptr;
  209. int from, to, x;
  210. alphaptr = alpha + (yp * pic_xs + xp);
  211. for(i = 0; i < yc; i++, fbptr += scr_xs * cpp, imptr += pic_xs * cpp, alphaptr += pic_xs)
  212. {
  213. for(x = 0; x<xc; x++)
  214. {
  215. int v;
  216. from = to = -1;
  217. for(v = x; v<xc; v++)
  218. {
  219. if(from == -1)
  220. {
  221. if(alphaptr[v] > 0x80) from = v;
  222. }
  223. else
  224. {
  225. if(alphaptr[v] < 0x80)
  226. {
  227. to = v;
  228. break;
  229. }
  230. }
  231. }
  232. if(from == -1)
  233. break;
  234. if(to == -1) to = xc;
  235. memcpy(fbptr + (from * cpp), imptr + (from * cpp), (to - from - 1) * cpp);
  236. x += to - from - 1;
  237. }
  238. }
  239. }
  240. else
  241.     for(i = 0; i < yc; i++, fbptr += scr_xs * cpp, imptr += pic_xs * cpp)
  242. memcpy(fbptr, imptr, xc * cpp);
  243. if(cpp == 1)
  244.     set8map(fh, &map_back);
  245. munmap(fb, scr_xs * scr_ys * cpp);
  246. }
  247. inline static unsigned char make8color(unsigned char r, unsigned char g, unsigned char b)
  248. {
  249.     return (
  250. (((r >> 5) & 7) << 5) |
  251. (((g >> 5) & 7) << 2) |
  252.  ((b >> 6) & 3)       );
  253. }
  254. inline static unsigned short make15color(unsigned char r, unsigned char g, unsigned char b)
  255. {
  256.     return (
  257. (((r >> 3) & 31) << 10) |
  258. (((g >> 3) & 31) << 5)  |
  259.  ((b >> 3) & 31)        );
  260. }
  261. inline static unsigned short make16color(unsigned char r, unsigned char g, unsigned char b)
  262. {
  263.     return (
  264. (((r >> 3) & 31) << 11) |
  265. (((g >> 2) & 63) << 5)  |
  266.  ((b >> 3) & 31)        );
  267. }
  268. void* convertRGB2FB(int fh, unsigned char *rgbbuff, unsigned long count, int bpp, int *cpp)
  269. {
  270.     unsigned long i;
  271.     void *fbbuff = NULL;
  272. u_int8_t  *c_fbbuff;
  273.     u_int16_t *s_fbbuff;
  274.     u_int32_t *i_fbbuff;
  275.     switch(bpp)
  276.     {
  277. case 8:
  278.     *cpp = 1;
  279.     c_fbbuff = (unsigned char *) malloc(count * sizeof(unsigned char));
  280.     for(i = 0; i < count; i++)
  281. c_fbbuff[i] = make8color(rgbbuff[i*3], rgbbuff[i*3+1], rgbbuff[i*3+2]);
  282.     fbbuff = (void *) c_fbbuff;
  283.     break;
  284. case 15:
  285.     *cpp = 2;
  286.     s_fbbuff = (unsigned short *) malloc(count * sizeof(unsigned short));
  287.     for(i = 0; i < count ; i++)
  288. s_fbbuff[i] = make15color(rgbbuff[i*3], rgbbuff[i*3+1], rgbbuff[i*3+2]);
  289.     fbbuff = (void *) s_fbbuff;
  290.     break;
  291. case 16:
  292.     *cpp = 2;
  293.     s_fbbuff = (unsigned short *) malloc(count * sizeof(unsigned short));
  294.     for(i = 0; i < count ; i++)
  295. s_fbbuff[i] = make16color(rgbbuff[i*3], rgbbuff[i*3+1], rgbbuff[i*3+2]);
  296.     fbbuff = (void *) s_fbbuff;
  297.     break;
  298. case 24:
  299. case 32:
  300.     *cpp = 4;
  301.     i_fbbuff = (unsigned int *) malloc(count * sizeof(unsigned int));
  302.     for(i = 0; i < count ; i++)
  303. i_fbbuff[i] = ((rgbbuff[i*3] << 16) & 0xFF0000) |
  304.     ((rgbbuff[i*3+1] << 8) & 0xFF00) |
  305.     (rgbbuff[i*3+2] & 0xFF);
  306.     fbbuff = (void *) i_fbbuff;
  307.     break;
  308. default:
  309.     fprintf(stderr, "Unsupported video mode! You've got: %dbppn", bpp);
  310.     exit(1);
  311.     }
  312.     return fbbuff;
  313. }