Exemple #1
0
/* fut_new_gtbl creates a new grid table and optionally intializes it.
 * The input channels defined for the grid are specified in the input
 * channel mask portion of iomask.	Each input defined must have a size
 * specified in a KpInt32_t array.
 * Gfun must be a pointer to a function accepting from zero to three
 * doubles (depending on values of sx, sy, and sz) in the range (0.0,1.0)
 * and returning a fut_gtbldat_t in the range (0,FUT_GRD_MAXVAL).
 * A pointer to the newly allocated table is returned if there were no
 * errors.	(If gfun is NULL, the table is not initialized).
 */
fut_gtbl_p
	fut_new_gtblEx (	PTTableType_t	tableType,
						KpInt32_t		iomask,
						fut_gfunc_t		gfun,
						fut_calcData_p	data,
						KpInt32_p		dimList)
{
fut_gtbl_p	gtbl;
KpInt32_t	imask, i, dim_size, grid_size;

					/* get input mask */
	imask = (KpInt32_t)FUT_IMASK(iomask);

					/* allocate grid table structure */
	gtbl = fut_alloc_gtbl ();
	if ( gtbl == FUT_NULL_GTBL ) {
		DIAG("fut_new_gtblA: can't alloc grid table struct.\n", 0);
		return (FUT_NULL_GTBL);
	}

	/* get sizes from dimList */
	grid_size = 1;
	for ( i=0; i<FUT_NCHAN; i++ ) {
		dim_size = (imask & FUT_BIT(i)) ? dimList[i] : 1;
		if ( dim_size <= 0 ) {
			dim_size = 1;		/* make sure > 0 */
		}
		gtbl->size[i] = (KpInt16_t)dim_size;
		grid_size *= (KpInt32_t)dim_size;
	}

					/* check for valid grid size */
	if ( grid_size <= 0 || grid_size > FUT_GRD_MAX_ENT ) {
		DIAG("fut_new_gtblA: bad grid table size (%d).\n", grid_size);
		fut_free_gtbl(gtbl);
		return (FUT_NULL_GTBL);
	}
	gtbl->tbl_size = (KpInt32_t)grid_size * (KpInt32_t)sizeof(fut_gtbldat_t);

					/* allocate grid table */
	if (tableType == KCP_PT_TABLES) {
		gtbl->refTbl = fut_alloc_gtbldat (gtbl);
	} else {
		gtbl->refTbl = fut_alloc_gmftdat (gtbl);
	}
	if ( gtbl->refTbl == NULL ) {
		DIAG("fut_new_gtblA: can't alloc grid table array.\n", 0);
		fut_free_gtbl(gtbl);
		return (FUT_NULL_GTBL);
	}

					/* compute the grid table entries */
	if ( ! fut_calc_gtblEx (gtbl, gfun, data) ) {
		fut_free_gtbl(gtbl);
		return (FUT_NULL_GTBL);
	}

	return (gtbl);
}
Exemple #2
0
/* fut_defchan defines an output channel for a fut.	Returns FALSE(0) if
 * the output channel is already defined (or fut is NULL), TRUE(1)
 * otherwise.  The size of the grid table (if non-zero) must match those
 * of the corresponding input table.  If they do not, the channel remains
 * undefined and FALSE is returned.
 *
 * If a required input table is missing, the table will be shared
 * with the corresponding one from the list of common itbls.  If there
 * is no such table in the common list, a ramp table is created and
 * inserted into the common itbl list.
 *
 * Since fut_defchan is intended to be used for constructing futs with
 * shared input tables,	if an input table is supplied that conflicts with
 * a table in the common list, an error occurs.
 */
