From: bradst@knex (John Bradstreet)
Subject: Buggy semi data routine needs help
Organization: /users/bradst/.organization
Date: Sat, 3 Oct 1992 05:58:43 GMT


Ok, I give up.  What am I doing wrong???

I'm trying to write a module where I put a lattice on an output port
by myself instead of relying entirely on the data wrapper to do this.
This almost, but not quite works.  You need to 'fire' it after
hooking up the connection, which is the bug.

A brief example is listed below, which includes comments, and the
uuencoded .mres file is listed at the bottom if the bug isn't obvious
to the naked eye.

/* ------------------------------------------------------------------------
 * Buggy.c
 *
 *	Simple explorer module to test creating an output
 *	image of a desired size, with interesting (!) module
 *	data wrapper interaction bug.
 *
 *	To run, use `mbuilder' should create a module `Buggy'
 *	with:
 *	     User Func:     Buggy.c
 *	     Output Port    "Out_Img", type Lattice.
 *	     Function Args   Do_Buggy(), no arguments.
 *
 *  Running under Explorer 1.0, this has the following 
 *  problem, all probably caused by the same misunderstanding
 *  of how to put data on an output port.
 *  
 *	When you connect the module to DisplayImg, nothing
 *	gets displayed until you hit Buggy's Fire Button.
 *	'ReadImg' or 'GenLat' on the other hand, display 
 *	their data immediately on connection to DisplayImg.
 *	This is really anoying, not so much for this stupid
 *	little module, but because some of my bigger modules,
 *	which use the same trick, don't work quite right
 *	They almost work - that's what's so anoying!
 *
 *  If you rewrite this module so the output image gets created
 *  in the wrapper and then passed into this routine, it 
 *  opperates correctly.  Therefore, the problem has something
 *  to do with the way the output image is allocated and placed
 *  on the port.  However, I've checked the wrapper code on such 
 *  routines and it looks very similar to the code below. 
 *  What's wrong? 
 *
 *  Poking about in dbx on a module that Buggy deposits its
 *  data into, one notices that the reference count of the
 *  lattice Buggy generated is only 1, while a lattice
 *  GenLat's generated is 2. Now, this can be corrected by 
 *  uncommenting out the cxDataRefInc() call in the output 
 *  port generation code.  However, calling RefInc is not 
 *  recommended, and even if you do add it, the problem
 *  still doesn't work.
 *
 * ----------------------------------------------------------------------- */

#include <stdio.h>

#include <cx/DataAccess.h>
#include <cx/PortAccess.h>


gen_random(char * img_dst, long nDim, long *dims, long nbands)
{
  register int			j, b;
  register unsigned char	*out;
  int tsize;

/*  srandom((int) 100); */

  tsize = nbands;
  for(j = 0; j < nDim; j++) tsize *= dims[j];

  out = img_dst;
  for(j = tsize; --j; j > 0) 
    *out++ = (unsigned char) random();
}

				/* simple explorer module */
