Esempio n. 1
0
fut_p
	fut_free_futH (KpHandle_t futHandle)
{
fut_p fut;
	
	fut = (fut_p) lockBuffer(futHandle);

	if (IS_FUT(fut)) {

					/* free id string if exists */
	/*	fut_free_idstr (fut->idstr); */

					/* free shared input tables */
		fut_free_itbl_list_p (fut->itbl, fut->itblHandle);

					/* free channels */
		fut_free_chan_list_p (fut->chan, fut->chanHandle);

					/* free fut_t structure itself */
		fut->magic = 0;
		freeBufferPtr ((KpGenericPtr_t)fut);
	}

	return ((fut_p)NULL);
}
Esempio n. 2
0
fut_p
	fut_free (fut_p	fut)
{
KpInt32_t	i;

	if ( ! IS_FUT(fut)) {			/* check if defined */
		return (fut);
	}

/*	fut_free_idstr (fut->idstr); */	/* free id string if exists */

	fut_free_itbl_list (fut->itbl);	/* free shared input tables */

	for ( i=0; i<FUT_NOCHAN; i++ ) {	/* free channels */
		fut_free_chan (fut->chan[i]);
		fut->chan[i] = FUT_NULL_CHAN;
	}

	for ( i=0; i<FUT_NMCHAN; i++ ) {	/* free extra reference tables */
		freeBuffer (fut->mabInRefTblHandles[i]);
		fut->mabInTblEntries[i] = 0;
		fut->mabInRefTbl[i]= NULL;
		fut->mabInRefTblHandles[i] = NULL;

		freeBuffer (fut->mabOutRefTblHandles[i]);
		fut->mabOutTblEntries[i] = 0;
		fut->mabOutRefTbl[i]= NULL;
		fut->mabOutRefTblHandles[i] = NULL;
	}
	
	fut->magic = 0;					/* free fut_t structure itself */
	freeBufferPtr ((KpGenericPtr_t)fut);

	return ((fut_p)NULL);
}
Esempio n. 3
0
/* fut_add_chan inserts a new output channel into a fut.
 * Unlike itbls, otbls, and gtbls, the channel structure is not sharable
 * and so the caller must not free the chan after this call.	(If the
 * passed channel structure needs to be saved, use fut_copy_chan).
 * The iomask in this case simply tells which output channel is being
 * added, and if this channel already exists, an error (0) is returned.
 *
 * fut_add_chan is intended to be used in conjunction with fut_new_chan
 * to construct futs with independent input tables.	It does not update
 * the list of common input tables as does fut_new and fut_defchan and
 * should not be mixed with calls to fut_defchan.
 */
KpInt32_t
	fut_add_chan (fut_p	fut, KpInt32_t iomask, fut_chan_p chan)
{
	KpInt32_t		ochan;

	if ( ! IS_FUT(fut) || (chan != FUT_NULL_CHAN && ! IS_CHAN(chan)) ) {
		return (0);
	}

					/* get output channel no. */
	ochan = FUT_CHAN ((KpInt32_t)FUT_OMASK(iomask));

					/* prohibit redefinition of channel */
	if ( ochan >= FUT_NOCHAN || fut->chan[ochan] != NULL)
		return (0);
					/* insert channel into fut */
	fut->chan[ochan] = chan;
	fut->chanHandle[ochan] = (IS_CHAN(fut->chan[ochan])) ?
								fut->chan[ochan]->handle : FUT_NULL_HANDLE;

					/* update iomasks */
	if ( IS_CHAN(chan) ) {
		fut->iomask.out |= FUT_BIT(ochan);
		fut->iomask.in |= chan->imask;
	}

	return (1);
}
Esempio n. 4
0
/* initialize a PT for export
 * lock and return pointers to the header and fut
 * make the tables for the specified export format
 */
