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

📄 gfx.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/* * graphics file reading for page */#include <u.h>#include <libc.h>#include <draw.h>#include <event.h>#include <bio.h>#include "page.h"typedef struct Convert	Convert;typedef struct GfxInfo	GfxInfo;typedef struct Graphic	Graphic;struct Convert {	char *name;	char *cmd;	char *truecmd;	/* cmd for true color */};struct GfxInfo {	Graphic *g;};struct Graphic {	int type;	char *name;	uchar *buf;	/* if stdin */	int nbuf;};enum {	Ipic,	Itiff,	Ijpeg,	Igif,	Iinferno,	Ifax,	Icvt2pic,	Iplan9bm,	Iccittg4,	Ippm,	Ipng,	Iyuv,	Ibmp,};/* * N.B. These commands need to read stdin if %a is replaced * with an empty string. */Convert cvt[] = {[Ipic]		{ "plan9",	"fb/3to1 rgbv %a |fb/pcp -tplan9" },[Itiff]		{ "tiff",	"fb/tiff2pic %a | fb/3to1 rgbv | fb/pcp -tplan9" },[Iplan9bm]	{ "plan9bm",	nil },[Ijpeg]		{ "jpeg",	"jpg -9 %a", "jpg -t9 %a" },[Igif]		{ "gif",	"gif -9 %a", "gif -t9 %a" },[Iinferno]	{ "inferno",	nil },[Ifax]		{ "fax",	"aux/g3p9bit -g %a" },[Icvt2pic]	{ "unknown",	"fb/cvt2pic %a |fb/3to1 rgbv" },[Ippm]		{ "ppm",	"ppm -9 %a", "ppm -t9 %a" },/* ``temporary'' hack for hobby */[Iccittg4]	{ "ccitt-g4",	"cat %a|rx nslocum /usr/lib/ocr/bin/bcp -M|fb/pcp -tcompressed -l0" },[Ipng]		{ "png",	"png -9 %a", "png -t9 %a" },[Iyuv]		{ "yuv",	"yuv -9 %a", "yuv -t9 %a"  },[Ibmp]		{ "bmp",	"bmp -9 %a", "bmp -t9 %a"  },};static Image*	convert(Graphic*);static Image*	gfxdrawpage(Document *d, int page);static char*	gfxpagename(Document*, int);static int	spawnrc(char*, uchar*, int);static void	waitrc(void);static int	spawnpost(int);static int	addpage(Document*, char*);static int	rmpage(Document*, int);static int	genaddpage(Document*, char*, uchar*, int);static char*gfxpagename(Document *doc, int page){	GfxInfo *gfx = doc->extra;	return gfx->g[page].name;}static Image*gfxdrawpage(Document *doc, int page){	GfxInfo *gfx = doc->extra;	return convert(gfx->g+page);}Document*initgfx(Biobuf*, int argc, char **argv, uchar *buf, int nbuf){	GfxInfo *gfx;	Document *doc;	int i;	doc = emalloc(sizeof(*doc));	gfx = emalloc(sizeof(*gfx));	gfx->g = nil;		doc->npage = 0;	doc->drawpage = gfxdrawpage;	doc->pagename = gfxpagename;	doc->addpage = addpage;	doc->rmpage = rmpage;	doc->extra = gfx;	doc->fwdonly = 0;	fprint(2, "reading through graphics...\n");	if(argc==0 && buf)		genaddpage(doc, nil, buf, nbuf);	else{		for(i=0; i<argc; i++)			if(addpage(doc, argv[i]) < 0)				fprint(2, "warning: not including %s: %r\n", argv[i]);	}	return doc;}static intgenaddpage(Document *doc, char *name, uchar *buf, int nbuf){	Graphic *g;	GfxInfo *gfx;	Biobuf *b;	uchar xbuf[32];	int i, l;	l = 0;	gfx = doc->extra;	assert((name == nil) ^ (buf == nil));	assert(name != nil || doc->npage == 0);	for(i=0; i<doc->npage; i++)		if(strcmp(gfx->g[i].name, name) == 0)			return i;	if(name){		l = strlen(name);		if((b = Bopen(name, OREAD)) == nil) {			werrstr("Bopen: %r");			return -1;		}		if(Bread(b, xbuf, sizeof xbuf) != sizeof xbuf) {			werrstr("short read: %r");			return -1;		}		Bterm(b);		buf = xbuf;		nbuf = sizeof xbuf;	}	gfx->g = erealloc(gfx->g, (doc->npage+1)*(sizeof(*gfx->g)));	g = &gfx->g[doc->npage];	memset(g, 0, sizeof *g);	if(memcmp(buf, "GIF", 3) == 0)		g->type = Igif;	else if(memcmp(buf, "\111\111\052\000", 4) == 0) 		g->type = Itiff;	else if(memcmp(buf, "\115\115\000\052", 4) == 0)		g->type = Itiff;	else if(memcmp(buf, "\377\330\377", 3) == 0)		g->type = Ijpeg;	else if(memcmp(buf, "\211PNG\r\n\032\n", 3) == 0)		g->type = Ipng;	else if(memcmp(buf, "compressed\n", 11) == 0)		g->type = Iinferno;	else if(memcmp(buf, "\0PC Research, Inc", 17) == 0)		g->type = Ifax;	else if(memcmp(buf, "TYPE=ccitt-g31", 14) == 0)		g->type = Ifax;	else if(memcmp(buf, "II*", 3) == 0)		g->type = Ifax;	else if(memcmp(buf, "TYPE=ccitt-g4", 13) == 0)		g->type = Iccittg4;	else if(memcmp(buf, "TYPE=", 5) == 0)		g->type = Ipic;	else if(buf[0] == 'P' && '0' <= buf[1] && buf[1] <= '9')		g->type = Ippm;	else if(memcmp(buf, "BM", 2) == 0)		g->type = Ibmp;	else if(memcmp(buf, "          ", 10) == 0 &&		'0' <= buf[10] && buf[10] <= '9' &&		buf[11] == ' ')		g->type = Iplan9bm;	else if(strtochan((char*)buf) != 0)		g->type = Iplan9bm;	else if (l > 4 && strcmp(name + l -4, ".yuv") == 0)		g->type = Iyuv;	else		g->type = Icvt2pic;	if(name)		g->name = estrdup(name);	else{		g->name = estrdup("stdin");	/* so it can be freed */		g->buf = buf;		g->nbuf = nbuf;	}	if(chatty) fprint(2, "classified \"%s\" as \"%s\"\n", g->name, cvt[g->type].name);	return doc->npage++;}static int addpage(Document *doc, char *name){	return genaddpage(doc, name, nil, 0);}static intrmpage(Document *doc, int n){	int i;	GfxInfo *gfx;	if(n < 0 || n >= doc->npage)		return -1;	gfx = doc->extra;	doc->npage--;	free(gfx->g[n].name);	for(i=n; i<doc->npage; i++)		gfx->g[i] = gfx->g[i+1];	if(n < doc->npage)		return n;	if(n == 0)		return 0;	return n-1;}static Image*convert(Graphic *g){	int fd;	Convert c;	char *cmd;	char *name, buf[1000];	Image *im;	int rcspawned = 0;	Waitmsg *w;	c = cvt[g->type];	if(c.cmd == nil) {		if(chatty) fprint(2, "no conversion for bitmap \"%s\"...\n", g->name);		if(g->buf == nil){	/* not stdin */			fd = open(g->name, OREAD);			if(fd < 0) {				fprint(2, "cannot open file: %r\n");				wexits("open");			}		}else			fd = stdinpipe(g->buf, g->nbuf);		} else {		cmd = c.cmd;		if(truecolor && c.truecmd)			cmd = c.truecmd;		if(g->buf != nil)	/* is stdin */			name = "";		else			name = g->name;		if(strlen(cmd)+strlen(name) > sizeof buf) {			fprint(2, "command too long\n");			wexits("convert");		}		snprint(buf, sizeof buf, cmd, name);		if(chatty) fprint(2, "using \"%s\" to convert \"%s\"...\n", buf, g->name);		fd = spawnrc(buf, g->buf, g->nbuf);		rcspawned++;		if(fd < 0) {			fprint(2, "cannot spawn converter: %r\n");			wexits("convert");		}		}	im = readimage(display, fd, 0);	if(im == nil) {		fprint(2, "warning: couldn't read image: %r\n");	}	close(fd);	/* for some reason rx doesn't work well with wait */	/* for some reason 3to1 exits on success with a non-null status of |3to1 */	if(rcspawned && g->type != Iccittg4) {		if((w=wait())!=nil && w->msg[0] && !strstr(w->msg, "3to1"))			fprint(2, "slave wait error: %s\n", w->msg);		free(w);	}	return im;}static intspawnrc(char *cmd, uchar *stdinbuf, int nstdinbuf){	int pfd[2];	int pid;	if(chatty) fprint(2, "spawning(%s)...", cmd);	if(pipe(pfd) < 0)		return -1;	if((pid = fork()) < 0)		return -1;	if(pid == 0) {		close(pfd[1]);		if(stdinbuf)			dup(stdinpipe(stdinbuf, nstdinbuf), 0);		else			dup(open("/dev/null", OREAD), 0);		dup(pfd[0], 1);		//dup(pfd[0], 2);		execl("/bin/rc", "rc", "-c", cmd, nil);		wexits("exec");	}	close(pfd[0]);	return pfd[1];}

⌨️ 快捷键说明

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