KpInt32_t fut_calc_gtblEx ( fut_gtbl_p gtbl, fut_gfunc_t gfun, fut_calcData_p data) { KpInt32_t index, n[FUT_NICHAN], i[FUT_NICHAN], mftData; double norm[FUT_NICHAN], cList[FUT_NICHAN], val, mftMaxData = MF2_TBL_MAXVAL; mf2_tbldat_p grid; if ( ! IS_GTBL(gtbl) ) { return (0); } if (gfun != NULL) { /* set up grid size in each dimension */ for (index = 0; index < FUT_NICHAN; index++) { n[index] = gtbl->size[index]; if (n[index] == 1) { norm[index] = 0.0; } else { norm[index] = 1.0 / (double) (n[index] -1); } } gtbl->id = fut_unique_id(); /* new table data, new id */ /* construct function of 1 to 8 input variables */ grid = gtbl->refTbl; GCLOOP(0) GCLOOP(1) GCLOOP(2) GCLOOP(3) GCLOOP(4) GCLOOP(5) GCLOOP(6) GCLOOP(7) val = (*gfun)(cList, data); MFT_QUANT(val, mftData) *grid++ = (mf2_tbldat_t)mftData; GCLEND GCLEND GCLEND GCLEND GCLEND GCLEND GCLEND GCLEND } return (1); }
/* fut_comp_itbl_ilut composes an input table with an 8-bit or 12-bit, * 256 entry look-up table. It returns a newly allocated table or NULL * if an error occurred. This is called by fut_comp_ilut() which in turn * is called by fut_comp_itbl(). * * Although we are recomputing the input table here, we do so by simply * rearranging an existing one (in case of an 8-bit lut) or by linearly * interpolating within an existing one (in the case of a 12-bit lut). * Therefore, there is no need to do any clipping to avoid referencing * off-grid values - provided, of course, that the existing input table * has been clipped (see note in fut_calc_itbl()). */ static fut_itbl_p fut_comp_itbl_ilut (fut_itbl_p itbl, KpChar_p lut, KpInt32_t is_12bits) { fut_itbl_p new_itbl; fut_itbldat_p idat; fut_itbldat_p new_idat; /* create a new input table */ new_itbl = fut_new_itblEx ((KpInt32_t)itbl->size, FUT_NULL_IFUNEX, NULL); if ( new_itbl == FUT_NULL_ITBL ) return (FUT_NULL_ITBL); /* assign a unique id since we are about to recompute */ new_itbl->id = fut_unique_id (); /* reorder the input table entries using the lut */ idat = itbl->tbl; new_idat = new_itbl->tbl; if ( is_12bits ) { /* since input tables are only 8 bits in, we must use the * lowest 4 bits of the 12 bit data to interpolate between the * input table entries specified by the highest 8 bits. */ KpInt16_p lut_p = (KpInt16_t FAR*) lut; KpInt16_p lut_end = lut_p + FUT_INPTBL_ENT; while ( lut_p < lut_end ) { *new_idat++ = fut_itbl_interp (idat,*lut_p); lut_p++; } } else { /* The lut is 8 bits so we simply do a table look up in the * input table to find the new entries. */ KpUInt8_p lut_p = (KpUInt8_t FAR*) lut; KpUInt8_p lut_end = lut_p + FUT_INPTBL_ENT; while ( lut_p < lut_end ) { *new_idat++ = idat[*lut_p++]; } } /* don't forget to set the very last (the 257th) input table entry */ *new_idat = *(new_idat-1); return (new_itbl); }
/* fut_calc_otbl computes the values of an output table from a user defined * function. Ofun must be a pointer to a function accepting accepting a * double and returning a double, both in the range (0.0,1.0). (NULL is a * legal value - it just returns, leaving the table uninitialized). * fut_calc_otbl returns 0 (FALSE) if an error occurs (ofun returned * value out of range) and 1 (TRUE) otherwise. */ KpInt32_t fut_calc_otblEx ( fut_otbl_p otbl, fut_ofunc_t ofun, fut_calcData_p data) { KpInt32_t i, mftData; mf2_tbldat_p theOtbl; double val, indexNorm, indexInc, mftMaxData = MF2_TBL_MAXVAL; fData_t fDataL; fut_calcData_p fDataP; if ( ! IS_OTBL(otbl) ) { return (0); } if (ofun != NULL) { otbl->id = fut_unique_id(); if (data == NULL) { fDataP = &fDataL.std; fDataL.scale = 1.0; } else { fDataP = data; } theOtbl = otbl->refTbl; indexInc = 1.0 / (double) (otbl->refTblEntries -1); for (i = 0, indexNorm = 0.0; i < otbl->refTblEntries; i++, indexNorm += indexInc) { val = (*ofun) (indexNorm, fDataP); MFT_QUANT(val, mftData) theOtbl[i] = (mf2_tbldat_t)mftData; } } return (1); }
/* fut_calc_itbl computes the values of an input table from a user * defined function. Ifun must be a pointer to a function accepting a * double and returning a double, both in the range (0.0,1.0). (NULL is * a legal value - it returns leaving the table uninitialized) * fut_calc_itbl returns 0 (FALSE) if an error occurs (ifun returned * value out of range) and 1 (TRUE) otherwise. * */ KpInt32_t fut_calc_itblEx ( fut_itbl_p itbl, fut_ifunc_t ifun, fut_calcData_p data) { mf2_tbldat_p theItbl; KpInt32_t i, mftData; double val, indexNorm, indexInc, mftMaxData = MF2_TBL_MAXVAL; fData_t fDataL; fut_calcData_p fDataP; if ( ! IS_ITBL(itbl) ) { return (0); } if (ifun != NULL) { itbl->id = fut_unique_id (); /* new table values, get new unique id */ if (data == NULL) { fDataP = &fDataL.std; fDataL.scale = 1.0; } else { fDataP = data; } theItbl = itbl->refTbl; indexInc = 1.0 / (double) (itbl->refTblEntries -1); for (i = 0, indexNorm = 0.0; i < itbl->refTblEntries; i++, indexNorm += indexInc) { val = (*ifun) (indexNorm, fDataP); MFT_QUANT(val, mftData) theItbl[i] = (mf2_tbldat_t)mftData; } } return (1); }
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); }