PTErr_t
	initExport (	KpHandle_t		PTHdr,
					KpHandle_t		PTData,
					PTType_t		format,
					fut_hdr_p FAR*	futHdrP,
					fut_p FAR*		futP)
{
PTErr_t		errnum = KCP_SUCCESS;
fut_p		fut;
fut_hdr_p	futHdr;
KpInt32_t	status;

/* get fut pointer */
	fut = fut_lock_fut ((KpHandle_t)PTData);
	if ( ! IS_FUT(fut)) {
		errnum = KCP_PTERR_2;
		goto GetOut;
	}

/* get header pointer of checked in PT */
	futHdr = (fut_hdr_p) lockBuffer (PTHdr);
	if (futHdr == NULL) {
		errnum = KCP_MEM_LOCK_ERR;
		goto GetOut;
	}

	if (format == PTTYPE_FUTF) {	/* make fixed tables */
		status = makeFutTblDat (fut);
		if (status != 1) {
			fut_free_tbldat	(fut);
			errnum = KCP_INCON_PT;
		}
	}
	else {
		status = makeMftTblDat (fut);
		if (status != 1) {
			fut_free_mftdat	(fut);
			errnum = KCP_INCON_PT;
		}
	}
	

GetOut:
	if (errnum == KCP_SUCCESS) {
		*futP = fut;		/* return pointers to caller */
		*futHdrP = futHdr;
	}
	else {
		(void) unlockPT (PTHdr, fut);
		*futP = NULL;
		*futHdrP = NULL;
	}

	return errnum;
}
Esempio n. 5
0
/* TpFreeData frees all of the memory allocated for a fut.
 */
PTErr_t
	TpFreeData (	KpHandle_t	PTData)
{
PTErr_t errnum = KCP_PTERR_2;
fut_p fut;

	fut = fut_lock_fut ((KpHandle_t)PTData);
	if (IS_FUT(fut)) {
		fut_free (fut);
		errnum = KCP_SUCCESS;
	}

	return errnum;
}
Esempio n. 6
0
void
	fut_free_mftdat		(fut_p	fut)
{
KpInt32_t	i;
fut_chan_p	chan;

	if (IS_FUT(fut)) {
		fut_free_itbldat_list (&fut->itbl[0], FUT_MFTDATA);
		
		for ( i=0; i<FUT_NOCHAN; i++ ) {
			chan = fut->chan[i];
			if (IS_CHAN(chan)) {
				fut_free_itbldat_list (&chan->itbl[0], FUT_MFTDATA);
				fut_free_gmftdat (chan->gtbl, freeData);
				fut_free_omftdat (chan->otbl, freeData);
			}
		}
	}
}
Esempio n. 7
0
/* check the input and output data class of a PT
 * if a color space is known and the data class is not known,
 * set the data class to correspond to the color space
 */
