const Integer Integer::modulo(const Integer a) const throw (DivideByZeroException) { return doDivide(Integer(this->toString()), a).remainder; }
void evalTh1gen ( imagePtr_p inp, KpInt32_p inStride, KpUInt32_t dataTypeI, imagePtr_p outp, KpInt32_p outStride, KpUInt32_t dataTypeO, KpInt32_t n, PTTable_p PTTableP) { imagePtr_t inData[FUT_NICHAN], outData[FUT_NOCHAN]; KpInt32_t inStrideL[FUT_NICHAN], outStrideL[FUT_NOCHAN]; KpInt32_t i1, separableFut, numInputs, numOutputs, gDimSize[FUT_NOCHAN], oTblEntries[FUT_NOCHAN]; division_t iIndexFactor[FUT_NICHAN], gIndexFactor[FUT_NICHAN], oIndexFactor[FUT_NOCHAN]; KpInt32_t oDataShift, oDataRound, oDataFactor, dataMax, oDataBits; fut_p fut; fut_itbl_p iTbl[FUT_NICHAN], theITbl; fut_chan_p chan[FUT_NOCHAN], theChan; mf2_tbldat_p gTbl[FUT_NOCHAN], oTbl[FUT_NOCHAN]; KpInt32_p BoseSort[FUT_NICHAN] = {BoseSort1, BoseSort2, BoseSort3, BoseSort4, BoseSort5, BoseSort6, BoseSort7, BoseSort8}; mf2_tbldat_t identityTable[2] = {0, MF2_TBL_MAXVAL}; fut = PTTableP->dataP; separableFut = fut_is_separable (fut); /* check for separable (linearization) fut */ /* set up input table stuff */ switch (dataTypeI) { case KCM_UBYTE: dataMax = (1 << 8) -1; break; case KCM_USHORT_12: dataMax = (1 << 12) -1; break; case KCM_USHORT: dataMax = (1 << 16) -1; break; default: dataMax = 1; } for (i1 = 0, numInputs = 0; i1 < FUT_NICHAN; i1++) { if (inp[i1].p8 != NULL) { inData[numInputs].p8 = inp[i1].p8; /* copy addresses - do not change supplied lists! */ inStrideL[numInputs] = inStride[i1]; theITbl = fut->itbl[i1]; if ( ! IS_ITBL(theITbl)) { return; } iTbl[numInputs] = theITbl; /* collect the input tables */ /* set up interpolation into input table */ doDivide (theITbl->refTblEntries -1, dataMax, iIndexFactor[numInputs]); /* set up interpolation into input table */ /* set up interpolation into grid table */ gDimSize[i1] = theITbl->size; /* save in case of separable fut */ doDivide (gDimSize[i1] -1, MF2_TBL_MAXVAL, gIndexFactor[numInputs]); /* set up interpolation into input table */ numInputs++; } } /* set up grid and output table stuff */ for (i1 = 0, numOutputs = 0; i1 < FUT_NOCHAN; i1++) { if (outp[i1].p8 != NULL) { fut_otbl_p theOTbl; outData[numOutputs].p8 = outp[i1].p8; /* copy addresses - do not update supplied lists! */ outStrideL[numOutputs] = outStride[i1]; theChan = fut->chan[i1]; if ( ! IS_CHAN(theChan)) { return; } chan[numOutputs] = theChan; gTbl[numOutputs] = theChan->gtbl->refTbl; /* get the grid */ theOTbl = theChan->otbl; /* set up interpolation into output table */ if ( ! IS_OTBL(theOTbl) || ((oTbl[numOutputs] = theOTbl->refTbl) == NULL)) { oTbl[numOutputs] = identityTable; oTblEntries[numOutputs] = 2; } else { oTblEntries[numOutputs] = theOTbl->refTblEntries; } doDivide (oTblEntries[numOutputs] -1, MF2_TBL_MAXVAL, oIndexFactor[numOutputs]); /* set up interpolation into input table */ numOutputs++; } } /* set up output data scaling */ switch (dataTypeO) { case KCM_UBYTE: oDataBits = 8; break; case KCM_USHORT_12: oDataBits = 12; break; case KCM_USHORT: oDataBits = 16; break; default: dataMax = 1; } dataMax = (1 << oDataBits) -1; oDataShift = 32 -1 - oDataBits; oDataFactor = (dataMax << oDataShift) / MF2_TBL_MAXVAL; oDataRound = (1 << (oDataShift -1)) -1; /* all set up; evaluate each pixel */ for (i1 = 0; i1 < n; i1++) { KpInt32_t cell, i2, index, dimSize, numCompares, hVert[FUT_NICHAN]; KpInt32_t sPosition, iTableData[FUT_NICHAN], hFrac[FUT_NICHAN]; KpInt32_p BoseSortP; for (i2 = 0, cell = 0; i2 < numInputs; i2++) { KpInt32_t srcData, interpData; if (dataTypeI == KCM_UBYTE) { srcData = (KpInt32_t) (*inData[i2].p8); /* get 8 bit input data */ } else { srcData = (KpInt32_t) (*inData[i2].p16); /* get 12/16 bit input data */ } inData[i2].p8 += inStrideL[i2]; /* pass source image data through the input table */ theITbl = iTbl[i2]; interpData = interp1DTable (theITbl->refTbl, theITbl->refTblEntries, srcData, iIndexFactor[i2]); iTableData[i2] = interpData; /* save in case of separable fut */ doMultiply (interpData, gIndexFactor[i2], sPosition); /* calculate the input table position */ index = sPosition >> EVAL_FRACBITS; dimSize = theITbl->size; /* size of this dimension */ if (index < dimSize -1) { hFrac[i2] = sPosition & ((1 << EVAL_FRACBITS) -1); /* get grid interpolant */ } else { hFrac[i2] = (1 << EVAL_FRACBITS) -1; index--; } hVert[i2] = dimSize; /* save for offset calcs */ cell *= dimSize; /* build cell index */ cell += index; /* add in this index */ } /* build offsets for each dimension */ index = 2; for (i2 = numInputs-1; i2 >= 0; i2--) { dimSize = hVert[i2]; hVert[i2] = index; index *= dimSize; } /* find the hyperhedron in which the interpolation point is located */ BoseSortP = BoseSort[numInputs -1]; numCompares = *BoseSortP++; /* first element is # of compares */ for (i2 = 0; i2 < numCompares; i2++) { KpInt32_t tmpI, index1, index2; index1 = *BoseSortP++; index2 = *BoseSortP++; /* sort into largest to smallest based upon interpolants */ tmpI = hFrac[index1]; if (tmpI < hFrac[index2]) { hFrac[index1] = hFrac[index2]; /* swap interpolants */ hFrac[index2] = tmpI; tmpI = hVert[index1]; /* swap vertices */ hVert[index1] = hVert[index2]; hVert[index2] = tmpI; } } /* evaluate each output channel */ for (i2 = 0; i2 < numOutputs; i2++) { KpInt32_t i3, tResult, oTableData, previousVertex, thisVertex; KpUInt8_p vertexP; if (separableFut == 1) { tResult = interp1DTable (gTbl[i2], gDimSize[i2], iTableData[i2], gIndexFactor[i2]); } else { /* hyperhedral interpolation */ vertexP = (KpUInt8_p)(gTbl[i2] + cell); previousVertex = (KpInt32_t) *(mf2_tbldat_p)(vertexP); tResult = previousVertex << (EVAL_FRACBITS - EVAL_EXTENDED_BITS); for (i3 = 0; i3 < numInputs; i3++) { vertexP += hVert[i3]; thisVertex = (KpInt32_t) *(mf2_tbldat_p)(vertexP); interpolateDelta (previousVertex, thisVertex, hFrac[i3], previousVertex) tResult += previousVertex; previousVertex = thisVertex; } tResult += ROUND_VALUE(EVAL_FRACBITS - EVAL_EXTENDED_BITS); KCP_SHIFT_RIGHT(tResult, tResult, EVAL_FRACBITS - EVAL_EXTENDED_BITS); } /* output table lookup */ oTableData = interp1DTable (oTbl[i2], oTblEntries[i2], tResult, oIndexFactor[i2]); oTableData *= oDataFactor; /* convert to dest size */ oTableData += oDataRound; /* round */ oTableData >>= oDataShift; /* remove fractional bits */ if (dataTypeO == KCM_UBYTE) { *outData[i2].p8 = (KpUInt8_t) oTableData; } else { *outData[i2].p16 = (KpUInt16_t) oTableData; } outData[i2].p8 += outStrideL[i2]; /* next output data location */ } } }
const Integer Integer::divide(const Integer a) const throw (DivideByZeroException) { return doDivide(Integer(this->toString()), a).result; }