示例#1
0
PTErr_t
	makeForwardXformMono (	ResponseRecord_p	grayTRC,
							fut_p				theFut)
{
PTErr_t			PTErr = KCP_FAILURE;
KpInt32_t		futReturn, i1;
fut_otbldat_p	otblDat;
double			gamma;
fut_calcData_t	calcData;
KpUInt16_t		rrpData[2] = { 0, RRECORD_DATA_SIZE -1 };
ResponseRecord_t	rrt;
KpUInt16_t		*pCurveData = NULL;

	/* compute new table entries */
	calcData.chan = 0;				/* always uses 1st input chan */

	for (i1 = 0; i1 < FWD_MONO_OCHANS; i1++) {
		if (( ! IS_CHAN(theFut->chan[i1])) ||
			!fut_calc_gtblEx (theFut->chan[i1]->gtbl, fut_grampEx, &calcData) ||
			!fut_calc_otblEx (theFut->chan[i1]->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;
	}

	if (PARA_TYPE_SIG == grayTRC->TagSig)
	{
		pCurveData = (KpUInt16_p) allocBufferPtr (MFV_CURVE_TBL_ENT);	/* get memory for curve data */
		if (NULL == pCurveData) {
			return KCP_NO_MEMORY;
		}
		makeCurveFromPara (grayTRC->ParaFunction, grayTRC->ParaParams, pCurveData, MFV_CURVE_TBL_ENT);
		grayTRC->CurveCount = MFV_CURVE_TBL_ENT;
		grayTRC->CurveData = pCurveData;
	}
	/* setup the output table */
	switch (grayTRC->CurveCount)
	{
	case 0:
		/* setup the responseRecord struct */
		rrt.CurveCount = 2;
		rrt.CurveData = rrpData;

		/* make the output table */
		PTErr = calcOtblLSN (otblDat, &rrt);
		break;

	case 1:
		gamma = (double)grayTRC->CurveData[0] / SCALEDOT8;
		if (gamma <= 0.0) {
			goto ErrOut0;
		}

		/* make the output table */
		PTErr = calcOtblLS1 (otblDat, gamma);
		break;

	default:
		/* make the output table */
		makeMonotonic (grayTRC->CurveCount, grayTRC->CurveData);
		PTErr = calcOtblLSN (otblDat, grayTRC);
	}

GetOut:
	if (NULL != pCurveData) {
		freeBufferPtr (pCurveData);
	}
	return PTErr;


ErrOut0:
	PTErr = KCP_SYSERR_0;
	goto GetOut;
}
示例#2
0
/*-------------------------------------------------------------------
 *  init_xfer -- initialize the transfer tables by transferring coarse
 *			control points from an ICC ResponseRecord
 *			and interpolating the fine tables from them;
 *			returns +1 for success, -1 for failure to
 *			allocate memory for coarse table
 *-------------------------------------------------------------------
 */
PTErr_t
	init_xfer (	xfer_p				xferp,
				ResponseRecord_p	rrp)
{
PTErr_t		PTErr = KCP_SUCCESS;
double		val;			/* input variables */
KpInt32_t	numcoarse;		/* number of input control points */
double_p	coarse[2];		/* storage for control points */
KpInt32_t	i;			/* control-point index */
KpInt32_t	hint;
KpUInt16_t	*pCurveData = NULL;

     /* Verify inputs:  */
	if (xferp == (xfer_p)NULL)	return KCP_SYSERR_0;
	if (rrp == (ResponseRecord_p)NULL)	return KCP_SYSERR_0;
	
	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 < 2) {
		PTErr = KCP_SYSERR_0;
		goto ErrOut;
	}
	if (rrp->CurveData == (KpUInt16_p)NULL) {
		PTErr = KCP_SYSERR_0;
		goto ErrOut;
	}
	   
     /* Allocate space for coarse tables:  */
	numcoarse = rrp->CurveCount - 1;	/* skip zero entry to avoid infinity in logarithm */
	coarse[0] = (double_p)ALLOC (numcoarse, sizeof(double));
	if (coarse[0] == NULL)
	{
		PTErr = KCP_NO_MEMORY;
		goto ErrOut;
	}
	coarse[1] = (double_p)ALLOC (numcoarse, sizeof(double));
	if (coarse[1] == NULL)
	{
	   DALLOC (coarse[0]);	/* release storage */
		PTErr = KCP_NO_MEMORY;
		goto ErrOut;
	}

     /* Build coarse tables from ResponseRecord:  */
	for (i = 0; i < numcoarse; i++)
	{
	   val = (double)(i + 1) / (double)numcoarse;	/* skip zero to avoid infinite log */
	   coarse[0][i] = -log10 (val);
	   val = (double)rrp->CurveData[i + 1] / SCALEDOT16;
	   val = MAX (val, 1.0e-12);			/* clip to avoid infinite log */
	   coarse[1][i] = -log10 (val);
	}

     /* Build fine tables by interpolating in coarse tables:  */
	hint = 1;
	for (i = 0; i < NUMFINE; i++)				/* spaced code values */
	{
	   double	code;

	   code = (double)i * 2.4 / (double)(NUMFINE - 1);	/* equally spaced in [0, 2.4] */
	   xferp->nonlinear[i] = code;
	   xferp->linear[i] = f4l (code, coarse[0], coarse[1], numcoarse, &hint);
	}

     /* Delete coarse tables:  */
	DALLOC (coarse[0]);
	DALLOC (coarse[1]);

ErrOut:
	if (NULL != pCurveData) {
		freeBufferPtr (pCurveData);
	}
	return PTErr;
}
示例#3
0
/*---------------------------------------------------------------------------
 *  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;
}