/* fut_comp_chan_ilut composes (in place) the input tables of a * fut output channel with the look-up tables specified in the * list, luts. The original and new input tables from the * parent fut must be passed in order to preserve the sharing * of input tables. */ static KpInt32_t fut_comp_chan_ilut (fut_chan_p chan, KpChar_p FAR* luts, fut_itbl_p FAR* orig_itbls, fut_itbl_p FAR* new_itbls, KpInt32_t is_12bits) { KpInt32_t i; fut_itbl_p new_itbl; if ( ! IS_CHAN(chan) ) { return (0); } /* check each itbl to see if must be computed or shared */ for ( i=0; i<FUT_NICHAN; i++ ) { if ((luts[i] == NULL) || (chan->itbl[i] == NULL)) continue; if ((orig_itbls != NULL) && (chan->itbl[i] == orig_itbls[i])) { new_itbl = fut_share_itbl(new_itbls[i]); } else { new_itbl = fut_comp_itbl_ilut (chan->itbl[i], luts[i], is_12bits); } if (new_itbl == FUT_NULL_ITBL) { return (0); } /* replace with the new composed or shared itbl */ fut_free_itbl (chan->itbl[i]); chan->itbl[i] = new_itbl; } return (1); }
/* 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); }
/* 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); }
/* 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); }
/* 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); }
/* fut_copy_chan makes a copy of an existing fut_chan_t structure. */ fut_chan_p fut_copy_chan (fut_chan_p chan) { fut_chan_p new_chan; KpInt32_t i; KpHandle_t h; if ( ! IS_CHAN(chan) ) { return (FUT_NULL_CHAN); } new_chan = fut_alloc_chan (); if ( new_chan == FUT_NULL_CHAN ) { return (FUT_NULL_CHAN); } /* save handle before copying over old fut */ h = new_chan->handle; /* copy over to new structure */ *new_chan = *chan; /* move handle back to new structure */ new_chan->handle = h; /* copy itbls * if an itbl is shared, share it with the itbl in the new fut */ for ( i=0; i<FUT_NICHAN; i++ ) { new_chan->itbl[i] = (IS_SHARED (chan->itbl[i])) ? fut_share_itbl (chan->itbl[i]) : fut_copy_itbl (chan->itbl[i]); new_chan->itblHandle[i] = getHandleFromPtr((KpGenericPtr_t)new_chan->itbl[i]); } /* copy gtbl */ new_chan->gtbl = fut_copy_gtbl (chan->gtbl); new_chan->gtblHandle = getHandleFromPtr((KpGenericPtr_t)new_chan->gtbl); /* copy otbl */ new_chan->otbl = (IS_SHARED(chan->otbl)) ? fut_share_otbl (chan->otbl) : fut_copy_otbl (chan->otbl); new_chan->otblHandle = getHandleFromPtr((KpGenericPtr_t)new_chan->otbl); /* check for successful copies */ for ( i=0; i<FUT_NICHAN; i++ ) { if ( new_chan->itbl[i] == 0 && chan->itbl[i] != 0 ) { goto ErrOut; } } if ( (new_chan->otbl == 0 && chan->otbl != 0) || (new_chan->gtbl == 0 && chan->gtbl != 0) ) { goto ErrOut; } return (new_chan); ErrOut: fut_free_chan (new_chan); return (FUT_NULL_CHAN); }