// Emacs: -*- C++ -*-
static char rcsid[] = "$Id: test002.c,v 1.2 1992/12/15 21:51:32 thoth Exp $";

//
// $Log: test002.c,v $
// Revision 1.2  1992/12/15  21:51:32  thoth
// no more memory debuggin
//
// Revision 1.1  92/11/19  02:40:53  thoth
// Initial revision
// 
//

#include "IntPointSet.h"
#include "IPSIter.h"
#include "ImageDisplayProtocol.h"

void custom_convolve(IntPointSet source,
		     const unsigned char *input,
		     unsigned tcard,
		     const IntPoint *tpoints,
		     const double *tvals,
		     unsigned char *output)
{
    IntPoint	ip, newp;
    IPSIter	iter(source);
    double	temp;
    unsigned	masteridx=0;

    while (iter(ip)) {
	temp = 0;
	for (unsigned i=0; i<tcard; i++) {
	    newp = ip+tpoints[i];
	    unsigned idx = source.index(newp);
	    if (idx==IntPointSet::index_of_uncontained)
		continue;
	    temp += tvals[i]*input[idx];
	}
	output[masteridx++] = (unsigned char) temp;
    }
}

int main(int argc, char **argv)
{
    // malloc_debug(2);

    char	*disp=getenv("DISPLAY");
    if (disp==0) {
	cerr << "No DISPLAY environment variable, hasta.\n";
	exit(1);
    }

    IDP::ClientID	cid;
    cid = IDP::NewClient("iac++ test013");

    IDP::LinkID		lid;
#if 1
    if (argc!=2) {
	cerr << "Usage:\n" << argv[0] << " fname\n";
	exit(1);
    }
    char	*fname=argv[1];

    FILE	*fp;
    fp = fopen(fname, "r");
    if (!fp) {
	perror("opening file");
	exit(1);
    }

    int	width,height, maxval;
    if (3!=fscanf(fp, "P5 %d %d %d", &width, &height, &maxval)) {
	cerr << "Error: was expecting raw PGM (P5) image in file "
	     << fname << "\n";
	exit(1);
    }
    Array<unsigned> dims(2);
    dims[0] = height;
    dims[1] = width;

    int	ch;
    if ((ch=getc(fp))!='\n')
	ungetc(ch, fp);

    int	size = width*height;
    unsigned char	*ivalues;

    ivalues = new unsigned char[size];

    if (!fread(ivalues, size, 1, fp)) {
	perror("reading");
	exit(1);
    }
#else
    lid = IDP::PickDisplay(cid, disp, IDP::READ_ONLY);
    cout << "display picked" << endl;
    sleep(10);

    Array<unsigned>	dims;
    unsigned	elsize;
    IDP::ImageType	type;
    const unsigned char	*ivalues =
	(unsigned char *)IDP::ReadImage(lid, 1, &type, &elsize, &dims);
#endif

    IntPointSet	ps(extend_to_point(0, dims.len()),
		   IntPoint((int*)dims.data_start(), dims.len())-1);
    IntPointSet::throw_on_index_uncontained = 0;


    const int gsize=7;
    const IntPoint	gauss1[gsize] = {
	IntPoint(-3,0),
	    IntPoint(-2,0),
	    IntPoint(-1,0),
	    IntPoint(0, 0),
	    IntPoint( 1,0),
	    IntPoint( 2,0),
	    IntPoint( 3,0),
	};
    const IntPoint	gauss2[gsize] = {
	IntPoint(0,-3),
	    IntPoint(0,-2),
	    IntPoint(0,-1),
	    IntPoint(0, 0),
	    IntPoint(0, 1),
	    IntPoint(0, 2),
	    IntPoint(0, 3),
	};
    static const double	gvalues[gsize] = {
	0.00443,
	    0.05399,
	    0.24197,
	    0.39894,
	    0.24197,
	    0.05399,
	    0.00443,
	};

    lid = IDP::CreateDisplay(cid, disp, IDP::READ_WRITE);
    sleep(5); // avoid goddamn race condition
    IDP::WriteImage(lid, "original", IDP::U_BYTE, 1, dims, ivalues);

    IntPoint	ip, newp;
    IPSIter	iter(ps);
    unsigned char	*stage1 = new unsigned char[ps.card()];
    unsigned char	*stage2 = new unsigned char[ps.card()];

    custom_convolve(ps, ivalues, gsize, gauss1, gvalues, stage1);

    lid = IDP::CreateDisplay(cid, disp, IDP::READ_WRITE);
    sleep(5); // avoid goddamn race condition
    IDP::WriteImage(lid, "gaussed once", IDP::U_BYTE, 1, dims, stage1);

    custom_convolve(ps, stage1, gsize, gauss2, gvalues, stage2);

    lid = IDP::CreateDisplay(cid, disp, IDP::READ_WRITE);
    sleep(5); // avoid goddamn race condition
    IDP::WriteImage(lid, "gaussed twice", IDP::U_BYTE, 1, dims, stage2);
}
