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

📄 vgadisp.c

📁 zgv-5.6,一个Linux系统下的图片浏览器(VGA/SVGA)
💻 C
📖 第 1 页 / 共 5 页
字号:
/* zgv 5.6 - GIF, JPEG and PBM/PGM/PPM viewer, for VGA PCs running Linux. * Copyright (C) 1993-2002 Russell Marks. See README for license details. * * vgadisp.c - VGA-specific display routines. */#include <stdio.h>#include <string.h>#include <math.h>		/* for pow() */#include <unistd.h>#include <stdlib.h>#include <signal.h>#include <sys/file.h>#include <vga.h>#include <vgagl.h>#include <vgamouse.h>#include "zgv.h"#include "magic.h"#include "readgif.h"#include "readjpeg.h"#include "readpnm.h"#include "readbmp.h"#include "readpng.h"#include "readtga.h"#include "readpcx.h"#include "readxvpic.h"#include "readmrf.h"#include "readxbm.h"#include "readxpm.h"#include "readpcd.h"#include "readtiff.h"#include "readprf.h"#include "readnbkey.h"#include "helppage.h"#include "3deffects.h"#include "rc_config.h"#include "rcfile.h"#include "mousecur.h"#include "rbmenu.h"#include "modesel.h"#include "vgadisp.h"/* zgv.c initialises these */int curvgamode;int zoom,virtual;int vkludge;int pixelsize;		/* in bytes - 1 for 8-bit, 3 for 24-bit */int pic_incr;		/* after view, 0=stay, -1=prev, 1=next *//* for right-buttom menu */static int rb_ignore_first_left_click=0;static unsigned char *rb_save=NULL;static int rb_save_width,rb_save_height;char *viewerhelp[]=  {  "? (question mark)\\this help page",  "/\\show video mode selection help",  " ",  "v\\toggle smoothing in virtual/zoom modes",  "comma/dot\\contrast down/up",  "less-than/greater-than\\brightness down/up",  "semicolon\\reset contrast and brightness",  "z\\toggle zoomed mode",  "r\\rotate clockwise 90 degrees",  "m\\mirror",  "f\\flip",  "d\\double size of picture",  "D\\halve size of picture",  "Esc or x\\exit the viewer",  " ",  "hjkl or qaop keys scroll around the picture",  "HJKL or QAOP (also the cursor keys) scroll in bigger steps",  ""	/* end */  };char *viewermodeshelp[]=  {  "Generic VGA modes:",  "5 - 320x200x8\\6 - 320x240x8\\",  "7 - 320x400x8\\8 - 360x480x8\\0 - 640x480x4",  " ",  "SVGA modes (try these first):",  "F1 - 640x480x8\\F2 - 800x600x8\\F3 - 1024x768x8",  "F4 - 1280x1024x8\\F5 - 320x200x15\\F6 - 320x200x16",  "F7 - 320x200x24\\F8 - 640x480x15\\F9 - 640x480x16",  "F10 - 640x480x24\\SF1 - 800x600x15\\SF2 - 800x600x16",  "SF3 - 800x600x24\\SF4 - 1024x768x15\\SF5 - 1024x768x16",  "SF6 - 1024x768x24\\SF7 - 1280x1024x15\\SF8 - 1280x1024x16",  "Tab-F1 - 1280x1024x24\\Tab-F2 - 1152x864x8\\Tab-F3 - 1152x864x15",  "Tab-F4 - 1152x864x16\\Tab-F5 - 1152x864x24\\Tab-F6 - 1600x1200x8",  "Tab-F7 - 1600x1200x15\\Tab-F8 - 1600x1200x16\\Tab-F9 - 1600x1200x24",  " ",  "Or to browse modes:\\[ - lower-res mode\\] - higher-res mode",  ""	/* end */  };struct rbm_data_tag viewer_menu_data[]=  {  /* 31 chars max for label text */  {1, "Exit viewer",		RK_ESC		},    /* stuff in draw_rb_menu which sets the active field of these   * mode buttons assumes they are in *exactly* this order/position.   * So don't change anything before the "Normal" button without   * thinking twice... or more. :-)   *   * modes less than 480 pixels high are omitted here since   * the mouse menu is disabled on those.   */  {1, "360x480x8",		'8'		},  {1, "640x480x4",		'0'		},  {1, "640x480x8",		RK_F1		},  {1, "800x600x8",		RK_F2		},  {1, "1024x768x8",		RK_F3		},  {1, "640x480x15",		RK_F8		},  {1, "640x480x16",		RK_F9		},  {1, "640x480x24",		RK_F10		},  {1, "800x600x15",		RK_SHIFT_F1	},  {1, "800x600x16",		RK_SHIFT_F2	},  {1, "800x600x24",		RK_SHIFT_F3	},  {1, "1024x768x15",		RK_SHIFT_F4	},  {1, "1024x768x16",		RK_SHIFT_F5	},  {1, "1024x768x24",		RK_SHIFT_F6	},  {1, "Next file",		RK_ENTER	},  {1, " ...tag first",		' '		},  /* no gap thing here, due to split between columns */    {1, "Normal size",		'n'		},  {1, "Zoom on/off",		'z'		},  {1, " ...smooth on/off",	'v'		},  {1, "Scale up 1",		's'		},  {1, "Scale down 1",		'S'		},  {1, "Scale up x2",		'd'		},  {1, "Scale down x2",		'D'		},  {1, " ...smooth on/off",	'i'		},  {1, "Normal orient'n",	128+'n'		},  {1, "Save orient'n",		128+'s'		},  {1, "Use last orient'n",	128+'o'		},  {1, "Rotate c/w",		'r'		},  {1, "Rotate anti-c/w",	'R'		},  {1, "Mirror",			'm'		},  {1, "Flip",			'f'		},  /* this next one seems bizarre, but it's to the right of "next file" */  {1, "Previous file",		127		},  {1, "4-bit grey/colour",	'c'		},    {0,"",0}  };unsigned char vkcache[32768],vkcache_valid[32768];#define MOVSTP 10    /* for q,a,o,p panning */#define BIGSTP 100   /* for Q,A,O,P panning (i.e. with shift) */#define FIX_TO_EIGHT_BIT	1#define FIX_TO_HIGHCOLOUR	2byte *theimage;   /* quite slow if passed as parameter */int width,height,numcols; /* same here */byte *image_palette;double contrast=1.0;  /* note that double contrast is in fact 2 :-) */int brightness=0;double picgamma=1.0;double initial_picgamma=1.0;	/* value set by `4' */int scaling=1,interp=0,inextpix=1;int scrnwide,scrnhigh,scrnpixelsize,scrncols;int palr[256],palg[256],palb[256];byte palr64[256],palg64[256],palb64[256], palt[256];int palrgb[768];unsigned char pal32_no_bc[768];unsigned char dither16_greylookup[256];unsigned char dither16_rgb[768];volatile int repeat_sig;int first_repeat;int loading_file_type;int saved_px,saved_py;		/* for persistance in cfg.repeat_timer mode *//* grey values for rgb - NTSC uses these (adding up to 1000) */static int grey_red=299,grey_green=587,grey_blue=114;int sgres;static int override_zoom_clear=0;/* Scary orientation stuff * ----------------------- * * There are eight possible orientations (0 is the original image): *                             _____     _____  *    _______     _______     |    a|   |    b| *   |a      |   |b      |    |     |   |     | *   |   0   |   |   1   |    |  4  |   |  5  | *   |______b|   |______a|    |b____|   |a____| *    _______     _______      _____     _____  *   |      b|   |      a|    |b    |   |a    | *   |   2   |   |   3   |    |     |   |     | *   |a______|   |b______|    |  6  |   |  7  | *                            |____a|   |____b| * * That gives us these changes in orientation state for each of the * orientation-changing operations (rotate, mirror, flip): * * 		rot-cw	rot-acw	mirror	flip * 0 to...	4	5	3	2 * 1 to...	5	4	2	3 * 2 to...	7	6	1	0 * 3 to...	6	7	0	1 * 4 to...	1	0	7	6 * 5 to...	0	1	6	7 * 6 to...	2	3	5	4 * 7 to...	3	2	4	5 */int orient_state_rot_cw[8] ={4,5,7,6,1,0,2,3};int orient_state_rot_acw[8]={5,4,6,7,0,1,3,2};int orient_state_mirror[8] ={3,2,1,0,7,6,5,4};int orient_state_flip[8]   ={2,3,0,1,6,7,4,5};int orient_override=0;		/* override orientation (used by Alt-s) */int orient_override_state=0;#define GET32BITCOLOUR(r,g,b) (b|(g<<8)|(r<<16))/* indirection needed to allow high-colour brightness/contrast */typedef void (*eventuallyfunc)(byte *,int,int,int);eventuallyfunc eventuallydrawscansegment=NULL;int doing_hicol_bc=0;	/* non-zero if doing hi-col b/c in current redraw *//* prototypes */int readpicture(char *giffn,hffunc howfarfunc,int show_dont_tell,	int quick,int *real_width,int *real_height);int has_highcolour_mode(void);void fix_to_similar_mode(int modetype);void aborted_file_cleanup(void);int is_this_file_jpeg(void);void makerealpal(void);void filterpal(byte *palette);int dimmer(int a);int contrastup(int cp);int apply_gamma(int val);int get_mode_width(int vm);int get_mode_height(int vm);int get_mode_pixelbytes(int vm);int get_mode_numcols(int vm);void setmode_or_clear(int newmode);void init_vkludge_cache(void);void graphicson(void);void graphicsoff(void);int mode_is_usable_now(int modenum);int showgif(char *filename,byte *palette);static void draw_rb_menu(void);static void undraw_rb_menu(void);static int rb_menu_event(int *keyp);void repeat_sighandler(int foo);void setpalvec(int start,int num,int *pal);void redrawgif(int px, int py, int npx, int npy);void eventuallydrawscansegment_without_bc(byte *ptr, int x, int y, int len);void eventuallydrawscansegment_with_bc(byte *ptr, int x, int y, int len);void dither16scansegment(unsigned char *ptr,int x,int y,int len);int getvpix(int px, int py, int x, int y);void drawzoomedgif(void);void fx_mirror(void);void fx_flip(void);void fx_rot(void);int closest(int r, int g, int b);void samecentre(int *ppx, int *ppy, int newscale, int oldpx, int oldpy, int oldscale);void show_dimensions(int px, int py, int scaling);void orient_change_state(int from,int to,int clear_if_rot);int animate_gif(int orient_state);/* to read a picture only, set show_dont_tell=0. * If you're only reading the picture, not showing it, then: * 1. picture is returned in global vars. 'theimage' and 'image_palette' * 2. you have to set pixelsize=whatever and restore it afterwards. * 3. you have to free() both theimage and image_palette when finished. * * The `quick' arg sets whether or not to ask the jpeg decoder for a * rough image. This is useful when doing thumbnails, where we don't * need the accuracy, but you shouldn't use it elsewhere. * * `real_width' and `real_height' give the true width/height of the * image (useful if using `quick', and a smaller image was returned). * Set them to NULL if you don't care. */int readpicture(char *giffn,hffunc howfarfunc,int show_dont_tell,	int quick,int *real_width,int *real_height){int result=0;PICINFO ginfo;byte *palette=NULL;int realset=0;first_repeat=1;gif_delaycount=0;do  {  ginfo.numcols=256;	/* only changes for GIF files */  theimage=NULL;  if(!first_repeat) howfarfunc=NULL;    switch(loading_file_type=magic_ident(giffn))    {    case _IS_GIF:      /* part of the New Strategy (tm); always use 8-bit for GIFs.       * fix the mode to a similar 8-bit one if possible.       */      if(show_dont_tell) fix_to_similar_mode(FIX_TO_EIGHT_BIT);      result=read_gif_file(giffn,howfarfunc,&theimage,&palette,      			&pixelsize,&ginfo);      height=ginfo.height; width=ginfo.width;      break;        case _IS_JPEG:      /* don't *always* use 24-bit for JPEGs... check for 15/16/24-bit       * video modes before doing so, as well as the config.       */      if(show_dont_tell)        {        pixelsize=has_highcolour_mode()?3:1;        if(pixelsize==3 && cfg.jpeg24bit==0)          pixelsize=1;        }        theimage=NULL;      result=read_JPEG_file(giffn,howfarfunc,&palette,      		quick,real_width,real_height);      realset=1;            /* if error, then palette has already been nuked, so only       * need to deal with the image.       */      if(theimage!=NULL && result!=_PIC_OK) { free(theimage); theimage=NULL; }            break;          case _IS_PNG:      if(show_dont_tell)        {        pixelsize=has_highcolour_mode()?3:1;        if(pixelsize==3 && cfg.jpeg24bit==0)          pixelsize=1;        }        theimage=NULL;      result=read_png_file(giffn,howfarfunc,&palette);            /* if error, then palette has already been nuked, so only       * need to deal with the image.       */      if(theimage!=NULL && result!=_PIC_OK)        {        if(cfg.errignore)          result=_PIC_OK;        else          { free(theimage); theimage=NULL; }        }              break;          case _IS_PNM: case _IS_BMP: case _IS_TGA: case _IS_PCX:    case _IS_XVPIC: case _IS_MRF: case _IS_PCD:    case _IS_XBM: case _IS_XPM: case _IS_TIFF:    case _IS_PRF:      if(show_dont_tell) pixelsize=has_highcolour_mode()?3:1;      switch(loading_file_type)        {        case _IS_PNM:          result=read_pnm_file(giffn,howfarfunc,&theimage,&palette,&pixelsize,                  &ginfo); break;        case _IS_TIFF:          result=read_tiff_file(giffn,howfarfunc,&theimage,&palette,&pixelsize,                  &ginfo); break;        case _IS_BMP:          result=read_bmp_file(giffn,howfarfunc,&theimage,&palette,&pixelsize,                  &ginfo); break;        case _IS_TGA:          result=read_tga_file(giffn,howfarfunc,&theimage,&palette,&pixelsize,                  &ginfo); break;	case _IS_PCX:          result=read_pcx_file(giffn,howfarfunc,&theimage,&palette,&pixelsize,                  &ginfo); break;	case _IS_XVPIC:          result=read_xvpic(giffn,howfarfunc,&theimage,&palette,&pixelsize,                  &ginfo); break;	case _IS_MRF:          result=read_mrf_file(giffn,howfarfunc,&theimage,&palette,&pixelsize,                  &ginfo); break;        case _IS_PRF:          result=read_prf_file(giffn,howfarfunc,&theimage,&palette,&pixelsize,                  &ginfo); break;	case _IS_XBM:          result=read_xbm_file(giffn,howfarfunc,&theimage,&palette,&pixelsize,                  &ginfo); break;#ifdef PCD_SUPPORT        case _IS_PCD:          result=read_pcd_file(giffn,howfarfunc,&theimage,&palette,&pixelsize,                  &ginfo); break;#endif        case _IS_XPM:          result=read_xpm_file(giffn,howfarfunc,&theimage,&palette,&pixelsize,                  &ginfo); break;        }            width=ginfo.width;      height=ginfo.height;      if(result!=_PIC_OK)        {        gif_delaycount=0;	/* ignore any animation stuff */                if(theimage!=NULL) { free(theimage); theimage=NULL; }        if(palette!=NULL)  { free(palette);  palette=NULL; }        }      else        if(loading_file_type==_IS_TGA && tga_need_flip)          fx_flip();	/* right way up! */      break;        /* if they voted for "none of the above"... */    default:      return(_PICERR_BADMAGIC);    }      if(!realset)    {    if(real_width) *real_width=width;    if(real_height) *real_height=height;    realset=1;    }    if(show_dont_tell)    {    if(pixelsize==3)      fix_to_similar_mode(FIX_TO_HIGHCOLOUR);    else      fix_to_similar_mode(FIX_TO_EIGHT_BIT);      if(result==_PIC_OK)      {      numcols=ginfo.numcols;      sgres=showgif(giffn,palette);      free(theimage);      free(palette);      }    }  else    image_palette=palette;  }while(show_dont_tell && cfg.repeat_timer && result==_PIC_OK && sgres==0);return(result);}/* modes aren't counted if they're locked out */int has_highcolour_mode(){struct modedesc_tag *md_ptr;if(cfg.hicolmodes) return(1);	/* forces positive response */for(md_ptr=modedesc;md_ptr->mode;md_ptr++)  if(md_ptr->bitspp>=15 &&     vga_hasmode(md_ptr->mode) && cfg.mode_allowed[md_ptr->mode])    return(1);return(0);}/* since we've already tested if it's possible, this can't fail */void fix_to_similar_mode(int modetype){int f,newmode,numpixels,pixdiff,newnp,newdiff,mode_ok;vga_modeinfo *vminfo;

⌨️ 快捷键说明

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