void
	checkDataClass (PTRefNum_t	PTRefNum)
{
KpInt32_t		i1;
KpHandle_t		PTData;
fut_p			fut;
fut_chan_p		chan;
fut_otbl_p		otbl;
PTDataClass_t	iDataClass, oDataClass;

	iDataClass = getPTDataClass (PTRefNum, KCM_IN_SPACE);
	oDataClass = getPTDataClass (PTRefNum, KCM_OUT_SPACE);

	PTData = getPTData (PTRefNum);
	fut = fut_lock_fut (PTData);
	if ( ! IS_FUT(fut)) return;		/* bummer */

	checkInDataClass (iDataClass, fut->itbl);	/* check the data class of each shared input table */

	for (i1 = 0; i1 < FUT_NOCHAN; i1++) {
		chan = fut->chan[i1];

		if (IS_CHAN(chan)) {
			checkInDataClass (iDataClass, chan->itbl);	/* check the data class of each input table */

			if (oDataClass != KCP_UNKNOWN) {	/* check the data class of each output table */
				otbl = chan->otbl;
				if ((IS_OTBL(otbl)) && (otbl->dataClass == KCP_UNKNOWN)) {
					otbl->dataClass = oDataClass;
				}
			}
		}
	}
	
	fut_unlock_fut (fut);
}
Esempio n. 8
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);
}
Esempio n. 9
0
fut_p
	fut_resize (	fut_p		fut,
					KpInt32_p	sizeArray)
{
fut_p		reSizedGtblFut = NULL, gtblFut = NULL, reSizedFut = NULL, identityFut = NULL;
KpInt32_t	i1, i2, iomask, iiomask, imask, omask, sameDims;
fut_chan_p	chan;
fut_itbl_p	itbl, itbls[FUT_NICHAN];
fut_gtbl_p	gtbls[FUT_NOCHAN];
fut_otbl_p	otbls[FUT_NOCHAN];

	#if defined KCP_DIAG_LOG
	kcpDiagLog ("fut_resize\n");
	#endif
	
	if ( ! IS_FUT(fut)) {
		return NULL;
	}

	for (i1 = 0; i1 < FUT_NICHAN; i1++) {
		itbls[i1] = FUT_NULL_ITBL;			/* init to null for freeing on error */
	}

	/* collect the gtbls from the source fut */
	/* make sure that all the gtbls use the same itbls */
	omask = 0;
	
	for (i1 = 0, sameDims = 1; i1 < FUT_NOCHAN; i1++) {
		chan = fut->chan[i1];
		if (IS_CHAN(chan)) {
			for (i2 = 0; i2 < FUT_NICHAN; i2++) {
				itbl = fut->itbl[i2];
				if (chan->itbl[i2] != itbl) {	/* must be shared */
					goto GetOut;
				}
				
				if (IS_ITBL(itbl)) {
					if (itbl->size != sizeArray [i2]) {
						sameDims = 0;			/* not the same */
					}
				}
			}

			omask |= FUT_BIT(i1);			/* resize this chan */
			gtbls[i1] = chan->gtbl;			/* collect gtbls */
		}
		else {
			gtbls[i1] = NULL;
		}
	}

	if (sameDims == 1) {
		return fut;		/* already the right size! */
	}

	imask = fut->iomask.in;
	iomask = FUT_OUT(omask) | FUT_IN(imask);
	
	/* make a new fut with these gtbls and identity itbls and otbls */
	gtblFut = fut_new (iomask, NULL, gtbls, NULL);
	if (gtblFut != NULL) {

		/* make an identity fut with itbls that have the specified sizes */
		iiomask = FUT_OUT(imask) | FUT_IN(imask);
		identityFut = constructfut (iiomask, sizeArray, NULL, NULL, NULL, NULL, KCP_FIXED_RANGE, KCP_FIXED_RANGE);
		if (identityFut != NULL) {
		
			/* compose the new size fut with the gtbl fut */
			reSizedGtblFut = fut_comp (gtblFut, identityFut, 0);
			if (reSizedGtblFut != NULL) {

				/* make a new fut with original itbls, ... */
				for (i1 = 0; i1 < FUT_NICHAN; i1++) {
					if ((imask & FUT_BIT(i1)) != 0) {
						itbls[i1] = fut_copy_itbl (fut->itbl[i1]);			/* copy (do not share!) original itbls */
						if (itbls[i1] == NULL) {
							goto GetOut;
						}
						makeMftiTblDat (itbls[i1]);							/* convert to mft to remove grid size dependancy */
						itbls[i1]->size = reSizedGtblFut->itbl[i1]->size;	/* set new grid size */
						fut_free_itbldat (itbls[i1], freeData);				/* free fixed table, it has incorrect grid indices */
					}
				}

				/* ... resized gtbls, and original otbls */
				for (i1 = 0; i1 < FUT_NOCHAN; i1++) {
					if ((omask & FUT_BIT(i1)) != 0) {
						gtbls[i1] = reSizedGtblFut->chan[i1]->gtbl;	/* collect resized gtbls */
						otbls[i1] = fut->chan[i1]->otbl;			/* and original otbls */
					}
					else {
						gtbls[i1] = NULL;
						otbls[i1] = NULL;
					}
				}

				reSizedFut = fut_new (iomask, itbls, gtbls, otbls);
			}
		}
	}

GetOut:
	fut_free (reSizedGtblFut);	/* free the intermediate futs */
	fut_free (gtblFut);
	fut_free (identityFut);
	fut_free_tbls (FUT_NICHAN, (void **)itbls);

	return (reSizedFut);
}
Esempio n. 10
0
/* 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);
}
Esempio n. 11
0
fut_p
	fut_comp (fut_p fut1, fut_p fut0, KpInt32_t iomask)
{
KpInt32_t		ok = 1, nGridPoints, omask, evalomask, imask, pmask, order, i, j, nEntries, nOutChans;
fut_p			fut2 = NULL, evalFut = NULL;
fut_itbl_p		oitbls[FUT_NICHAN];
mf2_tbldat_p	indat[FUT_NICHAN], outdat[FUT_NOCHAN];
fut_gtbl_p		fut1_gtbls[FUT_NOCHAN];

	if (( ! IS_FUT(fut0)) || ( ! IS_FUT(fut1))) {
		return (NULL);
	}

	/* extract component masks from iomask */
	omask = FUT_OMASK(iomask);		/* which output chans? */
	pmask = FUT_PMASK(iomask);		/* which ones allowed to pass through? */
	order = FUT_ORDMASK(iomask);	/* which interpolation to use? */
	if ( order == FUT_DEFAULT ) {
		order = fut1->iomask.order;
	}

	/* adjust masks for iomask_check below */
	pmask &= fut0->iomask.out;		/* available for "pass through" */
	if ( omask == 0 ) {				/* required outputs (0 means all) */
		omask = fut1->iomask.out;
	}

	/* see if fut0 can provide required inputs to fut1 */
	imask = fut0->iomask.out;		/* available inputs for fut1 */
	iomask = FUT_OUT(omask) | FUT_IN(imask) | FUT_PASS(pmask);
	if ( ! fut_iomask_check (fut1, iomask) ) {
		return (NULL);
	}

	/* make sure the futs are in the reference state */
	if ((fut_to_mft (fut0) != 1) || (fut_to_mft (fut1) != 1)) {
		return (NULL);
	}	

	/* fut1 will be used to process the grid tables of fut0, placing the
	 * results in the grid tables of fut2.  Fut0's grid table data must first
	 * be passed through its output tables before sending it through fut1's
	 * input tables.  This is accomplished more efficiently by composing
	 * fut1's input tables with fut0's output tables and using these directly
	 * on fut0 grid data rather than the normal input tables.
	 *
	 * Create the result fut (fut2) which will be the composition of fut1
	 * and fut0.  Fut2 will inherit the input tables of fut0 and the output
	 * tables of fut1.  Its grid data will be in the same color coordinates
	 * as fut1's.
	 */
	fut2 = fut_new (FUT_IN(FUT_ALLIN), fut0->itbl, NULL, NULL);
	if ( fut2 == NULL ) {
		return (NULL);
	}

	/* for each desired channel i in fut2, create a new grid table.  The
	 * dimensions of each new grid table are derived from fut0 and fut1
	 * like so:  for every input required for channel i of fut1, form the
	 * union of the input sets of all corresponding fut0 outputs.
	 */

	/* null all io tables and table pointers */
	KpMemSet (oitbls, 0, sizeof(oitbls));

	imask = 0;			/* will be the input mask for all inputs needed to fut1 */
	evalomask = 0;		/* omask for evaluation */

	for (i = 0; (i < FUT_NOCHAN) && ok; i++) {
		KpInt32_t	size[FUT_NICHAN];
		fut_gtbl_p	gtbl;
		KpInt32_t	imask1, imask2;

		fut1_gtbls[i] = NULL;	/* assume not needed */

		if ((omask & FUT_BIT(i)) == 0) {	/* is this output channel needed? */
			continue;						/* no */
		}

		/* if a specified output is to be passed through from fut0, do that here */
		if ( ! IS_CHAN(fut1->chan[i]) && IS_CHAN(fut0->chan[i])) {

			ok = fut_defchan (fut2, FUT_OUT(FUT_BIT(i)), NULL,
							fut0->chan[i]->gtbl, fut0->chan[i]->otbl);

			continue;			/* no need to evaluate this ochan */
		}

		if (! IS_CHAN(fut1->chan[i])) {
			ok = 0;						/* something wrong */
			goto GetOut;
		}

		/* At this point we know that (fut1->chan[i] != 0).  We also
		 * have determined (from iomask_check above) that fut0->chan[j] != 0.
		 */
		imask2 = 0;						/* determine inputs from fut0 needed for this channel */
		imask1 = fut1->chan[i]->imask;	/* inputs used by this chan */

		for (j = 0; (j < FUT_NICHAN) && ok; j++) {
			if ((imask1 & FUT_BIT(j)) != 0) {		/* this input chan is needed */
				if ( ! IS_CHAN(fut0->chan[j])) {	/* available? */
					ok = 0;							/* composition fails */
					goto GetOut;
				}

				if (fut1->itbl[j] != fut1->chan[i]->itbl[j]) {	/* shared itbl? */
					goto nextOChan;								/* nope, ignore this ochan */
				}

				imask2 |= fut0->chan[j]->imask;
			}				
		}

		evalomask |= FUT_BIT(i);	/* will be evalutating this channel */
		imask |= imask1;			/* build mask of all needed inputs */
			
		/* determine required dimensions from mask */
		for (j = 0; j < FUT_NICHAN; j++) {
			size[j] = (imask2 & (KpInt32_t)FUT_BIT(j)) ? fut0->itbl[j]->size : 1;
		}

		/* create the new grid table
		 * insert it along with fut1's output table into fut2
		 */
		gtbl = fut_new_gtblEx (FUT_IN(FUT_ALLIN), NULL, NULL, size);
		ok = fut_defchan (fut2, FUT_OUT(FUT_BIT(i)), NULL, gtbl, fut1->chan[i]->otbl);
		fut_free_gtbl (gtbl);
		if (!ok) {
			goto GetOut;
		}

		fut1_gtbls[i] = fut1->chan[i]->gtbl;	/* collect gtbls for evaluation fut */

		/* verify the input data for the evaluation of the output channel in fut1 */
		for (j = 0; j < FUT_NICHAN; j++) {
			if ((imask1 & FUT_BIT(j)) != 0) {									/* this channel needed as input */
				if ((fut0->chan[j]->imask & (~fut2->chan[i]->imask)) != 0) {	/* it's inputs must be used by output */
					ok = 0;				/* composition fails */
					goto GetOut;
				}
			}
		}
nextOChan:;
	}

	/* collect the gtbls which are the input data for the chan evaluation.
	 * also pre-compose fut0's otbls with fut1's itbls.
	 */
	for (i = 0; i < FUT_NICHAN; i++) {
		oitbls[i] = NULL;

		if (ok) {
			fut_chan_p theChan = fut0->chan[i];
			
			if ((imask & FUT_BIT(i)) == 0) {
				continue;				/* this output from fut0 not required */
			}

			indat[i] = theChan->gtbl->refTbl;	/* collect gtbls: the input data for the evaluation */

			ok = (indat[i] != NULL);
			
			/* allocate memory for composed i/o tables
			 * these have the same size as the output tables of the channel supplying the input */
			if (ok) {
				fut_itbl_p	theITbl = fut1->itbl[i];
				fut_otbl_p	theOTbl = theChan->otbl;

				oitbls[i] = fut_alloc_itbl ();		/* get an itbl */

				oitbls[i]->size = theITbl->size;
				oitbls[i]->dataClass = KCP_FIXED_RANGE;

				nEntries = MAX(theITbl->refTblEntries, theOTbl->refTblEntries);

				ok = (fut_alloc_imftdat (oitbls[i], nEntries) != NULL);

				if (ok) {	/* make input table for evaluation */
					ok = fut_comp_iotblMF (theITbl, theOTbl, oitbls[i]);
				}
			}
		}
	}

	/* make an evaluation fut with the composed I/O tables, fut1's gtbls, and no otbls */
	evalFut = fut_new (iomask, oitbls, fut1_gtbls, NULL);
	if (( ! ok) ||
		(evalFut == NULL) ||		/* if evaluation fut ok */
		(fut_to_mft (fut2) != 1)) {	/* make sure the futs are in the reference state */
		ok = 0;
		goto GetOut;
	}	
	else {	/* Finally, we are ready to pass fut0's grid tables through fut1 */
		for (i = 0, nOutChans = 0; (i < FUT_NOCHAN) && ok; i++) {
			if ((evalomask & FUT_BIT(i)) != 0) {
				fut_gtbl_p	gtbl;
				
				gtbl = fut2->chan[i]->gtbl;
				nGridPoints = gtbl->tbl_size / sizeof (fut_gtbldat_t);	/* grid points for eval */

				if (evalFut->iomask.in != evalFut->chan[i]->imask) {	/* must evaluate this channel singly */
					evalomask &= ~FUT_BIT(i);							/* remove channel from multiple eval list */
					ok = evaluateFut (evalFut, FUT_BIT(i), KCM_USHORT, nGridPoints,
									(KpGenericPtr_t FAR*) indat, (KpGenericPtr_t FAR*) &(gtbl->refTbl));
				}
				else {
					outdat[nOutChans] = gtbl->refTbl;
					nOutChans++;
				}

			}
		}

		/* eval result is composed fut's gtbls */
		ok = evaluateFut (evalFut, evalomask, KCM_USHORT, nGridPoints,
						 (KpGenericPtr_t FAR*) indat, (KpGenericPtr_t FAR*) outdat);
	}

