📄 tekhvc.c
字号:
} return(XcmsSuccess);}/* * NAME * XcmsTekHVCToCIEuvY - convert TekHVC to CIEuvY * * SYNOPSIS */StatusXcmsTekHVCToCIEuvY(ccc, pHVC_WhitePt, pColors_in_out, nColors) XcmsCCC ccc; XcmsColor *pHVC_WhitePt; XcmsColor *pColors_in_out; unsigned int nColors;/* * DESCRIPTION * Transforms an array of TekHVC color specifications, given * their associated white point, to CIECIEuvY.color * specifications. * * RETURNS * XcmsFailure if failed, XcmsSuccess otherwise. * */{ XcmsFloat thetaOffset; XcmsColor *pColor = pColors_in_out; XcmsColor whitePt; XcmsCIEuvY uvY_return; XcmsFloat tempHue, u, v; XcmsFloat tmpVal; register int i; /* * Check arguments */ if (pHVC_WhitePt == NULL || pColors_in_out == NULL) { return(XcmsFailure); } /* * Make sure white point is in CIEuvY form */ if (pHVC_WhitePt->format != XcmsCIEuvYFormat) { /* Make copy of the white point because we're going to modify it */ bcopy((char *)pHVC_WhitePt, (char *)&whitePt, sizeof(XcmsColor)); if (!_XcmsDIConvertColors(ccc, &whitePt, (XcmsColor *)NULL, 1, XcmsCIEuvYFormat)) { return(XcmsFailure); } pHVC_WhitePt = &whitePt; } /* Make sure it is a white point, i.e., Y == 1.0 */ if (pHVC_WhitePt->spec.CIEuvY.Y != 1.0) { return(XcmsFailure); } /* Get the thetaOffset */ if (!ThetaOffset(pHVC_WhitePt, &thetaOffset)) { return(XcmsFailure); } /* * Now convert each XcmsColor structure to CIEXYZ form */ for (i = 0; i < nColors; i++, pColor++) { /* Make sure original format is TekHVC and is valid */ if (!XcmsTekHVC_ValidSpec(pColor)) { return(XcmsFailure); } if (pColor->spec.TekHVC.V == 0.0 || pColor->spec.TekHVC.V == 100.0) { if (pColor->spec.TekHVC.V == 100.0) { uvY_return.Y = 1.0; } else { /* pColor->spec.TekHVC.V == 0.0 */ uvY_return.Y = 0.0; } uvY_return.u_prime = pHVC_WhitePt->spec.CIEuvY.u_prime; uvY_return.v_prime = pHVC_WhitePt->spec.CIEuvY.v_prime; } else { /* Find the hue based on the white point offset */ tempHue = pColor->spec.TekHVC.H + thetaOffset; while (tempHue < 0.0) { tempHue += 360.0; } while (tempHue >= 360.0) { tempHue -= 360.0; } tempHue = radians(tempHue); /* Calculate u'v' for the obtained hue */ u = (XcmsFloat) ((XCMS_COS(tempHue) * pColor->spec.TekHVC.C) / (pColor->spec.TekHVC.V * (double)CHROMA_SCALE_FACTOR)); v = (XcmsFloat) ((XCMS_SIN(tempHue) * pColor->spec.TekHVC.C) / (pColor->spec.TekHVC.V * (double)CHROMA_SCALE_FACTOR)); /* Based on the white point get the offset from best red */ uvY_return.u_prime = u + pHVC_WhitePt->spec.CIEuvY.u_prime; uvY_return.v_prime = v + pHVC_WhitePt->spec.CIEuvY.v_prime; /* Calculate the Y value based on the L* = V. */ if (pColor->spec.TekHVC.V < 7.99953624) { uvY_return.Y = pColor->spec.TekHVC.V / 903.29; } else { tmpVal = (pColor->spec.TekHVC.V + 16.0) / 116.0; uvY_return.Y = tmpVal * tmpVal * tmpVal; /* tmpVal ** 3 */ } } /* Copy result to pColor */ bcopy ((char *)&uvY_return, (char *)&pColor->spec, sizeof(XcmsCIEuvY)); /* Identify that the format is now CIEuvY */ pColor->format = XcmsCIEuvYFormat; } return(XcmsSuccess);}/* * NAME * XcmsCIEuvYToTekHVC - convert CIEuvY to TekHVC * * SYNOPSIS */StatusXcmsCIEuvYToTekHVC(ccc, pHVC_WhitePt, pColors_in_out, nColors) XcmsCCC ccc; XcmsColor *pHVC_WhitePt; XcmsColor *pColors_in_out; unsigned int nColors;/* * DESCRIPTION * Transforms an array of CIECIEuvY.color specifications, given * their assiciated white point, to TekHVC specifications. * * RETURNS * XcmsFailure if failed, XcmsSuccess otherwise. * */{ XcmsFloat theta, L2, u, v, nThetaLow, nThetaHigh; XcmsFloat thetaOffset; XcmsColor *pColor = pColors_in_out; XcmsColor whitePt; XcmsTekHVC HVC_return; register int i; /* * Check arguments */ if (pHVC_WhitePt == NULL || pColors_in_out == NULL) { return(XcmsFailure); } /* * Make sure white point is in CIEuvY form */ if (pHVC_WhitePt->format != XcmsCIEuvYFormat) { /* Make copy of the white point because we're going to modify it */ bcopy((char *)pHVC_WhitePt, (char *)&whitePt, sizeof(XcmsColor)); if (!_XcmsDIConvertColors(ccc, &whitePt, (XcmsColor *)NULL, 1, XcmsCIEuvYFormat)) { return(XcmsFailure); } pHVC_WhitePt = &whitePt; } /* Make sure it is a white point, i.e., Y == 1.0 */ if (pHVC_WhitePt->spec.CIEuvY.Y != 1.0) { return(XcmsFailure); } if (!ThetaOffset(pHVC_WhitePt, &thetaOffset)) { return(XcmsFailure); } /* * Now convert each XcmsColor structure to CIEXYZ form */ for (i = 0; i < nColors; i++, pColor++) { if (!XcmsCIEuvY_ValidSpec(pColor)) { return(XcmsFailure); } /* Use the white point offset to determine HVC */ u = pColor->spec.CIEuvY.u_prime - pHVC_WhitePt->spec.CIEuvY.u_prime; v = pColor->spec.CIEuvY.v_prime - pHVC_WhitePt->spec.CIEuvY.v_prime; /* Calculate the offset */ if (u == 0.0) { theta = 0.0; } else { theta = v / u; theta = (XcmsFloat) XCMS_ATAN((double)theta); theta = degrees(theta); } nThetaLow = 0.0; nThetaHigh = 360.0; if (u > 0.0 && v > 0.0) { nThetaLow = 0.0; nThetaHigh = 90.0; } else if (u < 0.0 && v > 0.0) { nThetaLow = 90.0; nThetaHigh = 180.0; } else if (u < 0.0 && v < 0.0) { nThetaLow = 180.0; nThetaHigh = 270.0; } else if (u > 0.0 && v < 0.0) { nThetaLow = 270.0; nThetaHigh = 360.0; } while (theta < nThetaLow) { theta += 90.0; } while (theta >= nThetaHigh) { theta -= 90.0; } /* calculate the L value from the given Y */ L2 = (pColor->spec.CIEuvY.Y < 0.008856) ? (pColor->spec.CIEuvY.Y * 903.29) : ((XcmsFloat)(XCMS_CUBEROOT(pColor->spec.CIEuvY.Y) * 116.0) - 16.0); HVC_return.C = L2 * CHROMA_SCALE_FACTOR * XCMS_SQRT((double) ((u * u) + (v * v))); if (HVC_return.C < 0.0) { theta = 0.0; } HVC_return.V = L2; HVC_return.H = theta - thetaOffset; /* * If this is within the error margin let some other routine later * in the chain worry about the slop in the calculations. */ while (HVC_return.H < -EPS) { HVC_return.H += 360.0; } while (HVC_return.H >= 360.0 + EPS) { HVC_return.H -= 360.0; } /* Copy result to pColor */ bcopy ((char *)&HVC_return, (char *)&pColor->spec, sizeof(XcmsTekHVC)); /* Identify that the format is now CIEuvY */ pColor->format = XcmsTekHVCFormat; } return(XcmsSuccess);}/* * NAME * _XcmsTekHVC_CheckModify * * SYNOPSIS */int_XcmsTekHVC_CheckModify(pColor) XcmsColor *pColor;/* * DESCRIPTION * Checks if values in the color specification are valid. * If they are not it modifies the values. * Also brings hue into the range 0.0 <= Hue < 360.0 * * RETURNS * 0 if not valid. * 1 if valid. * */{ /* For now only use the TekHVC numbers as inputs */ if (pColor->format != XcmsTekHVCFormat) { return(0); } if (pColor->spec.TekHVC.V < 0.0) { pColor->spec.TekHVC.V = 0.0 + XMY_DBL_EPSILON; } else if (pColor->spec.TekHVC.V > 100.0) { pColor->spec.TekHVC.V = 100.0 - XMY_DBL_EPSILON; } if (pColor->spec.TekHVC.C < 0.0) { pColor->spec.TekHVC.C = 0.0 - XMY_DBL_EPSILON; } while (pColor->spec.TekHVC.H < 0.0) { pColor->spec.TekHVC.H += 360.0; } while (pColor->spec.TekHVC.H >= 360.0) { pColor->spec.TekHVC.H -= 360.0; } return(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -