PTErr_t makeInverseXformMono ( ResponseRecord_p grayTRC, fut_p theFut) { PTErr_t PTErr = KCP_FAILURE; fut_otbldat_p otblDat; ResponseRecord_t rrt; KpInt32_t futReturn; fut_calcData_t data; double gamma; KpUInt16_t rrpData[2] = { 0, RRECORD_DATA_SIZE -1 }; /* compute new grid table entries */ data.chan = 0; if (!fut_calc_gtblEx (theFut->chan[0]->gtbl, fut_grampEx, &data)) { goto ErrOut0; } /* compute new output table entries */ if (!fut_calc_otblEx (theFut->chan[0]->otbl, otblFunc, NULL)) { goto ErrOut0; } /* get address of the first output table */ futReturn = fut_get_otbl (theFut, 0, &otblDat); if ((futReturn != 1) || (otblDat == (fut_otbldat_p)NULL)) { goto ErrOut0; } /* setup the output table */ switch (grayTRC->count) { case 0: /* setup the responseRecord struct */ rrt.count = 2; rrt.data = rrpData; /* make the output table */ PTErr = calcOtblLN (otblDat, &rrt); break; case 1: gamma = (double)grayTRC->data[0] / SCALEDOT8; if (gamma <= 0.0) { goto ErrOut0; } /* make the output table */ PTErr = calcOtblL1 (otblDat, gamma); break; default: /* make the output table */ makeInverseMonotonic (grayTRC->count, grayTRC->data); PTErr = calcOtblLN (otblDat, grayTRC); } GetOut: return (PTErr); ErrOut0: PTErr = KCP_SYSERR_0; goto GetOut; }
/*--------------------------------------------------------------------------- * makeInverseXformFromMatrix -- make a fut of given gridsize from given * matrix data for inverse transform (XYZ -> RGB); return status code *--------------------------------------------------------------------------- */ PTErr_t makeInverseXformFromMatrix (LPMATRIXDATA mdata, KpUInt32_t interpMode, KpInt32_p dim, fut_p theFut) { PTErr_t PTErr = KCP_SUCCESS; ResponseRecord_p rrp; KpInt32_t i; fut_chan_p theChan; fut_gtbl_p theGtbl; fut_otbl_p theOtbl; mf2_tbldat_p gtblDat[3], otblDat, prevOtblDat; KpUInt16_t prevGamma = 0, thisGamma; double fwdgamma, one[3]; double offset[3] = {1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0}; KpUInt16_t *pCurveData = NULL; for (i = 0; i < 3; i++) { if (!IS_CHAN(theChan = theFut->chan[i]) || !IS_GTBL(theGtbl = theChan->gtbl) || ((gtblDat[i] = theGtbl->refTbl) == NULL) /* Get grid tables */ || !IS_OTBL(theOtbl = theChan->otbl) || ((otblDat = theOtbl->refTbl) == NULL)) { /* Get output table */ return KCP_INCON_PT; } if (theOtbl->refTblEntries != FUT_OUTTBL_ENT) return KCP_INCON_PT; /* Get ResponseRecord: */ rrp = mdata->outResponse[i]; if (NULL == rrp) { break; /* must only have output tables */ } if (PARA_TYPE_SIG == rrp->TagSig) { pCurveData = (KpUInt16_p) allocBufferPtr (MFV_CURVE_TBL_ENT*sizeof(KpUInt16_t)); /* get memory for curve data */ if (NULL == pCurveData) { return KCP_NO_MEMORY; } makeCurveFromPara (rrp->ParaFunction, rrp->ParaParams, pCurveData, MFV_CURVE_TBL_ENT); rrp->CurveCount = MFV_CURVE_TBL_ENT; rrp->CurveData = pCurveData; } if ((rrp->CurveCount > 0) && (rrp->CurveData == (KpUInt16_p)NULL)) { PTErr = KCP_INCON_PT; goto ErrOut; } /* Recompute output table: */ switch (rrp->CurveCount) { case 0: /* linear response, with clipping */ calcOtbl0 (otblDat); break; case 1: /* power law */ thisGamma = rrp->CurveData[0]; if (prevGamma == thisGamma) { /* same gamma, just copy table */ memcpy (otblDat, prevOtblDat, sizeof (*otblDat) * FUT_OUTTBL_ENT); } else { prevGamma = thisGamma; prevOtblDat = otblDat; fwdgamma = (double)thisGamma / SCALEDOT8; if (fwdgamma <= 0.0) { PTErr = KCP_INCON_PT; goto ErrOut; } calcOtbl1 (otblDat, fwdgamma); } break; default: /* look-up table of arbitrary length */ makeInverseMonotonic (rrp->CurveCount, rrp->CurveData); if (rrp->CurveCount == theOtbl->refTblEntries) { /* ready-to-use look-up table */ memcpy (otblDat, rrp->CurveData, sizeof (*otblDat) * rrp->CurveCount); } else { PTErr = calcOtblN (otblDat, rrp, interpMode); if (PTErr != KCP_SUCCESS) { PTErr = KCP_INCON_PT; goto ErrOut; } } break; } } /* Compute inverse matrix (XYZ -> RGB): */ one[0] = one[1] = one[2] = 1.0; /* arbitrary vector */ /* replaces matrix with inverse */ if (solvemat (3, mdata->matrix, one) != 0) { PTErr = KCP_INCON_PT; goto ErrOut; } /* Rescale given matrix by factor of 3 for extended range: */ for (i = 0; i < 3; i++) { KpInt32_t j; for (j = 0; j < 3; j++) { mdata->matrix[i][j] /= 3.0; } } /* Replace grid tables: */ calcGtbl3 (gtblDat, dim, mdata->matrix, offset); /* with offset */ ErrOut: if (NULL != pCurveData) { freeBufferPtr (pCurveData); } return PTErr; }