GetOut:
	/* must always free up the evaluation fut and io tables, even if an error occurred! */
	fut_free (evalFut);
	fut_free_tbls (FUT_NICHAN, (void *)oitbls);

	/* check for errors */
	if ( !ok ) {
		fut_free (fut2);
		fut2 = NULL;
	}

	return (fut2);
}
Esempio n. 12
0
/* fut_copy copies an existing fut.
 */
fut_p
	fut_copy (fut_p fut)
{
fut_p		new_fut;
KpInt32_t	i;
KpHandle_t	h;

	if ( ! IS_FUT(fut)) {
		return (0);
	}

				/* allocate basic fut_structure */
	new_fut = fut_alloc_fut ();
	if ( new_fut == FUT_NULL ) {
		return (FUT_NULL);
	}

				/* save handle before copying over old fut */
	h = new_fut->handle;

				/* copy over all data (including pointers */
	*new_fut = *fut;

				/* now copy back handle */
	new_fut->handle = h;

				/* copy id string */
	new_fut->idstr = 0;
/*	(void) fut_set_idstr (new_fut, fut->idstr); */

				/* copy input tables */
	for ( i=0; i<FUT_NICHAN; i++ ) {
		new_fut->itbl[i] = (IS_SHARED (fut->itbl[i])) ?
							fut_share_itbl (fut->itbl[i]) : fut_copy_itbl (fut->itbl[i]);
		new_fut->itblHandle[i] = getHandleFromPtr((KpGenericPtr_t)new_fut->itbl[i]);
	}

				/* copy output channels */
	for ( i=0; i<FUT_NOCHAN; i++ ) {
		new_fut->chan[i] = fut_copy_chan (fut->chan[i]);
		new_fut->chanHandle[i] = getHandleFromPtr((KpGenericPtr_t)new_fut->chan[i]);
	}

				/* now check that all copies were succesful */
	if ( new_fut->idstr == 0 && fut->idstr != 0 ) {
		goto ErrOut;
	}

	for ( i=0; i<FUT_NICHAN; i++ ) {
		if ( new_fut->itbl[i] == 0 && fut->itbl[i] != 0) {
			goto ErrOut;
		}
	}
	for ( i=0; i<FUT_NOCHAN; i++ ) {
		if ( new_fut->chan[i] == 0 && fut->chan[i] != 0) {
			goto ErrOut;
		}
	}

	for ( i=0; i<FUT_NMCHAN; i++ ) {	/* free extra reference tables */
		if (NULL != fut->mabInRefTblHandles[i])
		{
			new_fut->mabInTblEntries[i] = fut->mabInTblEntries[i];
			new_fut->mabInRefTbl[i] = (mf2_tbldat_p)
									allocBufferPtr (new_fut->mabInTblEntries[i] * sizeof (mf2_tbldat_t));
			KpMemCpy (new_fut->mabInRefTbl[i], fut->mabInRefTbl[i],
													new_fut->mabInTblEntries[i] * sizeof (mf2_tbldat_t));
			new_fut->mabInRefTblHandles[i] = getHandleFromPtr ((KpGenericPtr_t)new_fut->mabInRefTbl[i]);
		}

		if (NULL != fut->mabOutRefTblHandles[i])
		{
			new_fut->mabOutTblEntries[i] = fut->mabOutTblEntries[i];
			new_fut->mabOutRefTbl[i] = (mf2_tbldat_p)
									allocBufferPtr (new_fut->mabOutTblEntries[i] * sizeof (mf2_tbldat_t));
			KpMemCpy (new_fut->mabOutRefTbl[i], fut->mabOutRefTbl[i],
													new_fut->mabOutTblEntries[i] * sizeof (mf2_tbldat_t));
			new_fut->mabOutRefTblHandles[i] = getHandleFromPtr ((KpGenericPtr_t)new_fut->mabOutRefTbl[i]);
		}
	}

	return (new_fut);
	

ErrOut:
	fut_free (new_fut);
	return (FUT_NULL);
}
Esempio n. 13
0
/* gridDimValid determines whether the grid table dimensions are valid
 * for the format specified.  If the dimensions are not valid then the
 * function attempts to create a
 * PT with the correct size grid tables.  If it is successful the
 * PTRefNum of the resized PT is returned in the location pointed to by
 * resizePTRefNumP.  If resizing is not required the value returned in 
 * the location pointed to by resizePTRefNumP is 0.
 *
 * NOTE:  	If this function creates a resized PT, that PT is checked in.  
 *			it is the responsibility of the calling function to check out
 *			that PT.
 */
