V10/cmd/pico/files.c

Compare this file to the similar file:
Show the results in this format:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "pico.h"

extern struct	SRC src[MANY];
extern short	CURSCRATCH, CUROLD;
extern int	nsrc, DEF_LL, DEF_NL;
extern char	frameb, usedold, metheus;

prepare(infile)
	char *infile;
{
	struct SRC *into = &src[nsrc];
	int from;

	into->ex = into->ll = DEF_LL;
	into->ey = into->nl = DEF_NL;
	into->nchan = DEF_CH;
	into->sx = into->sy = 0;

	if ((from = whatarray(infile)) != -1)
	{	fprintf(stderr, "sorry: base name clash of %s with %s\n",
						infile, src[from].fname);
		return 0;
	}
	strcpy(into->fname, infile);
	if ((from = eopen(infile)) > 0 && readheader(into, from))
	{	into->fd = from;
		into->used = 0;
		into->pixred = (unsigned char *) Emalloc(DEF_LL*DEF_NL);
		if (into->nchan >= 3)
		{	into->pixgrn = (unsigned char *) Emalloc(DEF_LL*DEF_NL);
			into->pixblu = (unsigned char *) Emalloc(DEF_LL*DEF_NL);
		} else
		{	into->pixgrn = into->pixblu = into->pixred;
		}
		into->incore = 1;
		nsrc++;
		return nsrc-1;
	} else
	{	into->fname[0] = '\0';
		into->fd = -1;
		into->incore = into->used = 0;
		return 0;
	}
}

interpret(infile)
	char *infile;
{
	struct SRC *into = &src[nsrc];
	int from, hh;

	into->ex = into->ll = DEF_LL;
	into->ey = into->nl = DEF_NL;
	into->nchan = DEF_CH;
	into->sx = into->sy = 0;

	if ((from = eopen(infile)) > 0 && (hh = rawheader(into, from)))
	{	fprintf(stderr, "%s: ", &infile[findbase(infile)]);
		if (hh == 2)
		{	hh = less(from);
			fprintf(stderr, "headerless file, ");
			fprintf(stderr, "ll %d nl %d, ", into->ll, into->nl);
			fprintf(stderr, "(%d = %dx512 bytes)\n", hh, hh/512);
		} else
		{	fprintf(stderr, "%s ", (into->nchan == 1)?"b&w  ":"color");
			tpfile(into->type);
			fprintf(stderr, "ll %d nl %d ", into->ll, into->nl);
			wsize(into->sx, into->sy, into->ex, into->ey);
		}
		close(from);
	}
	into->fd = -1;
	into->incore = into->used = 0;
}

tpfile(n)
{
	switch (n) {
	case PICO:	fprintf(stderr, "pico-format "); break;
	case DUMP:	fprintf(stderr, "dump-format "); break;
	case RUNCODE:	fprintf(stderr, "runcode-format "); break;
	}
}

less(fd)
{ 	struct stat bam;
	if (fstat(fd, &bam)==0)
		return bam.st_size;
	return 0;
}

nopix(into)
	struct SRC *into;
{
	into->pixred = (unsigned char *) Emalloc(DEF_LL*DEF_NL);
/*
	into->pixgrn = (unsigned char *) Emalloc(DEF_LL*DEF_NL);
	into->pixblu = (unsigned char *) Emalloc(DEF_LL*DEF_NL);
*/
	into->pixgrn = (unsigned char *) 0;
	into->pixblu = (unsigned char *) 0;
	into->ex = into->ll = DEF_LL;
	into->ey = into->nl = DEF_NL;
	into->nchan = DEF_CH;
	into->sx = into->sy = 0;
	into->ox = into->oy = 0;
	strcpy(into->fname, "_workspace_");
	into->incore = 1;
}

checkpix(into)
	struct SRC *into;
{
	if (!into->pixgrn)
		into->pixgrn = (unsigned char *) Emalloc(DEF_LL*DEF_NL);
	if (!into->pixblu)
		into->pixblu = (unsigned char *) Emalloc(DEF_LL*DEF_NL);
}

discard(s)
	char *s;
{	int nr;

	if ((nr = ungetpix(s)) < 2)
		return 0;

	close(src[nr].fd);
	src[nr].fd = -1;
	src[nr].sx = src[nr].sy = src[nr].nchan = 0;
	src[nr].ex = src[nr].ey = src[nr].ll = 0;
	strcpy(src[nr].fname, " empty");
	src[nr].used = 0;

	return nr;
}

ungetpix(s)
	char *s;
{	int nr;

	if ((nr = whatarray(s)) < 2)
	{	fprintf(stderr, "unknown file %s\n", s);
		return 0;
	}

	if (src[nr].incore == 0)
		return nr;

	free(src[nr].pixred);
	if (src[nr].nchan >= 3)
	{	free(src[nr].pixgrn);
		free(src[nr].pixblu);
	}
	src[nr].incore = 0;
	lseek(src[nr].fd, src[nr].sop, 0);

	return nr;
}

newscreen(infile)
	char *infile;
{
	if ((Old->fd = eopen(infile)) > 0 && readheader(Old, Old->fd))
	{	getpix(Old, infile);
		putscreen(CUROLD);
		setscratch(Old, Scratch);
		return 1;
	}	/* else reset */
	Old->ex = Old->ll = DEF_LL;
	Old->ey = Old->nl = DEF_NL;
	Old->nchan = DEF_CH;
	Old->sx = Old->sy = 0;
	return 0;
}

