Category : Recently Uploaded Files
Archive   : PL192SRC.ZIP
Filename : PLFRAME.C

 
Output of file : PLFRAME.C contained in archive : PL192SRC.ZIP
/* PLFRAME.C : Miscellaneous frame process commands for PICLAB. One of the
** reasons for storing the edit buffers in separate files for each plane is
** apparent from many of these processes: the memory required to perform many
** frame processes is reduced to a third by processing each plane separately.
** Commands here include ADD, SUBTRACT, AVERAGE, CLIP, REVERSE, ROTATE,
** MIRROR, RESCALE.
*/

#pragma loop_opt(off)

#include
#include

#include "piclab.h"

static int samesize(void);
static int tempfile(void);

static char *plane = "plane";

/* Utility function to test for the same-size condition necessary for many of
** these functions. Prints error message if failed.
*/
static int samesize()
{
if (new->width == old->width &&
new->height == old->height &&
new->planes == old->planes &&
(new->flags & 1) == (old->flags & 1)) return 1;
else {
pl_printf("To perform this operation, images in both buffers must be of same\r\n");
pl_printf("size, depth, and raster direction. Use CLIP, RESCALE, REVERSE, GRAY\r\n");
pl_printf("and/or COLOR as necessary to accomplish this.\r\n");
return 0;
}
}

static int tempfile()
{
struct _imgbuf *temp;
char *tc;

temp = itmp; itmp = new; new = temp;
tc = itmp->bufname; itmp->bufname = new->bufname; new->bufname = tc;
new->width = itmp->width;
new->height = itmp->height;
new->planes = itmp->planes;
new->flags = itmp->flags;
return 0;
}

/* Add OLD image to NEW. Used immediately after two load commands. If first
** argument is "WRAP", then values exceeding 255 are taken mod 256 rather than
** being truncated to 255.
*/
int addimg(int ac, argument *av)
{
U32 mem;
int r, i, lost, wrap;
U8 *sp1, *sp2, *dp;
register S16 val;
U16 lines, x;
struct _plane *ip1, *ip2, *op;

if (new->flags & 2) {
pl_printf(maperr);
return 0;
}
if (ac == 1) wrap = 0;
else {
if (ac > 2) pl_warn(1);
if (*av[1].cval == 'W') wrap = 1;
}
if (new->planes == 0 || old->planes == 0) return 7;
if (!samesize()) return 0;
if ((r = begintransform()) != 0) return r;
if ((r = tempfile()) != 0) return r;

mem = mark();
lost = 0;
pl_printf(working);
for (i=0; i < new->planes; ++i) {
if ((ip1 = openplane(i, old, READ)) == NULL) return 3;
if ((ip2 = openplane(i, itmp, READ)) == NULL) return 3;
if ((op = openplane(i, new, WRITE)) == NULL) return 3;
for (lines=0; lines < old->height; ++lines) {
if (getline(ip1) == 0) return 4;
if (getline(ip2) == 0) return 4;
sp1 = ip1->linebuf;
sp2 = ip2->linebuf;
dp = op->linebuf;

for (x=0; x < new->width; ++x) {
val = (S16)*sp1++ + (S16)*sp2++;
if (val > 255) {
if (!wrap) lost = val = 255;
}
*dp++ = (U8)val;
}
if (putline(op) == 0) return 3;
pl_trace(lines);
}
closeplane(ip1);
closeplane(ip2);
closeplane(op);
release(mem);
}
pl_printf(done);
if (lost) pl_warn(3);
return 0;
}

/* Subtract NEW image from OLD, storing result in NEW. Used immediately after
** two load commands. If first argument is "WRAP", then values less than 0
** are taken mod 256 rather than being clamped to 0.
*/
int subimg(int ac, argument *av)
{
U32 mem;
int r, i, lost, wrap;
U8 *sp1, *sp2, *dp;
register S16 val;
U16 lines, x;
struct _plane *ip1, *ip2, *op;

if (new->flags & 2) {
pl_printf(maperr);
return 0;
}
if (ac == 1) wrap = 0;
else {
if (ac > 2) pl_warn(1);
if (*av[1].cval == 'W') wrap = 1;
}
if (new->planes == 0 || old->planes == 0) return 7;
if (!samesize()) return 0;
if ((r = begintransform()) != 0) return r;
if ((r = tempfile()) != 0) return r;

mem = mark();
pl_printf(working);
for (i=0; i < new->planes; ++i) {
if ((ip1 = openplane(i, old, READ)) == NULL) return 3;
if ((ip2 = openplane(i, itmp, READ)) == NULL) return 3;
if ((op = openplane(i, new, WRITE)) == NULL) return 3;
for (lines=0; lines < old->height; ++lines) {
if (getline(ip1) == 0) return 4;
if (getline(ip2) == 0) return 4;
sp1 = ip1->linebuf;
sp2 = ip2->linebuf;
dp = op->linebuf;

for (x=0; x < new->width; ++x) {
val = (S16)*sp2++ - (S16)*sp1++;
if (val < 0) {
if (!wrap) { val = 0; lost = 1; }
}
*dp++ = (U8)val;
}
if (putline(op) == 0) return 3;
pl_trace(lines);
}
closeplane(ip1);
closeplane(ip2);
closeplane(op);
release(mem);
}
pl_printf(done);
if (lost) pl_warn(3);
return 0;
}