static PTErr_t
	gridDimValid (	PTType_t	format,
					PTRefNum_t	PTRefNum,
					PTRefNum_p	resizePTRefNumP)
{
KpHandle_t	PTData;
KpInt32_t	inputChans, outputChans, LUTDimensions, dummy = 0;
fut_p	 	fut;
PTErr_t		retVal, error = KCP_SUCCESS;

	/*	Assume no resizing */
	if (NULL != resizePTRefNumP) {
		*resizePTRefNumP = 0;
	}

	/*	Convert the PTRefNum to a fut */
	PTData = getPTData (PTRefNum);
	fut = fut_lock_fut (PTData);
	if (fut == FUT_NULL) {
		return KCP_PTERR_2;
	}

	if ( ! IS_FUT (fut) ) {	/* check for valid fut */
		retVal = KCP_NOT_FUT;
		goto GetOut;
	}

	switch (format ) {

#if !defined KCP_ICC_ONLY
	case PTTYPE_FUTF:
		/* 	may want to check if any of the grid dimensions exceed the max 
			grid dimension, but for now accept any size						*/
		break;
#endif
	case PTTYPE_MAB1:
	case PTTYPE_MAB2:
	case PTTYPE_MBA1:
	case PTTYPE_MBA2:
		/* 	may want to check if any of the grid dimensions exceed the max 
			grid dimension, but for now accept any size						*/
		break;

	case PTTYPE_MFT1:
	case PTTYPE_MFT2:
	case PTTYPE_MFT2_VER_0:
		/*	The grid dimensions must all be the same.  If they are not then
			attempt to build a grid table where all the dimensions are the
			same.															*/
		retVal = (PTErr_t) fut_mfutInfo (fut, &LUTDimensions, &inputChans, &outputChans, format,
										&dummy, &dummy, &dummy);
		if (1 != retVal) {
			if (-2 != retVal) {
				retVal = KCP_INVAL_GRID_DIM;
				goto GetOut;
			}
			else {
				KpInt32_t	i1, newGridDims[FUT_NICHAN];
				fut_p		futresized;

				for (i1 = 0; i1 < FUT_NICHAN; i1++) {		/* define new grid sizes */
					newGridDims[i1] = LUTDimensions;
				}

				futresized = fut_resize (fut, newGridDims);	/* resize the fut */
				if (futresized == NULL) {
					retVal = KCP_NO_MEMORY;
					goto GetOut;
				}

				if (futresized == fut) {					/* should not happen, probably fut_mfutInfo() error */
					retVal = KCP_SYSERR_3;
					goto GetOut;
				}

				if (fut_to_mft (futresized) != 1) {			/* convert to reference tables */
					retVal = KCP_INCON_PT;
					goto GetOut;
				}

				retVal = fut2PT (&futresized, -1, -1, PTTYPE_CALCULATED, resizePTRefNumP);	/* make into PT */
				if (retVal == KCP_SUCCESS) {
					retVal = copyAllAttr (PTRefNum, *resizePTRefNumP);	/* Copy all attributes to new PT */
					if (retVal != KCP_SUCCESS) {
						PTCheckOut (*resizePTRefNumP);
						goto GetOut;
					}
				}
 			}
		}
		break;

	default:
		retVal = KCP_INVAL_PTTYPE;
	}

	retVal = KCP_SUCCESS;

GetOut:
	fut_unlock_fut (fut);
	return retVal;
}
Esempio n. 14
0
/* frees source fut on error */
PTErr_t
	fut2PT (fut_p		*futSrc,
			KpInt32_t	inSpace,
			KpInt32_t	outSpace,
			KpInt32_t	srcFormat,
			PTRefNum_p	PTRefNumNew)
{
PTErr_t		PTErr;
fut_hdr_p	PTHdr = NULL;
KpHandle_t	PTHdrH = NULL, PTDataH = NULL;
KpChar_t	colorSpaceAttr[20];

	*PTRefNumNew = 0;

	if ( ! IS_FUT(*futSrc)) goto ErrOut1;

	PTHdr = allocBufferPtr (sizeof(fut_hdr_t));	/* get buffer for resultant info header */
	if (PTHdr == NULL) {
		goto ErrOut4;
	}

	if (!fut_io_encode (*futSrc, PTHdr)) {	/* make the info header */
		goto ErrOut3;
	}

	PTHdr->srcFormat = srcFormat;

	PTDataH = fut_unlock_fut (*futSrc);
	if (PTDataH == NULL) {
		goto ErrOut2;
	}
	*futSrc = NULL;

	PTHdrH = unlockBufferPtr (PTHdr);		/* unlock the header buffer */
	if (PTHdrH == NULL) {
		goto ErrOut2;
	}
	PTHdr = NULL;

	PTErr = registerPT (PTHdrH, NULL, PTRefNumNew);	/* enter PT into list */
	if (PTErr != KCP_SUCCESS) {
		goto ErrOut0;
	}

	makeActive (*PTRefNumNew, PTDataH);		/* activate the new PT */

	if (inSpace != -1) {	/* set the input color space attribute */
		KpItoa (inSpace, colorSpaceAttr); 
		PTErr = PTSetAttribute (*PTRefNumNew, KCM_IN_SPACE, colorSpaceAttr);
	}

	if (outSpace != -1) {	/* set the output color space attribute */
		KpItoa (outSpace, colorSpaceAttr); 
		PTErr = PTSetAttribute (*PTRefNumNew, KCM_OUT_SPACE, colorSpaceAttr);
	}

	if (PTErr != KCP_SUCCESS) {
		goto ErrOut0;
	}

getOut:
	return PTErr;


ErrOut4:
	PTErr = KCP_NO_CHECKIN_MEM;	
	goto ErrOut0;

ErrOut3:
	PTErr = KCP_ENCODE_PTHDR_ERR;
	goto ErrOut0;

ErrOut2:
	PTErr = KCP_MEM_UNLOCK_ERR;
	goto ErrOut0;

ErrOut1:
	PTErr = KCP_BAD_ARG;

ErrOut0:
	if (PTDataH != NULL) {
		*futSrc = fut_lock_fut (PTDataH);
	}
	if (*futSrc != FUT_NULL) fut_free (*futSrc);

	if (PTHdr != NULL) freeBufferPtr (PTHdr);
	if (PTHdrH != NULL) freeBuffer (PTHdrH);
	if (*PTRefNumNew != 0) PTCheckOut (*PTRefNumNew);

	goto getOut;
}