Do_Buggy()
{
  long xdim	= 64;
  long ydim	= 64;
  long nbands 	= 3;		/* colored noise for fun */

  long dims[2];
  long nDim = 2;
  char * out_port_name = "Out_Img"; /* set as name in output port */
  cxLattice *dst_lat = NULL;
  cxCoord   *dst_coords = NULL;
  cxData    *dst_data = NULL ;
  char *out_data;

  dims[0] = xdim;
  dims[1] = ydim;

#define TEST_ERROR if(cxDataAllocErrorGet()) \
  { cxModAlert("Alloc Error"); goto malloc_error; }

				/* create output lattice */
  dst_lat  = cxLatRootNew(nDim, dims);
  TEST_ERROR;
				/* create place to store data */
  dst_data = cxDataNew(nDim, dims, nbands, cx_prim_byte);
  TEST_ERROR;
				/* create coordinates */
  dst_coords = cxCoordDefaultNew(nDim, dims);
  TEST_ERROR;

				/* put all the pointers together */
  cxLatPtrSet(dst_lat, dst_data, NULL, dst_coords, NULL);

  /* random note: creating Lattice with CxLatNew(), without */
  /* creating coordinates, causes 0 sized bounding box to be */
  /* created, which in turn causes DisplayImg() to core dump. */

				/* shared mem array to stuff */
  out_data = (char *) cxDataValsGet(dst_data);
				/* fill our array with noise */
  gen_random(out_data, nDim, dims, nbands);


				/* now, try to write the results */
  				/* pretty sure error is in here */ 
				/* someplace, above like example */
				/* on B-13 of Module Writer's Guide */
  {
    int out_port = cxOutputPortOpen(out_port_name);	
    if(out_port != -1) {

	/* uncommenting this makes it work slightly better */
	/*    but it still doesn't work right. */
      cxDataRefInc(dst_lat);

      cxOutputDataSet(out_port, (void *) dst_lat);
      cxOutputDataFlush(out_port); /* needed */
    } else {
      char buff[512];
      sprintf(buff,"Unable to connect to port %s",out_port_name);
      cxModAlert(buff);
      goto malloc_error;
    }
  }
  return;

 malloc_error:
  cxDataRefDec(dst_data);
  cxDataRefDec(dst_coords);
  cxDataRefDec(dst_lat);
  return;
}


-------------------------------------------------------------
       uuencoded .mres file
-------------------------------------------------------------

begin 664 Buggy.mres
M(R%E>'!L;W)E<B!C>$UO9'5L95)E<V]U<F-E<R!B:6YA<GD@,2XP"B,@;F%M
M92!"=6=G>0HC(&UA:V5F:6QE(`HC(&EN8VQU9&5$:7)S(`HC('5S97),:6)S
M(`HC(&%O=70@0G5G9WD*(R!M8W=4>7!E(&-X7VUC=U]D969A=6QT"B,@;61W
M1FEL94YA;64@0G5G9WDN;61W+F,*(R!R95=R87!/:V%Y(&-X7W1R=64*(R!L
M:6YK86=E5'EP92!C>%]L:6YK86=E7V-C"B,@9FEL96YA;64@0G5G9WDN8PHC
M(&YU;49U;F-T:6]N<R`Q"@P,"@````A"=6=G>0````````0`=&0`````!```
M```````$``````````0`````````!````````````````0`````````$````
M``````0`````````!``````````$```````````````$``````````Q"=6=G
M>2YM9'<N8P```````````0`````````!`````0````Q"=6=G>2YD;V,`````
M````_____P````#_____`````0````(````!`````P````A"=6=G>0```/__
M__\``````````0`````````!````#$1O7T)U9V=Y``````````A"=6=G>2YC
M`````````````````/____\``````````````````````````0````0`````
M```````````````!``````````A/=71?26UG```````````!`````0``````
M`````````0````$````%````!P````8````!``````````#_____````!```
M```````$``````````0`````````!``````````$``````````$`````````
M`````````````````````````````````/____\````!``````````#_____
M`````0```!!C>%]D871A7VQA='1I8V4`````!P````@M/F1A=&$```````$`
M```'````""T^8V]O<F0``````0````@````(+3YN1&EM```````!````"0``
M`!0M/F1A=&$M/FY$871A5F%R`!!MH`````$````*````%"T^9&%T82T^<')I
M;51Y<&4`$&[H`````0````L````4+3YC;V]R9"T^8V]O<F14>7!E`#`````!
M````#````"PM/F-O;W)D+3YC+F-X7V-O;W)D7V-U<G9I;&EN96%R+FY#;V]R
M9%9A<@``"@````$````-`````0```!`H*&-X1&%T82`J*2`Q*0``_____P``
M``$````0*"AC>$-O;W)D("HI(#$I`/____\````!````!#$```#_____````
M`0````0Q`+TP_____P````$````08WA?<')I;5]B>71E`````````!!C>%]P
M<FEM7V1O=6)L90```````0```!1C>%]C;V]R9%]U;FEF;W)M`!!Q>````!AC
G>%]C;V]R9%]C=7)V:6QI;F5A<@`````````!````!#$``$;_____
`
end