V10/cmd/pico/files.c
#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;
}