Exemple #1
0
/* fut_size_gtbl returns the size in bytes of a grid table */
static KpInt32_t
	fut_size_gtbl (	fut_gtbl_p	gtbl)
{
	if (( ! IS_GTBL (gtbl)) || (gtbl->tbl == NULL)) return (0);

	return (((KpInt32_t)sizeof (KpInt32_t)*5) + ((KpInt32_t)sizeof (KpInt16_t)*FUT_NCHAN) + gtbl->tbl_size);
}
Exemple #2
0
/* fut_free_gtbl_p
		This function is passed a fut_gtbl_t pointer
		and handle.	If the ref count is zero, the table and
		the fut_gtbl_t is freed.  Otherwise the ref count is 
		decremented and the lock state of the fut_gtbl_t
		is returned to it's state on entry.
*/
static void
	fut_free_gtbl_p (	fut_gtbl_p	gtblP,
						KpHandle_t	gtblHdl)
{
fut_gtbl_p	gtbl = gtblP;

	if (gtblHdl == NULL) {
		return;
	}

	if (gtbl == NULL) {				/* gtbl is unlocked on entry */
		gtbl = lockBuffer(gtblHdl);
	}
	
	if (IS_GTBL(gtbl)) {
		if (gtbl->ref == 0) {
			fut_free_gtbl(gtbl);	/* last reference being freed */
		}
		else {
			if (gtbl->ref > 0) {	/* still other references, leave in original lock state */
				gtbl->ref--;
				if (gtblP == NULL) {
					unlockBuffer(gtblHdl);
				}
			}
		}
	}
}
Exemple #3
0
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);
}
Exemple #4
0
/* fut_copy_gtbl makes an exact copy of an existing fut_gtbl_t
 */
fut_gtbl_p
	fut_copy_gtbl (fut_gtbl_p gtbl)
{
fut_gtbl_p		new_gtbl;
KpInt32_t		gsize;
KpHandle_t		h;

				/* check for valid gtbl */
	if ( ! IS_GTBL(gtbl) ) {
		return (FUT_NULL_GTBL);
	}

	new_gtbl = fut_alloc_gtbl ();	/* allocate the new gtbl structure */
	if ( new_gtbl == FUT_NULL_GTBL ) {
		DIAG("fut_copy_gtbl: can't alloc grid table struct.\n", 0);
		return (FUT_NULL_GTBL);
	}

	h = new_gtbl->handle;	/* save handle before copying over old gtbl */

	*new_gtbl = *gtbl;		/* copy entire struct except reference count */

	new_gtbl->handle = h;
	new_gtbl->ref = 0;		/* first reference */

	if (gtbl->tbl != NULL) {	/* copy fixed gtbl data */
		gsize = gtbl->tbl_size / (KpInt32_t)sizeof(fut_gtbldat_t);
		new_gtbl->tbl = fut_alloc_gtbldat (new_gtbl);
		if ( new_gtbl->tbl == NULL ) {
			DIAG("fut_copy_gtbl: can't alloc grid table array.\n", 0);
			goto ErrOut;
		}
		new_gtbl->tblHandle = getHandleFromPtr((KpGenericPtr_t)new_gtbl->tbl);

		/* copy the table entries */
		KpMemCpy (new_gtbl->tbl, gtbl->tbl, gtbl->tbl_size);
	}

	if (gtbl->refTbl != NULL) {	/* copy reference gtbl data */
		new_gtbl->refTbl = fut_alloc_gmftdat (new_gtbl);
		if (new_gtbl->refTbl == NULL ) {
			DIAG("fut_copy_gtbl: can't alloc ref grid table array.\n", 0);
			goto ErrOut;
		}

		/* copy the table entries */
		KpMemCpy (new_gtbl->refTbl, gtbl->refTbl, gtbl->tbl_size);
	}

	return (new_gtbl);
	

ErrOut:
	fut_free_gtbl (new_gtbl);
	return (FUT_NULL_GTBL);
}
Exemple #5
0
void
	fut_free_gmftdat (	fut_gtbl_p		gtbl,
						fut_freeMode_t	mode)
{
	if (IS_GTBL(gtbl)) {
		if ((mode == freeTable) ||
			((mode == freeData) && (gtbl->tbl != NULL))) {

			freeBuffer (gtbl->refTblHandle);
			gtbl->refTbl = NULL;
			gtbl->refTblHandle = NULL;
		}
	}
}
Exemple #6
0
void
	fut_free_gtbl (fut_gtbl_p gtbl)
{
	if ( ! IS_GTBL(gtbl)) {		/* defined? */
		return;
	}

	if (gtbl->ref != 0) {					/* last reference? */
		gtbl->ref--;
	}
	else {
		fut_free_gmftdat (gtbl, freeTable);	/* free the data */
		fut_free_gtbldat (gtbl, freeTable);
		gtbl->magic = 0;
		freeBufferPtr ((KpGenericPtr_t)gtbl);
	}
}
Exemple #7
0
/* 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);
}
Exemple #8
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;
}