⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fbi.c

📁 linux下开源图片codec
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * image viewer, for framebuffer devices * *   (c) 1998-2002 Gerd Knorr <kraxel@bytesex.org> * */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <time.h>#include <fcntl.h>#include <errno.h>#include <termios.h>#include <getopt.h>#include <math.h>#include <setjmp.h>#include <signal.h>#include <ctype.h>#include <locale.h>#include <sys/time.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <linux/fb.h>#include <jpeglib.h>#ifdef HAVE_LIBEXIF# include <libexif/exif-data.h>#endif#ifdef HAVE_LIBLIRC# include "lirc/lirc_client.h"# include "lirc.h"#endif#include "loader.h"#include "dither.h"#include "fbtools.h"#include "fb-gui.h"#include "filter.h"#include "list.h"#include "jpeg/transupp.h"		/* Support routines for jpegtran */#include "jpegtools.h"#define TRUE            1#define FALSE           0#define MAX(x,y)        ((x)>(y)?(x):(y))#define MIN(x,y)        ((x)<(y)?(x):(y))#define ARRAY_SIZE(x)   (sizeof(x)/sizeof(x[0]))#define KEY_EOF        -1       /* ^D */#define KEY_ESC        -2#define KEY_SPACE      -3#define KEY_Q          -4#define KEY_PGUP       -5#define KEY_PGDN       -6#define KEY_TIMEOUT    -7#define KEY_TAGFILE    -8#define KEY_PLUS       -9#define KEY_MINUS     -10#define KEY_VERBOSE   -11#define KEY_ASCALE    -12#define KEY_DESC      -13/* with arg */#define KEY_GOTO     -100#define KEY_SCALE    -101/* edit */#define KEY_DELETE   -200#define KEY_ROT_CW   -201#define KEY_ROT_CCW  -202#define DEFAULT_DEVICE  "/dev/fb0"/* ---------------------------------------------------------------------- *//* lirc fd */int lirc = -1;/* variables for read_image */int32_t         lut_red[256], lut_green[256], lut_blue[256];int             dither = FALSE, pcd_res = 3, steps = 50;int             textreading = 0, redraw = 0, statusline = 1;int             new_image;int             left, top;/* file list */struct flist {    int               nr;    int               tag;    char              *name;    struct list_head  list;};static LIST_HEAD(flist);static int           fcount;static struct flist  *fcurrent;/* framebuffer */char                       *fbdev = NULL;char                       *fbmode  = NULL;int                        fd, switch_last, debug;unsigned short red[256],  green[256],  blue[256];struct fb_cmap cmap  = { 0, 256, red,  green,  blue };static float fbgamma = 1;/* Command line options. */int autodown = 0;int autoup   = 0;int comments = 0;struct option fbi_options[] = {    {"version",    no_argument,       NULL, 'V'},  /* version */    {"help",       no_argument,       NULL, 'h'},  /* help */    {"device",     required_argument, NULL, 'd'},  /* device */    {"mode",       required_argument, NULL, 'm'},  /* video mode */    {"gamma",      required_argument, NULL, 'g'},  /* set gamma */    {"quiet",      no_argument,       NULL, 'q'},  /* quiet */    {"verbose",    no_argument,       NULL, 'v'},  /* verbose */    {"scroll",     required_argument, NULL, 's'},  /* set scrool */    {"timeout",    required_argument, NULL, 't'},  /* timeout value */    {"once",       no_argument,       NULL, '1'},  /* loop only once */    {"resolution", required_argument, NULL, 'r'},  /* select resolution */    {"random",     no_argument,       NULL, 'u'},  /* randomize images */    {"font",       required_argument, NULL, 'f'},  /* font */    {"autozoom",   no_argument,       NULL, 'a'},    {"edit",       no_argument,       NULL, 'e'},  /* enable editing */    {"list",       required_argument, NULL, 'l'},    {"vt",         required_argument, NULL, 'T'},    {"backup",     no_argument,       NULL, 'b'},    {"preserve",   no_argument,       NULL, 'p'},    /* long-only options */    {"autoup",     no_argument,       &autoup,   1 },    {"autodown",   no_argument,       &autodown, 1 },    {"comments",   no_argument,       &comments, 1 },    {0,0,0,0}};/* font handling */static char *fontname = NULL;/* ---------------------------------------------------------------------- */static voidversion(void){    fprintf(stderr, "fbi version " VERSION	    " (c) 1999-2003 Gerd Knorr; compiled on %s.\n", __DATE__ );}static voidusage(char *name){    char           *h;    if (NULL != (h = strrchr(name, '/')))	name = h+1;    fprintf(stderr,	    "\n"	    "This program displays images using the Linux framebuffer device.\n"	    "Supported formats: PhotoCD, jpeg, ppm, gif, tiff, xwd, bmp, png.\n"	    "It tries to use ImageMagick's convert for unknown file formats.\n"	    "\n"	    "  Usage: %s [ options ] file1 file2 ... fileN\n"	    "\n"	    "    --help       [-h]      Print this text\n"	    "    --version    [-V]      Show the fbi version number\n"	    "    --device     [-d] dev  Framebuffer device [%s]\n"	    "    --mode       [-m] mode Video mode (must be listed in /etc/fb.modes)\n"	    "                           - Default is current mode.\n"	    "    --gamma      [-g] f    Set gamma\n"	    "    --scroll     [-s] n    Set scroll steps in pixels (default: 50)\n"	    "    --quiet      [-q]      don't print anything at all\n"	    "    --verbose    [-v]      show print filenames all the time\n"	    "    --timeout    [-t] n    Load next image after N sec without any keypress\n"	    "    --once       [-1]      Don't loop (for use with -t).\n"	    "    --resolution [-r] n    Select resolution [1..5] (PhotoCD)\n"	    "    --random     [-u]      Show file1 .. fileN in a random order\n"	    "    --font       [-f] fn   Use font fn (either console psf file or\n"	    "                           X11 font spec if a font server is available\n"	    "    --autozoom   [-a]      Automagically pick useful zoom factor.\n"	    "      --autoup             Like the above, but upscale only.\n"	    "      --autodown           Like the above, but downscale only.\n"	    "    --edit       [-e]      enable editing commands (see man page).\n"	    "      --backup   [-b]      create backup files when editing.\n"	    "      --preserve [-p]      preserve timestamps when editing.\n"	    "    --list       [-l] file read list of images from file\n"	    "    --comments             display image comments\n"	    "    --vt         [-T] vt   start on console #vt\n"	    "\n"	    "Large images can be scrolled using the cursor keys.  Zoom in/out\n"	    "works with '+' and '-'.  Use ESC or 'q' to quit.  Space and PgDn\n"	    "show the next, PgUp shows the previous image. Jumping to a image\n"	    "works with <number>g.  Return acts like Space but additionally\n"	    "prints the filename of the currently displayed image to stdout.\n"	    "\n",	    name, fbdev ? fbdev : "/dev/fb0");}/* ---------------------------------------------------------------------- */static int flist_add(char *filename){    struct flist *f;    f = malloc(sizeof(*f));    memset(f,0,sizeof(*f));    f->name = strdup(filename);    list_add_tail(&f->list,&flist);    return 0;}static int flist_add_list(char *listfile){    char filename[256];    FILE *list;    list = fopen(listfile,"r");    if (NULL == list) {	fprintf(stderr,"open %s: %s\n",listfile,strerror(errno));	return -1;    }    while (NULL != fgets(filename,sizeof(filename)-1,list)) {	size_t off = strcspn(filename,"\r\n");	if (off)	    filename[off] = 0;	flist_add(filename);    }    fclose(list);    return 0;}static int flist_del(struct flist *f){    list_del(&f->list);    free(f->name);    free(f);    return 0;}static void flist_renumber(void){    struct list_head *item;    struct flist *f;    int i = 0;    list_for_each(item,&flist) {	f = list_entry(item, struct flist, list);	f->nr = ++i;    }    fcount = i;}static int flist_islast(struct flist *f){    return (&flist == f->list.next) ? 1 : 0;}static int flist_isfirst(struct flist *f){    return (&flist == f->list.prev) ? 1 : 0;}static struct flist* flist_first(void){    return list_entry(flist.next, struct flist, list);}static struct flist* flist_next(struct flist *f, int eof, int loop){    if (flist_islast(f)) {	if (eof)	    return NULL;	if (loop)	    return flist_first();	return f;    }    return list_entry(f->list.next, struct flist, list);}static struct flist* flist_prev(struct flist *f){    if (flist_isfirst(f))	return f;    return list_entry(f->list.prev, struct flist, list);}static struct flist* flist_goto(int dest){    struct list_head *item;    struct flist *f;    list_for_each(item,&flist) {	f = list_entry(item, struct flist, list);	if (f->nr == dest)	    return f;    }    return NULL;}static void flist_randomize(void){    struct flist *f;    int count;    srand((unsigned)time(NULL));    flist_renumber();    for (count = fcount; count > 0; count--) {	f = flist_goto((rand() % count)+1);	list_del(&f->list);	list_add_tail(&f->list,&flist);	flist_renumber();    }}static void flist_print_tagged(FILE *fp){    struct list_head *item;    struct flist *f;    list_for_each(item,&flist) {	f = list_entry(item, struct flist, list);	if (f->tag)	    fprintf(fp,"%s\n",f->name);    }}/* ---------------------------------------------------------------------- */static void status(unsigned char *desc, char *info){    int chars, ilen;    char *str;        if (!statusline)	return;    chars = fb_var.xres / fb_font_width();    str = malloc(chars+1);    if (info) {	ilen = strlen(info);	sprintf(str, "%-*.*s [ %s ] H - Help",		chars-14-ilen, chars-14-ilen, desc, info);    } else {	sprintf(str, "%-*.*s | H - Help", chars-11, chars-11, desc);    }    fb_status_line(str);    free(str);}static void show_error(unsigned char *msg){    fb_status_line(msg);    sleep(2);}static void show_exif(struct flist *f){#ifdef HAVE_LIBEXIF    static unsigned int tags[] = {	0x010f, // Manufacturer	0x0110, // Model	0x0112, // Orientation	0x0132, // Date and Time	0x01e3, // White Point	0x829a, // Exposure Time	0x829d, // FNumber	0x9206, // Subject Distance	0xa40c, // Subject Distance Range	0xa405, // Focal Length In 35mm Film	0x9209, // Flash    };    ExifData   *ed;    ExifEntry  *ee;    unsigned int tag,l1,l2,len,count,i;    const char *title[ARRAY_SIZE(tags)];    char *value[ARRAY_SIZE(tags)];    char *linebuffer[ARRAY_SIZE(tags)];    if (!visible)	return;    ed = exif_data_new_from_file(f->name);    if (NULL == ed) {	status("image has no EXIF data", NULL);	return;    }    /* pass one -- get data + calc size */    l1 = 0;    l2 = 0;    for (tag = 0; tag < ARRAY_SIZE(tags); tag++) {	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], tags[tag]);	if (NULL == ee)	    ee = exif_content_get_entry (ed->ifd[EXIF_IFD_EXIF], tags[tag]);	if (NULL == ee) {	    title[tag] = NULL;	    value[tag] = NULL;	    continue;	}	title[tag] = exif_tag_get_title(tags[tag]);	value[tag] = strdup(exif_entry_get_value(ee));	len = strlen(title[tag]);	if (l1 < len)	    l1 = len;	len = strlen(value[tag]);	if (l2 < len)	    l2 = len;    }    /* pass two -- print stuff */    count = 0;    for (tag = 0; tag < ARRAY_SIZE(tags); tag++) {	if (NULL == title[tag])	    continue;	linebuffer[count] = malloc(l1+l2+8);	sprintf(linebuffer[count],"%-*.*s : %-*.*s",		l1, l1, title[tag],		l2, l2, value[tag]);	count++;    }    fb_text_box(24,16,linebuffer,count);    /* pass three -- free data */    for (tag = 0; tag < ARRAY_SIZE(tags); tag++)	if (NULL != value[tag])	    free(value[tag]);    exif_data_unref (ed);    for (i = 0; i < count; i++)	free(linebuffer[i]);#else    status("compiled without EXIF support, sorry",NULL);#endif}static void show_help(void){    static char *help[] = {	"keyboard commands",	"~~~~~~~~~~~~~~~~~",	"  ESC, Q      - quit",	"  pgdn, space - next image",	"  pgup        - previous image",	"  +/-         - zoom in/out",	"  A           - autozoom image",	"  cursor keys - scroll image",	"",	"  H           - show this help text",	"  I           - show EXIF info",	"  P           - pause slideshow",	"  V           - toggle statusline",	"",	"available if started with --edit switch,",	"rotation works for jpeg images only:",	"  shift+D     - delete image",	"  R           - rotate clockwise",	"  L           - rotate counter-clockwise",    };    fb_text_box(24,16,help,ARRAY_SIZE(help));}/* ---------------------------------------------------------------------- */struct termios  saved_attributes;int             saved_fl;static voidtty_raw(void){    struct termios tattr;        fcntl(0,F_GETFL,&saved_fl);    tcgetattr (0, &saved_attributes);        fcntl(0,F_SETFL,O_NONBLOCK);    memcpy(&tattr,&saved_attributes,sizeof(struct termios));    tattr.c_lflag &= ~(ICANON|ECHO);    tattr.c_cc[VMIN] = 1;    tattr.c_cc[VTIME] = 0;    tcsetattr (0, TCSAFLUSH, &tattr);}static voidtty_restore(void){    fcntl(0,F_SETFL,saved_fl);    tcsetattr (0, TCSANOW, &saved_attributes);}/* testing: find key codes */static void debug_key(char *key){    char linebuffer[128];    int i,len;    len = sprintf(linebuffer,"key: ");    for (i = 0; key[i] != '\0'; i++)	len += sprintf(linebuffer+len, "%s%c",		       key[i] < 0x20 ? "^" : "",		       key[i] < 0x20 ? key[i] + 0x40 : key[i]);    status(linebuffer, NULL);}static voidconsole_switch(int is_busy){    switch (fb_switch_state) {    case FB_REL_REQ:	fb_switch_release();    case FB_INACTIVE:	visible = 0;	break;    case FB_ACQ_REQ:	fb_switch_acquire();    case FB_ACTIVE:	visible = 1;	redraw = 1;	ioctl(fd,FBIOPAN_DISPLAY,&fb_var);	fb_clear_screen();	if (is_busy)	    status("busy, please wait ...", NULL);			break;    default:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -