예제 #1
0
/*------------------------------------------------------------------------------
 *  PTGetRelToAbsPT -- generate a PT which
 					converts from ICC relative colorimetry to ICC absolute colorimetry
 					
 	(absolute color) = ((media white point) / (profile white point)) * (relative color)

 	so
 	(source absolute color) = ((source media white point) / (source profile white point)) * (source relative color)
 	and
 	(dest absolute color) = ((dest media white point) / (dest profile white point)) * (dest relative color)

	equating source and dest absolute colors
	 	(dest relative color) = ((source media white point) / (dest media white point))
	 						  * ((dest profile white point) / (source profile white point))
	 						  * (source relative color)

 *------------------------------------------------------------------------------
 */
PTErr_t
	 PTGetRelToAbsPT(	KpUInt32_t		RelToAbsMode,
						PTRelToAbs_p	PTRelToAbs,
						PTRefNum_p		PTRefNumPtr)
{
PTErr_t				PTErr;
KpInt32_t			status;
FloatXYZColor_t		sMWP, dMWP, sPWP, dPWP;
Fixed_t				matrix[MF_MATRIX_DIM * MF_MATRIX_DIM];
fut_p				theFutFromMatrix = NULL;

		/* just one mode now.  allows for future expansion of the function */
	if (RelToAbsMode != 0)		return KCP_NOT_IMPLEMENTED;
	if (PTRefNumPtr == NULL)	return KCP_BAD_ARG;

	*PTRefNumPtr = 0;

	sMWP.X = PTRelToAbs->srcMediaWhitePoint.X / (KpFloat32_t)KpF15d16Scale;	/* convert fixed point XYZ to floating point */
	sMWP.Y = PTRelToAbs->srcMediaWhitePoint.Y / (KpFloat32_t)KpF15d16Scale;
	sMWP.Z = PTRelToAbs->srcMediaWhitePoint.Z / (KpFloat32_t)KpF15d16Scale;
	dMWP.X = PTRelToAbs->dstMediaWhitePoint.X / (KpFloat32_t)KpF15d16Scale;
	dMWP.Y = PTRelToAbs->dstMediaWhitePoint.Y / (KpFloat32_t)KpF15d16Scale;
	dMWP.Z = PTRelToAbs->dstMediaWhitePoint.Z / (KpFloat32_t)KpF15d16Scale;
	sPWP.X = PTRelToAbs->srcProfileWhitePoint.X / (KpFloat32_t)KpF15d16Scale;
	sPWP.Y = PTRelToAbs->srcProfileWhitePoint.Y / (KpFloat32_t)KpF15d16Scale;
	sPWP.Z = PTRelToAbs->srcProfileWhitePoint.Z / (KpFloat32_t)KpF15d16Scale;
	dPWP.X = PTRelToAbs->dstProfileWhitePoint.X / (KpFloat32_t)KpF15d16Scale;
	dPWP.Y = PTRelToAbs->dstProfileWhitePoint.Y / (KpFloat32_t)KpF15d16Scale;
	dPWP.Z = PTRelToAbs->dstProfileWhitePoint.Z / (KpFloat32_t)KpF15d16Scale;
		
	matrix[0] = (Fixed_t)(((sMWP.X * dPWP.X) / (dMWP.X * sPWP.X) * KpF15d16Scale) + 0.5);	/* fill in the matrix */
	matrix[1] = 0;
	matrix[2] = 0;
	matrix[3] = 0;
	matrix[4] = (Fixed_t)(((sMWP.Y * dPWP.Y) / (dMWP.Y * sPWP.Y) * KpF15d16Scale) + 0.5);
	matrix[5] = 0;
	matrix[6] = 0;
	matrix[7] = 0;
	matrix[8] = (Fixed_t)(((sMWP.Z * dPWP.Z) / (dMWP.Z * sPWP.Z) * KpF15d16Scale) + 0.5);

	status = makeOutputMatrixXform ((Fixed_p)&matrix, PTRelToAbs->gridSize, &theFutFromMatrix);
	if (status != 1) {
		goto ErrOut1;
	}

	if (fut_to_mft (theFutFromMatrix) != 1) {		/* convert to reference tables */
		goto ErrOut3;
	}

	PTErr = fut2PT (&theFutFromMatrix, KCM_CIE_XYZ, KCM_CIE_XYZ, PTTYPE_CALCULATED, PTRefNumPtr);	/* make into PT */
	if (PTErr != KCP_SUCCESS) {
		goto ErrOut0;
	}

GetOut:
	return (PTErr);


ErrOut3:
	PTErr = KCP_INCON_PT;
	goto ErrOut0;

ErrOut1:
	PTErr = KCP_BAD_ARG;

ErrOut0:
	if (theFutFromMatrix != NULL) fut_free (theFutFromMatrix);
	if (*PTRefNumPtr != 0) PTCheckOut (*PTRefNumPtr);
	goto GetOut;
}
예제 #2
0
/* TpReadData reads a fut from a memory block and returns a handle to a newly allocated fut
 */