KpInt32_t
	fut_defchan (	fut_p			fut,
					KpInt32_t		iomask,
					fut_itbl_p FAR*	itbls,
					fut_gtbl_p		gtbl,
					fut_otbl_p		otbl)
{
fut_itbl_p	itbl[FUT_NICHAN];
fut_chan_p	chan;
KpInt32_t	imask, i, tIndex;

					/* check for valid fut */
	if ( ! IS_FUT(fut)) {
		return (0);
	}
					/* get input mask */
	imask = (KpInt32_t) FUT_IMASK(iomask);

					/* get args specified by imask */
	for ( i=0, tIndex = 0; i < FUT_NICHAN; i++ ) {
		if ((itbls != NULL) && ((imask & FUT_BIT(i)) != 0)) { 	/* if itbl is in arglist, use it */
			itbl[i] = (fut_itbl_p)itbls[tIndex++];
		}
		else {	/* use itbl from shared itbl list */
			itbl[i] = fut->itbl[i];
		}
	}

	chan = fut_new_chan ((KpInt32_t)(FUT_IN (FUT_ALLIN)), (fut_itbl_p FAR*)itbl, gtbl, otbl);
	if ( ! IS_CHAN(chan)) {
		return (0);
	}

	/* If fut_new_chan created a new itbl (ramp), add it to the
	 * common list.	However, if an itbl in the chan differs from
	 * one in the common list, return an error.
	 */
	for ( i=0; i < FUT_NICHAN; i++ ) {
		if ( chan->itbl[i] == NULL ) {
			continue;
		}
		
		if ( ! IS_ITBL(fut->itbl[i])) {
			fut->itbl[i] = fut_share_itbl(chan->itbl[i]);
			fut->itblHandle[i] = chan->itblHandle[i];
		}
		else {
			if ( fut->itbl[i] != chan->itbl[i] ) {
				DIAG("fut_defchan: conflicting itbls.\n", 0);
				fut_free_chan (chan);
				return (0);
			}
		}
	}

					/* insert channel into fut */
	if ( ! fut_add_chan (fut, iomask, chan) ) {
		fut_free_chan (chan);
		return (0);
	}

	return (1);
}
Exemple #3
0
/* fut_new_chan allocates and initializes a fut_chan_t data structure.
 * If a required input table is missing, a ramp of the proper grid size
 * will be created.	If a supplied itbl is not required, it will not be
 * inserted into the channel's private itbl list.	All tables which are
 * actually used are copied and so the caller is responsible for
 * freeing the passed tables if necessary.
 *
 * If VARARGS is used, the list of input tables may be relaced by a
 * single array of fut_itbl_t pointers.	This array must then be followed
 * by a fut_gtbl_p and a fut_otbl_p.
 */
fut_chan_p
	fut_new_chan (	KpInt32_t		iomask,
					fut_itbl_p FAR*	itbls,
					fut_gtbl_p		gtbl,
					fut_otbl_p		otbl)
{
fut_itbl_p	itbl[FUT_NCHAN];
fut_chan_p	chan;
KpInt32_t	imask, i, tIndex;

	/* get input mask */
	imask = (KpInt32_t)FUT_IMASK(iomask);

	/* get args specified by imask */
	for ( i=0, tIndex = 0; i<FUT_NCHAN; i++ ) {
		itbl[i] = ((imask & FUT_BIT(i)) && (itbls != NULL)) ? itbls[tIndex++] : NULL;
	}

				/* allocate and clear the fut_chan_t structure */
	chan = fut_alloc_chan ();
	if ( ! IS_CHAN(chan)) {
		return (NULL);
	}

				/* check for valid grid and output tables */
	if (( ! IS_GTBL(gtbl)) || ((otbl != NULL) && ( ! IS_OTBL(otbl))) ) {
		DIAG("fut_new_chan: invalid grid or output table.\n", 0);
		fut_free_chan (chan);
		return (NULL);
	}

	/* get required input channels from gtbl */
	chan->imask = fut_gtbl_imask(gtbl);

				/* insert the required input tables */
	for ( i=0; i<FUT_NICHAN; i++ ) {
		if ( (chan->imask & FUT_BIT(i)) == 0 ) continue;

		if ( itbl[i] == FUT_NULL_ITBL ) {
			chan->itbl[i] = fut_new_itblEx (KCP_REF_TABLES, KCP_FIXED_RANGE, gtbl->size[i], fut_irampEx, NULL);
			if ( chan->itbl[i] == NULL) {
				DIAG("fut_new_chan: can't create itbl.\n",0);
				fut_free_chan (chan);
				return (NULL);
			}

			chan->itblHandle[i] = chan->itbl[i]->handle;
		}
		else {
			if ( ! IS_ITBL (itbl[i])) {
				DIAG("fut_new_chan: invalid input table.\n", 0);
				fut_free_chan (chan);
				return (NULL);
			}
			else {
				if ( itbl[i]->size != gtbl->size[i] ) {
					DIAG("fut_new_chan: gtbl-itbl size mismatch.\n", 0);
					fut_free_chan (chan);
					return (NULL);
				}
				else {
					chan->itbl[i] = fut_share_itbl(itbl[i]);	/* share the input table */
					chan->itblHandle[i] = chan->itbl[i]->handle;
				}
			}
		}
	}

					/* insert grid and output tables */
	chan->gtbl = fut_share_gtbl (gtbl);
	chan->gtblHandle =	(IS_GTBL(chan->gtbl)) ? chan->gtbl->handle : FUT_NULL_HANDLE;
	
	if (IS_OTBL(otbl)) {
		chan->otbl = fut_share_otbl (otbl);
	}
	else {
		chan->otbl = fut_alloc_otbl();
	}

	chan->otblHandle = (IS_OTBL(chan->otbl)) ? chan->otbl->handle : FUT_NULL_HANDLE;

	return (chan);
}
Exemple #4
0
/* fut_new allocates and initializes a new fut_t data structure.
 * iomask specifies which (common) input tables and which output channels
 * are being defined.	Additional channels may be added later using
 * fut_defchan.
 *
 * NOTES:
 *	1. All the tables must be packed into a single array.
 *
 *	2. If a needed input table is not supplied (as determined from the
 *	grid table) or if a supplied input table is NULL, then a ramp
 *	input table will be automatically generated and inserted into
 *	the common itbl list.	The grid sizes are inferred from the
 *	supplied grid tables.
 */