/* Average OLD and NEW images to NEW.
*/
int average(int ac, argument *av)
{
U32 mem;
int r, i;
U8 *sp1, *sp2, *dp;
register U16 val;
U16 lines, x;
struct _plane *ip1, *ip2, *op;

if (new->flags & 2) {
pl_printf(maperr);
return 0;
}
if (ac > 1) pl_warn(1);
if (old->planes == 0 || new->planes == 0) return 7;
if (!samesize()) return 0;
if ((r = begintransform()) != 0) return r;
if ((r = tempfile()) != 0) return r;

mem = mark();
pl_printf(working);
for (i=0; i < new->planes; ++i) {
if ((ip1 = openplane(i, old, READ)) == NULL) return 3;
if ((ip2 = openplane(i, itmp, READ)) == NULL) return 3;
if ((op = openplane(i, new, WRITE)) == NULL) return 3;
for (lines=0; lines < old->height; ++lines) {
if (getline(ip1) == 0) return 4;
if (getline(ip2) == 0) return 4;
sp1 = ip1->linebuf;
sp2 = ip2->linebuf;
dp = op->linebuf;

for (x=0; x < new->width; ++x) {
val = (*sp1++ + *sp2++) >> 1;
*dp++ = (U8)val;
}
if (putline(op) == 0) return 3;
pl_trace(lines);
}
closeplane(ip1);
closeplane(ip2);
closeplane(op);
release(mem);
}
pl_printf(done);
return 0;
}

/* Clip edit buffer from (xorigin,yorigin) to a size given by first two
** arguments. If no arguments are given, uses largest values.
*/
int clip(int ac, argument *av)
{
U32 mem;
int r, i;
U8 *sp, *dp;
U16 lines, x, xlimit, ylimit;
struct _plane *ip, *op;

if (ac == 1) {
if (xorigin == 0 && yorigin == 0) {
pl_printf("No clipping bounds were specified.\r\n");
return 0;
}
else xlimit = ylimit = 65535;
} else if (ac == 2) {
pl_printf("Syntax is CLIP [ ]. If both are omitted, image\r\n");
pl_printf("is made as large as possible starting at (xorigin,yorigin).\r\n");
return 0;
} else {
if (ac > 3) pl_warn(1);
xlimit = xorigin + (U16)av[1].fval;
ylimit = yorigin + (U16)av[2].fval;
}
if (new->planes == 0) return 7;
if (xlimit > new->width) xlimit = new->width;
if (ylimit > new->height) ylimit = new->height;

if ((r = begintransform()) != 0) return r;
new->width = xlimit - xorigin;
new->height = ylimit - yorigin;

mem = mark();
pl_printf(working);
for (i=0; i < new->planes; ++i) {
if ((ip = openplane(i, old, READ)) == NULL) return 3;
if ((op = openplane(i, new, WRITE)) == NULL) return 3;

seekline(ip, yorigin);
for (lines=yorigin; lines < old->height; ++lines) {
if (getline(ip) == 0) return 4;
else if (lines >= ylimit) break;

sp = ip->linebuf+xorigin;
dp = op->linebuf;

for (x=0; x < new->width; ++x) *dp++ = *sp++;
if (putline(op) == 0) return 3;
pl_trace(lines);
}
closeplane(ip);
closeplane(op);
release(mem);
}
pl_printf(done);
pl_warn(3);
xorigin = yorigin = 0;
return 0;
}