PTErr_t
	TpReadData(	KpFd_p			fd,
				PTType_t		format,
				PTRefNum_t		PTRefNum,
				KpHandle_t		PTHdr,
				KpHandle_t FAR*	PTData)
{
PTErr_t			errnum;
fut_p			fut = NULL, theFutFromMatrix = NULL, newFut = NULL, lab2xyzFut = NULL, finalFut = NULL;
fut_hdr_p		futHdr;
Fixed_t			matrix[MF_MATRIX_DIM * MF_MATRIX_DIM + MF_MATRIX_DIM];
KpInt32_t		ret, iomask;
KpChar_t		ENUM_String[20];
KpInt32_t		inCS, i, i1;
ResponseRecord_t	inRedTRC, inGreenTRC, inBlueTRC;
ResponseRecord_t	outRedTRC, outGreenTRC, outBlueTRC;
PTRefNum_t		matrixPTRefNum;
PTDataClass_t 	iClass, oClass;

	futHdr = (fut_hdr_p) lockBuffer (PTHdr);	/* get buffer pointer */
	if (futHdr == NULL) {
		errnum = KCP_MEM_LOCK_ERR;
		goto GetOut;
	}

	futHdr->profileType = getIntAttrDef (PTRefNum, KCM_ICC_PROFILE_TYPE);
	futHdr->spaceIn = getIntAttrDef (PTRefNum, KCM_SPACE_IN);
	futHdr->spaceOut = getIntAttrDef (PTRefNum, KCM_SPACE_OUT);
	futHdr->iDataClass = getDataClass (futHdr->spaceIn);
	futHdr->oDataClass = getDataClass (futHdr->spaceOut);

	switch (format) {
	case FUT_CIGAM: /* fut with bytes reversed */
	case FUT_MAGIC: /* fut with bytes in correct order */
		if ((fut = fut_alloc_fut ()) == NULL) {	/* allocate a new fut structure */
			errnum = KCP_NO_ACTIVATE_MEM;
		}
		else {
			if (fut_read_tbls (fd, fut, futHdr) != 1) {	/* read fut tables */
				errnum = KCP_PT_DATA_READ_ERR;
			}
			else {
				if (fut_io_decode (fut, futHdr) == 0) {
					errnum = KCP_PTERR_0;
				}
				else {
					errnum = KCP_SUCCESS;
				}
			}
		}
		break;

	case PTTYPE_MFT1:
	case PTTYPE_MFT2:
		fut = fut_readMFutTbls (fd, futHdr, matrix);	/* read matrix fut tables */
		if (fut == NULL) {
			errnum = KCP_NO_ACTIVATE_MEM;
		}
		else {
			inCS = getIntAttrDef (PTRefNum, KCM_SPACE_IN);

			if ((inCS == KCM_CIE_XYZ) && (isIdentityMatrix (matrix, MF_MATRIX_DIM) != 1)) {
				ret = makeOutputMatrixXform ((Fixed_p)&matrix, 8, &theFutFromMatrix);
				if (ret != 1) {
					errnum = KCP_INCON_PT;
					goto GetOut;
				}
				else {
					iomask = FUT_PASS(FUT_XYZ);		/* get the Lab to XYZ fut */
					lab2xyzFut = get_lab2xyz (KCP_GRID_DIM_SIXTEEN);

					newFut = fut_comp (theFutFromMatrix, lab2xyzFut, iomask);			

					if (newFut != NULL) {
						finalFut = fut_comp (fut, newFut, iomask);
					}			

					fut_free (theFutFromMatrix);	/* free intermediate futs */
					fut_free (lab2xyzFut);
					fut_free (fut);
					fut_free (newFut);

					fut = finalFut;

					/* set the input color space attribute to Lab */
					KpItoa (KCM_CIE_LAB, ENUM_String);
					errnum = PTSetAttribute (PTRefNum, KCM_SPACE_IN, ENUM_String);
					if (errnum != KCP_SUCCESS) {
						goto GetOut;
					}

					/* set the input composition attribute to Lab */
					errnum = PTSetAttribute (PTRefNum, KCM_IN_CHAIN_CLASS_2, "6");
					if (errnum != KCP_SUCCESS) {
						goto GetOut;
					}
				}
			}

			if ((fut == NULL) || !fut_io_encode (fut, futHdr)) {	/* make the info header */
				errnum = KCP_INCON_PT;
				goto GetOut;
			}

			errnum = KCP_SUCCESS;
		}
		break;

	case PTTYPE_MA2B:
	case PTTYPE_MB2A:
	
		matrix[0] = matrix[4] = matrix[8] = KpF15d16FromDouble(1.0);
		matrix[1] = matrix[2] = matrix[3] = 
		matrix[5] = matrix[6] = matrix[7] = 
		matrix[9] = matrix[10] = matrix[11] = KpF15d16FromDouble(0.0);
		
		fut = fut_readMabFutTbls (fd, futHdr, matrix);	/* read matrix fut tables */
		if (fut == NULL) {
			errnum = KCP_NO_ACTIVATE_MEM;
		}
		else {
			if (fut->lutConfig & HAS_MATRIX_DATA) {
				i = MF_MATRIX_DIM * MF_MATRIX_DIM + MF_MATRIX_DIM;
				for (i1 = 0; i1 < i; i1++)
				{
					fut->matrix[i1] = matrix[i1];
				}
				switch (fut->lutConfig) {
				case MAB_M_MATRIX_B_COMBO:
				case MBA_B_MATRIX_M_COMBO:
					inRedTRC.CurveCount = fut->mabInTblEntries[0];
					inGreenTRC.CurveCount = fut->mabInTblEntries[1];
					inBlueTRC.CurveCount = fut->mabInTblEntries[2];
					inRedTRC.CurveData = fut->mabInRefTbl[0];
					inGreenTRC.CurveData = fut->mabInRefTbl[1];
					inBlueTRC.CurveData = fut->mabInRefTbl[2];
					outRedTRC.CurveCount = fut->mabOutTblEntries[0];
					outGreenTRC.CurveCount = fut->mabOutTblEntries[1];
					outBlueTRC.CurveCount = fut->mabOutTblEntries[2];
					outRedTRC.CurveData = fut->mabOutRefTbl[0];
					outGreenTRC.CurveData = fut->mabOutRefTbl[1];
					outBlueTRC.CurveData = fut->mabOutRefTbl[2];
					iClass = getDataClass(futHdr->spaceIn);
					oClass = getDataClass(futHdr->spaceOut);
					ret = makeFutFromMatrix ((Fixed_p)&matrix, &inRedTRC, &inGreenTRC, &inBlueTRC, 
												&outRedTRC, &outGreenTRC, &outBlueTRC, MATRIX_GRID_SIZE, iClass, oClass, 
												(fut_p *)&theFutFromMatrix);
					break;

				case MBA_B_MATRIX_M_CLUT_A_COMBO:
					inRedTRC.CurveCount = fut->mabInTblEntries[0];
					inGreenTRC.CurveCount = fut->mabInTblEntries[1];
					inBlueTRC.CurveCount = fut->mabInTblEntries[2];
					inRedTRC.CurveData = fut->mabInRefTbl[0];
					inGreenTRC.CurveData = fut->mabInRefTbl[1];
					inBlueTRC.CurveData = fut->mabInRefTbl[2];
					iClass = getDataClass(futHdr->spaceIn);
					oClass = KCP_UNKNOWN;
					ret = makeFutFromMatrix ((Fixed_p)&matrix, &inRedTRC, &inGreenTRC, &inBlueTRC, 
												NULL, NULL, NULL, MATRIX_GRID_SIZE, iClass, oClass, (fut_p *)&theFutFromMatrix);
					break;

				case MAB_A_CLUT_M_MATRIX_B_COMBO:
					outRedTRC.CurveCount = fut->mabOutTblEntries[0];
					outGreenTRC.CurveCount = fut->mabOutTblEntries[1];
					outBlueTRC.CurveCount = fut->mabOutTblEntries[2];
					outRedTRC.CurveData = fut->mabOutRefTbl[0];
					outGreenTRC.CurveData = fut->mabOutRefTbl[1];
					outBlueTRC.CurveData = fut->mabOutRefTbl[2];
					iClass = KCP_UNKNOWN;
					oClass = getDataClass(futHdr->spaceOut);
					ret = makeFutFromMatrix ((Fixed_p)&matrix, NULL, NULL, NULL, &outRedTRC, &outGreenTRC,
												&outBlueTRC, MATRIX_GRID_SIZE, iClass, oClass, (fut_p *)&theFutFromMatrix);
					break;

				default:
					break;
				}
				if (NULL != theFutFromMatrix)
				{
					/* Create a PT from the fut */
					errnum = fut2PT (&theFutFromMatrix, KCM_UNKNOWN, KCM_UNKNOWN, PTTYPE_CALCULATED, &matrixPTRefNum);
					if (errnum != KCP_SUCCESS) {
						goto GetOut;
					}
					errnum = setMatrixPTRefNum (PTRefNum, matrixPTRefNum, fut->lutConfig);
					if (errnum != KCP_SUCCESS) {
						goto GetOut;
					}
				}
				if (ret != 1) {
					errnum = KCP_INCON_PT;
					goto GetOut;
				}
			}

			if ((fut == NULL) || !fut_io_encode (fut, futHdr)) {	/* make the info header */
				errnum = KCP_INCON_PT;
				goto GetOut;
			}

			errnum = KCP_SUCCESS;
		}
		break;

	default:
		break;
	}


GetOut:
	if ((errnum != KCP_SUCCESS) || (fut == NULL)) {
		fut_free (fut);
	}
	else {		/* return handle to fut to caller */

	/* make sure the futs are in the reference state */
		if (fut_to_mft (fut) == 1) {
			*PTData = (KpHandle_t)fut_unlock_fut (fut);
		}
	}

	if ( ! unlockBuffer (PTHdr)) {
		errnum = KCP_MEM_UNLOCK_ERR;
	}

	return errnum;
}