fut_p
	fut_new (	KpInt32_t		iomask,
				fut_itbl_p FAR*	itbls,
				fut_gtbl_p FAR*	gtbls,
				fut_otbl_p FAR*	otbls)
{
fut_itbl_p	itbl[FUT_NICHAN];
fut_otbl_p	otbl[FUT_NOCHAN];
fut_gtbl_p	gtbl[FUT_NOCHAN];
fut_p		fut;
KpInt32_t	tIndex, imask, omask, i;

					/* get input and output masks */
	imask = (KpInt32_t)FUT_IMASK(iomask);
	omask = (KpInt32_t)FUT_OMASK(iomask);
	if ( imask > FUT_ALLIN || omask > FUT_ALLOUT ) {
		DIAG("fut_new: too many input or output channels.\n", 0);
		return (NULL);
	}

	/* get args specified by iomask */
	for ( i=0, tIndex = 0; i<FUT_NICHAN; i++ ) {
		itbl[i] = (((imask & FUT_BIT(i)) != 0) && (itbls != NULL))
					? itbls[tIndex++] : FUT_NULL_ITBL;
	}
	for ( i=0, tIndex = 0; i<FUT_NOCHAN; i++ ) {
		gtbl[i] = FUT_NULL_GTBL;
		otbl[i] = FUT_NULL_OTBL;

		if ((omask & FUT_BIT(i)) != 0) {
			if (gtbls != NULL) {
				gtbl[i] = gtbls[tIndex];
			}

			if (otbls != NULL) {
				otbl[i] = otbls[tIndex];
			}

			tIndex++;
		}
	}

				/* allocate and clear the fut_t structure */
	fut = fut_alloc_fut ();
	if ( fut == NULL ) {
		return (NULL);
	}

				/* set the interpolation order */
	fut->iomask.order = (KpInt32_t)FUT_ORDMASK(iomask);

				/* insert the specified input tables */
	for ( i=0; i<FUT_NICHAN; i++ ) {
		if ( itbl[i] == NULL) continue;
		if ( ! IS_ITBL (itbl[i]) ) {
			fut_free (fut);
			return (NULL);
		}
		fut->iomask.in |= FUT_BIT(i);
		fut->itbl[i] = fut_share_itbl(itbl[i]);
		fut->itblHandle[i] = fut->itbl[i]->handle;
	}

				/* define the specified output channels */
	for ( i=0; i<FUT_NOCHAN; i++ ) {
		if ( gtbl[i] == NULL) continue;
		if ( ! fut_defchan(fut,FUT_OUT(FUT_BIT(i)),NULL,gtbl[i],otbl[i]) ) {
			fut_free (fut);
			return (NULL);
		}
	}
	fut->lutConfig = LUT_TYPE_UNKNOWN;
	return (fut);
}
Exemple #5
0
fut_p
	constructfut (	KpInt32_t		iomask,
					KpInt32_p		sizeArray,
					fut_calcData_p	fData,
					fut_ifunc_p		ifunArray,
					fut_gfunc_p		gfunArray,
					fut_ofunc_p		ofunArray,
					PTDataClass_t	iClass,
					PTDataClass_t	oClass)
{
fut_p		futp;
KpInt32_t	i1, imask, omask;
fut_itbl_p	itbls[FUT_NICHAN] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
fut_gtbl_p	gtbls[FUT_NOCHAN] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
fut_otbl_p	otbls[FUT_NOCHAN] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
fut_ifunc_t	ifun;
fut_gfunc_t	gfun;
fut_ofunc_t	ofun;
fData_t			fDataL;
fut_calcData_p	fDataP;

	if (sizeArray == NULL) return NULL;

	if (fData == NULL) {
		fDataP = &fDataL.std;
	}
	else {
		fDataP = fData;
	}
	
	imask = FUT_IMASK(iomask);
	omask = FUT_OMASK(iomask);

	#if defined KCP_DIAG_LOG
	{KpChar_t	string[256], str2[256];
	KpInt32_t	i1;
	sprintf (string, "constructfut\n iomask %x, sizeArray[]", iomask);
	for (i1 = 0; i1 < FUT_NICHAN; i1++) {
		if ((FUT_BIT(i1) & imask) != 0) {
			sprintf (str2, " %d", sizeArray[i1]);
			strcat (string, str2);
		}
	}
	sprintf (str2, ", fData %x, ifunArray %x, gfunArray %x, ofunArray %x, iClass %d, oClass %d\n",
					fData, ifunArray, gfunArray, ofunArray, iClass, oClass);
	strcat (string, str2);
	kcpDiagLog (string);}
	#endif
	
	/* Compute shared input tables:  */
	for (i1 = 0; i1 < FUT_NICHAN; i1++) {
		if ((imask & FUT_BIT(i1)) != 0) {
			if ((ifunArray == NULL) || (ifunArray[i1] == NULL)) {
				ifun = fut_irampEx;
				fDataP = &fDataL.std;
				if (iClass == KCP_VARIABLE_RANGE) {
					fDataL.scale = KCP_16_TO_8_ENCODING;
				}
				else {
					fDataL.scale = 1.0;
				}
			}
			else {
				ifun = ifunArray[i1];
			}

			fDataP->chan = i1;	/* define the channel # */

			itbls[i1] = fut_new_itblEx (KCP_REF_TABLES, iClass, sizeArray[i1], ifun, fDataP);
			itbls[i1]->id = fut_unique_id ();
			itbls[i1]->dataClass = iClass;
		}
	}

	/* Compute grid tables and output tables:  */
	for (i1 = 0; i1 < FUT_NOCHAN; i1++) {
		if ((omask & FUT_BIT(i1)) != 0) {
			if ((gfunArray == NULL) || (gfunArray[i1] == NULL)) {
				gfun = fut_grampEx;
			}
			else {
				gfun = gfunArray[i1];
			}

			fDataP->chan = i1;	/* define the channel # */

			gtbls[i1] = fut_new_gtblEx (KCP_REF_TABLES, iomask, gfun, fDataP, sizeArray);
			gtbls[i1]->id = fut_unique_id();

			if ((ofunArray == NULL) || (ofunArray[i1] == NULL)) {
				ofun = fut_orampEx;
				fDataP = &fDataL.std;
				if (oClass == KCP_VARIABLE_RANGE) {
					fDataL.scale = KCP_8_TO_16_ENCODING;
				}
				else {
					fDataL.scale = 1.0;
				}
			}
			else {
				ofun = ofunArray[i1];
			}

			otbls[i1] = fut_new_otblEx (KCP_REF_TABLES, oClass, ofun, fDataP);
			otbls[i1]->id = fut_unique_id();
			otbls[i1]->dataClass = oClass;
		}
	}

	/* Assemble FuT:  */
	futp = fut_new (iomask, itbls, gtbls, otbls);

	fut_free_tbls (FUT_NICHAN, (KpGenericPtr_t *)itbls);
	fut_free_tbls (FUT_NOCHAN, (KpGenericPtr_t *)gtbls);
	fut_free_tbls (FUT_NOCHAN, (KpGenericPtr_t *)otbls);

	if (fut_to_mft (futp) != 1) {		/* convert to reference tables */
		fut_free (futp);
		futp = NULL;
	}

	return (futp);
}
/* fut_comp_ilut composes a set of 8 or 12-bit, 256 element look-up tables
 * with the input tables of a fut.  These may have been derived from
 * another separable fut.  A new fut is returned which shares grid and
 * output tables with the original but has new input tables.
 *
 * Iomask usage:
 *	imask => luts defined in vararglist to be composed with itbls.
 *		A NULL imask indicates one lut which is composed with
 *		the first defined input table.
 *	omask => unused
 *	pmask => unused
 *	INPLACE may be set to perform the composition in place,
 *		replacing the existing itbls and returning a pointer
 *		to the original fut.
 *	VARARGS may be used to specify an array of luts.
 *	12BITS  if set, supplied luts are 12-bit data (KpInt16_t).
 *		Otherwise, they are 8-bit (KpUInt8_t).
 */
