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

📄 viewfax.c

📁 涉及Fax/Mail/Voice通讯编程的一个程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Program to view fax files on an X-window screen   Copyright (C) 1990, 1995  Frank D. Cringle.This file is part of viewfax - g3/g4 fax processing software.     viewfax is free software; you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation; either version 2 of the License, or (at youroption) any later version.     This program is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNUGeneral Public License for more details.     You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include <stdlib.h>#include <stdio.h>#include <string.h>#include <sys/time.h>/* NewImage() needs to fiddle with the Display structure */#define XLIB_ILLEGAL_ACCESS#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/Xatom.h>#include <X11/keysym.h>#include <X11/keysymdef.h>#include <X11/cursorfont.h>#include "faxexpand.h"#define VERSION "2.4"/* If moving the image around with the middle mouse button is jerky or   slow, try defining USE_MOTIONHINT.  It may help (it may also make   things worse - it depends on the server implementation) */#undef USE_MOTIONHINTstruct pagenode *firstpage, *lastpage, *thispage, *helppage;struct pagenode defaultpage;/* access the 'extra' field in a pagenode */#define Pimage(p)	((XImage *)(p)->extra)/* getopt declarations */extern int getopt();extern char *optarg;extern int optind, opterr, optopt;/* forward declarations */static XImage *FlipImage(XImage *xi);static XImage *MirrorImage(XImage *xi);static XImage *NewImage(int w, int h, char *data, int bit_order);static XImage *RotImage(XImage *Image);static XImage *ZoomImage(XImage *Big);static void FreeImage(XImage *Image);static int GetImage(struct pagenode *pn);static void SetupDisplay(int argc, char **argv);static void ShowLoop(void);static int release(int quit);static char *suffix(char *opt, const char *str);/* X variables */static char *DispName = NULL;static char *Geometry = NULL;static Display *Disp;static Window Root;static Window Win;static int Default_Screen;static GC PaintGC;static Cursor WorkCursor;static Cursor ReadyCursor;static Cursor MoveCursor;static Cursor LRCursor;static Cursor UDCursor;char *ProgName;int verbose = 0;static int abell = 0;			/* audio bell */static int vbell = 1;			/* visual bell */static int zfactor = 0;			/* zoom factor */static size_t Memused = 0;		/* image memory usage */static size_t Memlimit = 4*1024*1024;	/* try not to exceed */#undef min#undef max#define min(a,b)	((a)<(b)?(a):(b))#define max(a,b)	((a)>(b)?(a):(b))#ifndef EXIT_FAILURE#define EXIT_FAILURE 1#endif/* OK, OK - this is a dreadful hack.  But it adequately distinguishes   modern big- and little- endian hosts.  We only need this to set the   byte order in XImage structures */static union { t32bits i; unsigned char b[4]; } bo;#define ByteOrder	bo.b[3]static char Banner[] ="\nviewfax version " VERSION ", Copyright (C) 1990, 1995 Frank D. Cringle.\n""viewfax comes with ABSOLUTELY NO WARRANTY; for details see the\n""file \"COPYING\" in the distribution directory.\n\n";static char Usage[] ="usage: %s <flags> file ...\n""\t-f\tfine resolution (default unless filename begins with 'fn')\n""\t-n\tnormal resolution\n""\t-h\theight (number of fax lines)\n""\t-w\twidth (dots per fax line)\n""\t-l\tturn image 90 degrees (landscape mode)\n""\t-u\tturn image upside down\n""\t-i\tinvert (black/white)\n""\t-d\t(or -display) use an alternate X display\n""\t-g\t(or -geometry) size and position of window\n""\t-b\tuse audio (-ba) or visual (-bv) warning bell\n""\t-m\tmemory usage limit\n""\t-r\tfax data is packed ls-bit first in input bytes\n""\t-v\tverbose messages\n""\t-z\tinitial zoom factor\n""\t-2\traw files are g3-2d\n""\t-4\traw files are g4\n";intmain(int argc, char **argv){    int c;    int err = 0;    bo.i = 1;    defaultpage.vres = -1;    defaultpage.expander = g31expand;    opterr = 0;			/* suppress getopt error message */    if ((ProgName = strrchr(argv[0], '/')) == NULL)	ProgName = argv[0];    else	ProgName++;    while ((c = getopt(argc, argv, "b:d:fg:h:ilm:nruvw:z:24")) != -1)	switch(c) {	case 'b':	    abell = vbell = 0;	    while (*optarg) {		abell |= (*optarg == 'a');		vbell |= (*optarg == 'v');		optarg++;	    }	    break;	case 'd':		/* display name */	    if (*(DispName = suffix(optarg, "isplay")) == 0)		DispName = argv[optind++];	    break;	case 'f':		/* fine resolution */	    defaultpage.vres = 1;	    break;	case 'g':		/* geometry */	    if (*(Geometry = suffix(optarg, "eometry")) == 0)		Geometry = argv[optind++];	    break;	case 'h':		/* user thinks this is the height */	    defaultpage.height = atoi(optarg);	    break;	case 'i':		/* invert black/white */	    defaultpage.inverse = 1;	    break;	case 'l':		/* landscape */	    defaultpage.orient |= TURN_L;	    break;	case 'm':		/* memory usage limit */	    Memlimit = atoi(optarg);	    switch(optarg[strlen(optarg)-1]) {	    case 'M':	    case 'm':		Memlimit *= 1024;	    case 'K':	    case 'k':		Memlimit *= 1024;	    }	    break;	case 'n':		/* normal resolution */	    defaultpage.vres = 0;	    break;	case 'r':		/* reverse input bits */	    defaultpage.lsbfirst = 1;	    break;	case 'u':		/* upside down */	    defaultpage.orient |= TURN_U;	    break;	case 'v':		/* verbose messages */	    verbose = 1;	    break;	case 'w':		/* user thinks this is the width */	    defaultpage.width = atoi(optarg);	    break;	case 'z':		/* zoom factor */	    c = atoi(optarg);	    if (c <= 0)		c = 1;	    for (zfactor = 1; c > 1; c >>= 1)		zfactor <<= 1;	/* constrain to a power of 2 */	    break;	case '2':	    defaultpage.expander = g32expand;	    break;	case '4':	    defaultpage.expander = g4expand;	    break;	default:	    err++;	    break;	}    if (defaultpage.expander == g4expand && defaultpage.height == 0) {	fputs("-h value is required to interpret raw g4 faxes\n", stderr);	err++;    }    if (verbose)	fputs(Banner, stdout);    firstpage = lastpage = thispage = helppage = NULL;    for (; optind < argc; optind++)	(void) notetiff(argv[optind]);    if (err || firstpage == NULL) {	if (!verbose)	    fprintf(stderr, Banner);	fprintf(stderr, Usage, ProgName);	exit(EXIT_FAILURE);    }    if ((Disp = XOpenDisplay(DispName)) == NULL) {	fprintf(stderr, "%s: can't open display %s\n", ProgName,		DispName ? DispName : XDisplayName((char *) NULL));	exit(EXIT_FAILURE);    }    Default_Screen = XDefaultScreen(Disp);    faxinit();    thispage = firstpage;    while (!GetImage(firstpage))	/* try again */;    SetupDisplay(argc, argv);    ShowLoop();    return 0;}/* return mismatching suffix of option name */static char *suffix(char *opt, const char *prefix){    while (*opt && *opt == *prefix) {	opt++; prefix++;    }    return opt;}/* Change orientation of all following pages */static voidTurnFollowing(int How, struct pagenode *pn){    while (pn) {	if (Pimage(pn)) {	    FreeImage(Pimage(pn));	    pn->extra = NULL;	}	pn->orient ^= How;	pn = pn->next;    }}static voiddrawline(pixnum *run, int LineNum, struct pagenode *pn){    t32bits *p, *p1;		/* p - current line, p1 - low-res duplicate */    pixnum *r;			/* pointer to run-lengths */    t32bits pix;		/* current pixel value */    t32bits acc;		/* pixel accumulator */    int nacc;			/* number of valid bits in acc */    int tot;			/* total pixels in line */    int n;    LineNum += pn->stripnum * pn->rowsperstrip;    p = (t32bits *) (Pimage(pn)->data + LineNum*(2-pn->vres)*Pimage(pn)->bytes_per_line);    p1 = pn->vres ? NULL : p + Pimage(pn)->bytes_per_line/sizeof(*p);    r = run;    acc = 0;    nacc = 0;    pix = pn->inverse ? ~0 : 0;    tot = 0;    while (tot < pn->width) {	n = *r++;	tot += n;	if (pix)	    acc |= (~(t32bits)0 >> nacc);	else if (nacc)	    acc &= (~(t32bits)0 << (32 - nacc));	else	    acc = 0;	if (nacc + n < 32) {	    nacc += n;	    pix = ~pix;	    continue;	}	*p++ = acc;	if (p1)	    *p1++ = acc;	n -= 32 - nacc;	while (n >= 32) {	    n -= 32;	    *p++ = pix;	    if (p1)		*p1++ = pix;	}	acc = pix;	nacc = n;	pix = ~pix;    }    if (nacc) {	*p++ = acc;	if (p1)	    *p1++ = acc;    }}static intGetPartImage(struct pagenode *pn, int n){    unsigned char *Data = getstrip(pn, n);    if (Data == NULL)	return 0;    pn->stripnum = n;    (*pn->expander)(pn, drawline);    free(Data);    return 1;}static intGetImage(struct pagenode *pn){    int i;    if (pn->strips == NULL) {	/* raw file; maybe we don't have the height yet */	unsigned char *Data = getstrip(pn, 0);	if (Data == NULL)	    return 0;	pn->extra = NewImage(pn->width, pn->vres ?			     pn->height : 2*pn->height, NULL, 1);	(*pn->expander)(pn, drawline);    }    else {	/* multi-strip tiff */	pn->extra = NewImage(pn->width, pn->vres ?			     pn->height : 2*pn->height, NULL, 1);	pn->stripnum = 0;	for (i = 0; i < pn->nstrips; i++) {	    if (verbose) printf("\texpanding strip #%d\n", i);	    if (GetPartImage(pn, i) == 0) {		FreeImage(Pimage(pn));		return 0;	    }	}    }    if (pn->orient & TURN_U)	pn->extra = FlipImage(Pimage(pn));    if (pn->orient & TURN_M)	pn->extra = MirrorImage(Pimage(pn));    if (pn->orient & TURN_L)	pn->extra = RotImage(Pimage(pn));    if (verbose) printf("\tmemused = %d\n", Memused);    return 1;}#ifndef _HAVE_USLEEPstatic intusleep(unsigned usecs){    struct timeval t;    t.tv_sec = usecs/10000000;    t.tv_usec = usecs%1000000;    (void) select(1, NULL, NULL, NULL, &t);    return 0;}#endif#ifndef REAL_ROOT/* Function Name: GetVRoot * Description: Gets the root window, even if it's a virtual root * Arguments: the display and the screen * Returns: the root window for the client * * by David Elliott, taken from the x-faq */static WindowGetVRoot(Display *dpy, int scr){    Window rootReturn, parentReturn, *children;    unsigned int numChildren;    Window root = RootWindow(dpy, scr);    Atom __SWM_VROOT = None;    int i;     __SWM_VROOT = XInternAtom(dpy, "__SWM_VROOT", False);    XQueryTree(dpy, root, &rootReturn, &parentReturn, &children,	       &numChildren);    for (i = 0; i < numChildren; i++) {        Atom actual_type;        int actual_format;        unsigned long nitems, bytesafter;        Window *newRoot = NULL;         if (XGetWindowProperty(dpy, children[i], __SWM_VROOT, 0, 1,			       False, XA_WINDOW, &actual_type,			       &actual_format, &nitems, &bytesafter,			       (unsigned char **) &newRoot)					== Success && newRoot) {	    if (children) XFree(children);	    return *newRoot;	}    }    return root;}#endifstatic Atom wm_delete_window;/* Area the user would like us to use, derived from -geometry */static struct {    int v, x, y;    unsigned int w, h;} Area = {0, 0, 0};/* nominal border width */#define BW 4/* Figure out the zoom factor needed to fit the fax on the available display */static voidSetupDisplay(int argc, char **argv){    int Width, Height, i;    XSetWindowAttributes Attr;    XSizeHints size_hints;    Atom wm_protocols;    int faxh = Pimage(thispage)->height;    int faxw = Pimage(thispage)->width;#ifdef REAL_ROOT    Root = RootWindow(Disp, Default_Screen);    Width = Area.w = DisplayWidth(Disp, Default_Screen);    Height = Area.h = DisplayHeight(Disp, Default_Screen);#elif TVTWM_BIGWINDOW    XWindowAttributes RootWA;    Root = GetVRoot(Disp, Default_Screen);    XGetWindowAttributes(Disp, Root, &RootWA);    Width = Area.w = RootWA.width;    Height = Area.h = RootWA.height;#else    Root = GetVRoot(Disp, Default_Screen);    Width = Area.w = DisplayWidth(Disp, Default_Screen);

⌨️ 快捷键说明

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