/* Change bottom-up raster to top-down or vice versa.
*/
int reverse(int ac, argument *av)
{
U32 mem;
U16 lines;
int r, i;
struct _plane *ip, *op;

if (ac > 1) pl_warn(1);
if (new->planes == 0) return 7;

if ((r = begintransform()) != 0) return r;
mem = mark();

for (i=0; i < new->planes; ++i) {
if ((ip = openplane(i, old, READ)) == NULL) return 3;
if ((op = openplane(i, new, WRITE)) == NULL) return 3;

for (lines=0; lines < new->height; ++lines) {
seekline(ip, new->height-(lines+1));
if (getline(ip) == 0) return 4;
memcpy(op->linebuf, ip->linebuf, new->width);
if (putline(op) == 0) return 3;
}
closeplane(ip);
closeplane(op);
release(mem);
}
pl_printf(done);
new->flags ^= 1;
return 0;
}

/* Rotate image clockwise in 90-degree increments. If no argument is given,
** default to one 90-degree rotation. If argument >= 90, interpret it as
** degrees, otherwise interpret argument as 90-degree increments.
*/
int rotate(int ac, argument *av)
{
U32 mem, needed;
U16 lines, x, y;
U8 **buf, *sp, *dp;
int r, i, angle, flipped;
struct _plane *p;

if (ac == 1) angle = 1;
else {
if (ac > 2) pl_warn(1);
i = (int)av[1].fval;
if (i > 3) angle = (i % 360) / 90;
else angle = i;
}

if (new->planes == 0) return 7;
if ((r = begintransform()) != 0) return r;
if (angle == 1 || angle == 3) {
new->height = old->width; new->width = old->height;
}
needed = (U32)new->height * sizeof(U8 *) + (U32)new->width * new->height +
new->width + BUFSIZE;
if (freemem() < needed) return 2;

buf = (U8 **)talloc(new->height * sizeof(U8 *));
for (lines=0; lines < new->height; ++lines) {
buf[lines] = (U8 *)talloc(new->width);
}
flipped = ((new->flags & 1) == 1);

mem = mark();
for (i=0; i < new->planes; ++i) {
pl_printf(reading, plane);
if ((p = openplane(i, old, READ)) == NULL) return 3;
for (lines=0; lines < old->height; ++lines) {
if (getline(p) == 0) return 4;
sp = p->linebuf;
switch (angle) {
case 1:
if (flipped) {
for (x=old->width-1; x > 0; --x) buf[x][lines] = *sp++;
buf[0][lines] = *sp;
} else {
y = (old->height - lines) - 1;
for (x=0; x < old->width; ++x) buf[x][y] = *sp++;
}
break;
case 2:
dp = buf[(old->height - lines) - 1] + new->width;
for (x=0; x < old->width; ++x) *--dp = *sp++;
break;
case 3:
if (flipped) {
y = (old->height - lines) - 1;
for (x=0; x < old->width; ++x) buf[x][y] = *sp++;
} else {
for (x=old->width-1; x > 0; --x) buf[x][lines] = *sp++;
buf[0][lines] = *sp;
}
break;
default: return 1;
}
}
closeplane(p);
release(mem);

pl_printf(writing, plane);
if ((p = openplane(i, new, WRITE)) == NULL) return 3;
for (lines=0; lines < new->height; ++lines) {
memcpy(p->linebuf, buf[lines], new->width);
if (putline(p) == 0) return 3;
}
closeplane(p);
release(mem);
}
pl_printf(done);
return 0;
}

/* Flip image about the vertical axis. No arguments.
*/
int mirror(int ac, argument *av)
{
U32 mem;
int r, i;
U8 *sp, *dp;
U16 lines, x;
struct _plane *ip, *op;

if (ac > 1) pl_warn(1);
mem = mark();
if (new->planes == 0) return 7;
if ((r = begintransform()) != 0) return r;
pl_printf(working);
for (i=0; i < new->planes; ++i) {
if ((ip = openplane(i, old, READ)) == NULL) return 3;
if ((op = openplane(i, new, WRITE)) == NULL) return 3;
for (lines=0; lines < new->height; ++lines) {
if (getline(ip) == 0) return 4;
sp = ip->linebuf;
dp = op->linebuf + new->width;
for (x=0; x < new->width; ++x) *--dp = *sp++;
if (putline(op) == 0) return 3;
pl_trace(lines);
}
closeplane(ip);
closeplane(op);
release(mem);
}
pl_printf(done);
return 0;
}

int sh, sw, dh, dw; /* Source and destination height & width. */

/* Utility routine to rescale one line. Called by rescale().
*/
void scaleline(U8 *sp, U8 *dp, int sw, int dw)
{
int i, x0, y0, y1, v;
long count, total;

count = total = 0L;
x0 = 0;
if (sw == dw) memcpy(dp, sp, sw);
else if (dw > sw) {
y0 = (int)(sp[0]); y1 = (int)(sp[1]);
for (i=0; i *dp++ = (U8)(y0 + (int)((count * (long)(y1 - y0)) / (long)dw));
count += sw;
if (count >= dw) {
count -= dw;
++x0;
y0 = y1;
y1 = ((x0 == sw-1) ? y1 : sp[x0+1]);
}
}
} else {
for (i=0; i count += dw;
if (count >= sw) {
count -= sw;
v = (int)(*sp++);
total += ((long)v * ((long)dw - count)) / (long)dw;
*dp++ = (U8)((total * (long)dw) / (long)sw);
total = ((long)v * count) / (long)dw;
} else {
total += *sp++;
}
}
}
return;
}

/* Rescale buffer to new size specified by two arguments. Scaling up is
** done by bilinear interpolation; scaling down by resampling. If one of
** the arguments is "?", it is calculated to keep the aspect ratio constant.
*/
int rescale(int ac, argument *av)
{
U32 mem;
long *tots, count;
int r, i, nl;
U8 *dp, *vp, *vp2;
U16 lines, x;
struct _plane *ip, *op;
float f;

if (new->flags & 2) {
pl_printf(maperr);
return 0;
}
sw = new->width; sh = new->height;
if (ac == 2) {
if ((f = av[1].fval) <= 0.0F) return 9;
dw = (U16)(f * sw);
dh = (U16)(f * sh);
} else if (ac >= 3) {
if (*av[1].cval == '?') {
dh = (U16)av[2].fval;
dw = (U16)(((long)sw * dh) / (long)sh);
} else if (*av[2].cval == '?') {
dw = (U16)av[1].fval;
dh = (U16)(((long)sh * dw) / (long)sw);
} else {
dw = (U16)av[1].fval;
dh = (U16)av[2].fval;
}
} else {
pl_printf("Syntax is RESCALE .\r\n");
return 0;
}
if (dw <= 0 || dh <= 0) return 9;

mem = mark();
if (new->planes == 0) return 7;
if ((r = begintransform()) != 0) return r;
new->width = dw; new->height = dh;

pl_printf("Rescaling to %d x %d...\r\n", dw, dh);
for (i=0; i < new->planes; ++i) {
if ((ip = openplane(i, old, READ)) == NULL) return 3;
if ((op = openplane(i, new, WRITE)) == NULL) return 3;

count = 0L;
if (sh == dh) {
for (lines=0; lines if (getline(ip) == 0) return 4;
scaleline(ip->linebuf, op->linebuf, sw, dw);
if (putline(op) == 0) return 3;
pl_trace(lines);
}
} else if (sh < dh) {
if ((vp = (U8 *)talloc(dw)) == NULL) return 2;
if ((vp2 = (U8 *)talloc(dw)) == NULL) return 2;
if (getline(ip) == 0) return 4;
scaleline(ip->linebuf, vp, sw, dw);
if (getline(ip) == 0) return 4;
scaleline(ip->linebuf, vp2, sw, dw);

for (lines=0; lines dp = op->linebuf;
for (x=0; x (int)((count * ( (long)(vp2[x])-(long)(vp[x]) ) ) / (long)dh) );

if ((count += sh) >= dh) {
count -= dh;
dp = vp; vp = vp2; vp2 = dp;
if (getline(ip) == 0) memcpy(vp2, vp, dw);
else scaleline(ip->linebuf, vp2, sw, dw);
}
if (putline(op) == 0) return 3;
pl_trace(lines);
}
} else {
if ((tots = (long *)talloc(dw * sizeof(long))) == NULL) return 2;
memset((char *)tots, 0, dw * sizeof(long));
if ((vp = (U8 *)talloc(dw)) == NULL) return 2;
nl = 0;
for (lines=0; lines if (getline(ip) == 0) return 4;
scaleline(ip->linebuf, vp, sw, dw);

count += dh;
if (count >= sh) {
count -= sh;
dp = op->linebuf;
for (x=0; x tots[x] += ((long)(vp[x]) * ((long)dh - count)) / (long)dh;
*dp++ = (U8)((tots[x] * (long)dh) / (long)sh);
tots[x] = ((long)(vp[x]) * count) / (long)dh;
}
if (putline(op) == 0) return 3;
++nl;
} else {
for (x=0; x }
pl_trace(nl);
}
}
closeplane(ip);
closeplane(op);
release(mem);
}
pl_printf(done);
if (dw < sw || dh < sh) pl_warn(3);
return 0;
}

int expand(int ac, argument *av)
{
U32 mem;
int r, i;
U8 fill[3];
U16 lines, xsize, ysize;
struct _plane *ip, *op;

xsize = ysize = fill[0] = fill[1] = fill[2] = 0;
if (ac > 1) xsize = (U16)av[1].fval;
if (ac > 2) ysize = (U16)av[2].fval;
if (ac > 3) {
if (*av[3].cval == 'B') fill[0] = fill[1] = fill[2] = 0;
else if (*av[3].cval == 'W') fill[0] = fill[1] = fill[2] = 255;
else {
fill[0] = (U8)av[3].fval;
if (ac > 4) fill[1] = (U8)av[4].fval;
if (ac > 5) fill[2] = (U8)av[5].fval;
}
}

if (xsize < new->width) xsize = new->width;
if (ysize < new->height) ysize = new->height;
if (xsize == new->width && ysize == new->height) {
pl_printf("No expansion specified.\r\n");
return 0;
}

if ((r = begintransform()) != 0) return r;
new->width = xsize;
new->height = ysize;

mem = mark();
pl_printf(working);
for (i=0; i < new->planes; ++i) {
if ((ip = openplane(i, old, READ)) == NULL) return 3;
if ((op = openplane(i, new, WRITE)) == NULL) return 3;
for (lines=0; lines < ysize; ++lines) {
memset(op->linebuf, fill[i], xsize);
if (lines < old->height) {
if (getline(ip) == 0) return 4;
memcpy(op->linebuf, ip->linebuf, old->width);
}
if (putline(op) == 0) return 3;
pl_trace(lines);
}
closeplane(ip);
closeplane(op);
release(mem);
}
pl_printf(done);
return 0;
}

int overlay(int ac, argument *av)
{
U32 mem;
int r, i, j, c, transval = -1;
U16 lines, xlimit, ylimit;
struct _plane *ip1, *ip2, *op;
struct _imgbuf *temp;
char *tc, *sp, *dp;

if (ac > 1) xorigin = (U16)av[1].fval;
if (ac > 2) yorigin = (U16)av[2].fval;
if (ac > 3) transval = (int)av[3].fval;

pl_printf("X=%d, Y=%d, T=%d\r\n", xorigin, yorigin, transval);

if (ac > 4) pl_warn(1);
xlimit = xorigin + new->width;
ylimit = yorigin + new->height;

if (xlimit > old->width || ylimit > old->height) {
pl_printf("Overlay exceeds bounds of base image.\r\n");
return 0;
}
if (transpend) return 8; /* Cannot use begintransform() here if */
histvalid = 0; /* base image is larger than overlay. */
temp = old; old = new; new = temp;
tc = old->bufname; old->bufname = new->bufname; new->bufname = tc;
if ((r = tempfile()) != 0) return r;

mem = mark();
pl_printf(working);
for (i=0; i < new->planes; ++i) {
if ((ip1 = openplane(i, itmp, READ)) == NULL) return 3;
if ((ip2 = openplane(i, old, READ)) == NULL) return 3;
if ((op = openplane(i, new, WRITE)) == NULL) return 3;
for (lines=0; lines < itmp->height; ++lines) {
if (getline(ip1) == 0) return 4;
memcpy(op->linebuf, ip1->linebuf, itmp->width);

if (lines >= yorigin && lines < ylimit) {
if (getline(ip2) == 0) return 4;

if (transval == -1) {
memcpy(op->linebuf+xorigin, ip2->linebuf, old->width);
} else {
sp = ip2->linebuf;
dp = op->linebuf+xorigin;

for (j = 0; j < old->width; ++j) {
if ((U8)(*sp) > transval) *dp = *sp;
++sp;
++dp;
}
}
}
if (putline(op) == 0) return 3;
pl_trace(lines);
}
closeplane(ip1);
closeplane(ip2);
closeplane(op);
release(mem);
}
xorigin = yorigin = 0;
pl_printf(done);
return 0;
}

#pragma loop_opt(on)


  3 Responses to “Category : Recently Uploaded Files
Archive   : PL192SRC.ZIP
Filename : PLFRAME.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/