fut_p
	fut_comp_ilut (	fut_p				fut,
					KpInt32_t			iomask,
					KpGenericPtr_t FAR*	srcluts)
{
KpChar_p	luts[FUT_NICHAN];
KpInt32_t	i, i2;
KpInt32_t	imask;
KpInt32_t	is_12bits;
KpInt32_t	in_place;
fut_p		new_fut;
fut_itbl_p	new_itbl;
fut_itbl_p	orig_itbls[FUT_NICHAN];

	if ( ! IS_FUT(fut) )
		return (FUT_NULL);

	/* unpack input mask.  If zero, use first defined channel */
	imask = (KpInt32_t)FUT_IMASK(iomask);
	if (imask == 0 ) {
		imask = (KpInt32_t)FUT_BIT(fut_first_chan((KpInt32_t)fut->iomask.in));
		iomask |= FUT_IN(imask);
	}

					/* get args specified by iomask */
	for ( i=0, i2 = 0; i<FUT_NICHAN; i++ ) {
		if (imask & FUT_BIT(i)) {
			luts[i] = srcluts[i2];	/* save lut address in array */
			i2++;
		}

	}

	/* if INPLACE is not set, create a new fut which shares all of its tables */
	in_place = (KpInt32_t)FUT_IPMASK(iomask);
	if ( in_place ) {
		new_fut = fut;
	}
	else {
		new_fut = fut_copy (fut);
	}

					/* unpack 12bit data flag */
	is_12bits = (KpInt32_t)FUT_12BMASK(iomask);

	/* for each lut passed, compose it with the specified input table(s) */
	/* start by composing the common itbls */
	for ( i=0; i<FUT_NICHAN; i++) {
		/* save original itbls for future comparison */
		orig_itbls[i] = fut->itbl[i];

		/* if no lut or no itbl, there's nothing to do. */
		if ( luts[i] == 0 || fut->itbl[i] == FUT_NULL_ITBL )
			continue;

		/* compose itbl with fut and replace the existing one. */
		new_itbl = fut_comp_itbl_ilut (fut->itbl[i], luts[i], is_12bits);
		if ( new_itbl == FUT_NULL_ITBL ) {
			if ( ! in_place )
				fut_free (new_fut);
			return (FUT_NULL);
		}
		fut_free_itbl (new_fut->itbl[i]);
		new_fut->itbl[i] = new_itbl;
	}

	/* now compose the itbls in each chan, re-sharing if possible */
	for ( i=0; i<FUT_NOCHAN; i++) {
		if ( new_fut->chan[i] == FUT_NULL_CHAN )
			continue;

		if ( ! fut_comp_chan_ilut (new_fut->chan[i], (KpChar_p FAR*)luts,
									orig_itbls, new_fut->itbl, is_12bits) ) {
			if ( ! in_place ) {
				fut_free (new_fut);
			}

			return (FUT_NULL);
		}
	}

	return (new_fut);
}