readheader(into, from)
	struct SRC *into;
{
	int i, ret = rawheader(into, from);
	int a = into->sx, b = into->sy;
	int c = into->ex, d = into->ey;
	int n = into->nchan;

	if (a > c) i = a, a = c, c = i;		/* flip */
	if (b > d) i = b, b = d, d = i;
	if (a < 0) c -= a, a = 0;		/* normalize  */
	if (b < 0) d -= b, b = 0;
	into->ll = c-a; into->nl = d-b;		/* scan ll,nl */
			
	a = min(DEF_LL, a); c = min(DEF_LL, c);	/* clip */
	b = min(DEF_NL, b); d = min(DEF_NL, d);

	into->sx = a; into->sy = b;
	into->ex = c; into->ey = d;
	into->ox = 0; into->oy = 0;

	if (ret == 0) return 0;

	if (a >= c || b >= d)
	{	fprintf(stderr, "pico: file window is outside screen area\n");
		return 0;
	}
	if (n < 1 || n > 4)
	{	fprintf(stderr, "pico: bad nr of channels (%d)\n", n);
		return 0;
	}

	return ret;
}

rawheader(into, from)
	struct SRC *into;
{ char line[512];
  int i, j, a, b, c, d, N, sawtype=0;
  extern double sqrt();

	into->type = PICO;	/* default */
	for (j = 0;;)
	{	for (i = 0; i < 127; i++, j++)
		{	read(from, &line[i], 1);
			if (line[i] == '\n')
			{	line[i] = '\0';
				break;
		}	}
		if (i == 0)			/* saw end of header */
		{	if (sawtype)
			{	into->sop = j;
				return 1;
			} else
				i = 127;
		}
		if (i == 127)			/* no header */
		{	into->nchan = 1;	/* assume b&w, square image */
			N = (int) sqrt((double)less(from)+1.0);
			into->ex = into->ey = N;
			into->ll = into->nl = N;
			lseek(from, 0L, 0);
			into->sop = 0;
			return 2;
		}
		if (sscanf(line, "WINDOW=%d %d %d %d", &a, &b, &c, &d) == 4)
		{	into->sx = a; into->sy = b;
			into->ex = c; into->ey = d;
			into->ll = c-a; into->nl = d-b;
		} else if (sscanf(line, "NCHAN=%d", &a) == 1)
			into->nchan = a;
		   else if (strcmp(line, "TYPE=dump") == 0)
		 {	into->type = DUMP; sawtype = 1;
		 } else if (strcmp(line, "TYPE=runcode") == 0)
		 {	into->type = RUNCODE; sawtype = 1;
		 } else if (strcmp(line, "TYPE=pico") == 0)
		 {	into->type = PICO; sawtype = 1;
		 } else if (strncmp(line, "TYPE", 4) == 0)
		{	fprintf(stderr, "pico: unknown format: %s..\n", line);
			return 0;
		}
	}
}

putheader(where, n, a, b, c, d)
{	char line[128];

	sprintf(line, "TYPE=pico\nWINDOW=%d %d %d %d\nNCHAN=%d\n\n", a,b,c,d,n);
	write(where, line, strlen(line));
}

putdpix(which, how)
	char *which;
{
	int fd, a, b, c, d;

	a = Old->sx; b = Old->sy;
	c = Old->ex; d = Old->ey;

	checkit();		/* make sure we have screen incore */
	if ((fd = creat(which, 0666)) <= 0)
		yyerror("cannot create file %s", which);

	if (!how)
		putwindow(fd, Old->pixred, a, b, c-a, d-b);
	else
	{	if (Old->nchan != 1 || c-a != d-b)
			putheader(fd, min(3, Old->nchan), a, b, c, d);
		putfile(fd, a, b, c-a, d-b);
	}
	close(fd);
}

putfile(where, x, y, w, d)
{
	putwindow(where, Old->pixred, x, y, w, d);
	if (Old->nchan >= 3)
	{	putwindow(where, Old->pixgrn, x, y, w, d);
		putwindow(where, Old->pixblu, x, y, w, d);
	}
	close(where);
}

checkit()
{	register int i;

	if (usedold && src[CUROLD].incore != 2 && (frameb || metheus))
		fprintf(stderr, "warning: picture on screen wasn't read\n");

	for (i = 2; i < nsrc; i++)
	if (src[i].used && src[i].incore != 2)
	{	src[i].used = 0;
		getpix(&src[i], src[i].fname);
	}
}

setscratch(from, to)
	struct SRC *from, *to;
{
	register unsigned char *qr = from->pixred, *pr = to->pixred;
	register unsigned char *qg = from->pixgrn, *pg = to->pixgrn;
	register unsigned char *qb = from->pixblu, *pb = to->pixblu;
	memcpy(pr, qr, DEF_NL*DEF_LL);
	if (pg && qg) memcpy(pg, qg, DEF_NL*DEF_LL);
	if (pb && qb) memcpy(pb, qb, DEF_NL*DEF_LL);
}

getter(n)
{
	if (n <= 0)
		return;
	if (n >  1)
	{	if (src[n].incore != 2)
		getpix(&src[n], src[n].fname);
		setscratch(&src[n], Old);
	}
	putscreen(CUROLD);
	if (n >  1)
		setscratch(Old, Scratch);
	RESIDENT;
}