patches2_xcms_fixes.diff Index: xc/lib/X11/LabGcL.c =================================================================== --- xc.orig/lib/X11/LabGcL.c 2005-11-22 08:07:53.000000000 +0100 +++ xc/lib/X11/LabGcL.c 2005-11-22 08:17:39.000000000 +0100 @@ -101,7 +101,7 @@ */ return(XcmsFailure); } else { - /* Convert from CIEXYZ to CIE L*u*v* format */ + /* Convert from CIEXYZ to CIE L*a*b* format */ if (_XcmsDIConvertColors(&myCCC, pColor, ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELabFormat) == XcmsFailure) { @@ -115,10 +115,13 @@ /* Step 1: compute the maximum L* and chroma for this hue. */ /* This copy may be overkill but it preserves the pixel etc. */ memcpy((char *)&Lab_max, (char *)pColor, sizeof(XcmsColor)); - if (_XcmsCIELabQueryMaxLCRGB (&myCCC, hue, &Lab_max, - (XcmsRGBi *)NULL) == XcmsFailure) { - return (XcmsFailure); + + if (XcmsCIELabQueryMaxLC(&myCCC, degrees(hue), &Lab_max) + == XcmsFailure) + { + return (XcmsFailure); } + maxChroma = XCMS_CIELAB_PMETRIC_CHROMA(Lab_max.spec.CIELab.a_star, Lab_max.spec.CIELab.b_star); @@ -133,7 +136,9 @@ /* When the chroma input is greater than the maximum chroma */ /* merely return the L* and chroma for the given hue. */ memcpy((char *)pColor, (char *)&Lab_max, sizeof(XcmsColor)); - return (XcmsFailure); + retval = _XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); + /* return (XcmsFailure); Principle of ClipL is to return something.*/ } else if (pColor->spec.CIELab.L_star < Lab_max.spec.CIELab.L_star) { /* Find the minimum lightness for the given chroma. */ if (pColor->format != XcmsCIELabFormat) { Index: xc/lib/X11/LabGcLC.c =================================================================== --- xc.orig/lib/X11/LabGcLC.c 2005-11-22 08:07:53.000000000 +0100 +++ xc/lib/X11/LabGcLC.c 2005-11-22 08:18:31.000000000 +0100 @@ -42,7 +42,7 @@ * Internal defines that need NOT be exported to any package or * program using this package. */ -#define MAXBISECTCOUNT 100 +#define EPS (XcmsFloat) 0.5 /*CIELab units*/ /************************************************************************ @@ -69,7 +69,7 @@ * DESCRIPTION * This routine will find the closest L* and chroma * for a specific hue. The color input is converted to - * CIE L*u*v* format and returned as CIE XYZ format. + * CIE L*a*b* format and returned as CIE XYZ format. * * Since this routine works with the L* within * pColor_in_out intermediate results may be returned @@ -84,13 +84,12 @@ Status retval; XcmsCCCRec myCCC; XcmsColor *pColor; - XcmsColor Lab_max; - XcmsFloat hue, chroma, maxChroma; - XcmsFloat Chroma, bestChroma, Lstar, maxLstar, saveLstar; - XcmsFloat bestLstar, bestastar, bestbstar; - XcmsFloat nT, saveDist, tmpDist; - XcmsRGBi rgb_max; - int nCount, nMaxCount, nI, nILast; + XcmsColor Lab_max, tmp; + XcmsFloat hue, Lstar, chroma; + XcmsFloat maxLstar, maxChroma, saveDist; + XcmsFloat tmpLstar, tmpChroma, tmpDist; + XcmsFloat nMaxCountLstar, nMinCountLstar, count; + int nCount; /* Use my own CCC */ memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); @@ -129,94 +128,63 @@ return(XcmsFailure); } - /* Step 1: compute the maximum L* and chroma for this hue. */ - /* This copy may be overkill but it preserves the pixel etc. */ - saveLstar = pColor->spec.CIELab.L_star; + Lstar = pColor->spec.CIELab.L_star; hue = XCMS_CIELAB_PMETRIC_HUE(pColor->spec.CIELab.a_star, pColor->spec.CIELab.b_star); chroma = XCMS_CIELAB_PMETRIC_CHROMA(pColor->spec.CIELab.a_star, pColor->spec.CIELab.b_star); + + /* Step 1: compute the maximum L* and chroma for this hue. */ + /* This copy may be overkill but it preserves the pixel etc. */ + memcpy((char *)&Lab_max, (char *)pColor, sizeof(XcmsColor)); - if (_XcmsCIELabQueryMaxLCRGB (&myCCC, hue, &Lab_max, &rgb_max) + if (XcmsCIELabQueryMaxLC (&myCCC, degrees(hue), &Lab_max) == XcmsFailure) { return (XcmsFailure); } + maxLstar = Lab_max.spec.CIELab.L_star; - - /* Now check and return the appropriate L* */ - if (saveLstar == maxLstar) { - /* When the L* input is equal to the maximum L* */ - /* merely return the maximum Lab point. */ - memcpy((char *)pColor, (char *)&Lab_max, sizeof(XcmsColor)); - retval = _XcmsDIConvertColors(&myCCC, pColor, - ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); - } else { - /* return the closest point on the hue leaf. */ - /* must do a bisection here to compute the delta e. */ - maxChroma = XCMS_CIELAB_PMETRIC_CHROMA(Lab_max.spec.CIELab.a_star, - Lab_max.spec.CIELab.b_star); - nMaxCount = MAXBISECTCOUNT; - nI = nMaxCount / 2; - bestLstar = Lstar = pColor->spec.CIELab.L_star; - bestastar = pColor->spec.CIELab.a_star; - bestbstar = pColor->spec.CIELab.b_star; - bestChroma = Chroma = chroma; - saveDist = XCMS_SQRT(((Chroma - maxChroma) * (Chroma - maxChroma)) + + maxChroma = XCMS_CIELAB_PMETRIC_CHROMA(Lab_max.spec.CIELab.a_star, + Lab_max.spec.CIELab.b_star); + saveDist = XCMS_SQRT(((chroma - maxChroma) * (chroma - maxChroma)) + ((Lstar - maxLstar) * (Lstar - maxLstar))); - for (nCount = 0; nCount < nMaxCount; nCount++) { - nT = (XcmsFloat) nI / (XcmsFloat) nMaxCount; - if (saveLstar > maxLstar) { - pColor->spec.RGBi.red = rgb_max.red * (1.0 - nT) + nT; - pColor->spec.RGBi.green = rgb_max.green * (1.0 - nT) + nT; - pColor->spec.RGBi.blue = rgb_max.blue * (1.0 - nT) + nT; - } else { - pColor->spec.RGBi.red = rgb_max.red - (rgb_max.red * nT); - pColor->spec.RGBi.green = rgb_max.green - (rgb_max.green * nT); - pColor->spec.RGBi.blue = rgb_max.blue - (rgb_max.blue * nT); - } - pColor->format = XcmsRGBiFormat; - - /* Convert from RGBi to CIE Lab */ - if (_XcmsConvertColorsWithWhitePt(&myCCC, pColor, - ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELabFormat, - (Bool *) NULL) == XcmsFailure) { - return (XcmsFailure); - } - chroma = XCMS_CIELAB_PMETRIC_CHROMA(pColor->spec.CIELab.a_star, - pColor->spec.CIELab.b_star); - tmpDist = XCMS_SQRT(((Chroma - chroma) * (Chroma - chroma)) + - ((Lstar - pColor->spec.CIELab.L_star) * - (Lstar - pColor->spec.CIELab.L_star))); - nILast = nI; - if (tmpDist > saveDist) { - nI /= 2; - } else { - nI = (nMaxCount + nI) / 2; + memcpy((char *)pColor, (char *)&Lab_max, sizeof(XcmsColor)); + + /* Initialized the variables.*/ + + nMaxCountLstar = 100; + nMinCountLstar = 0; + + if (Lstar < maxLstar) { + nMaxCountLstar = maxLstar; + } + if (Lstar > maxLstar) { + nMinCountLstar = maxLstar; + } + + /* Now check and return the appropriate L* */ + + for(nCount = 0; nCount <= (nMaxCountLstar-nMinCountLstar)/EPS; nCount ++) + { + count = nCount*EPS + nMinCountLstar; + XcmsCIELabQueryMaxC(&myCCC, degrees(hue), nCount, &tmp); + tmpLstar = tmp.spec.CIELab.L_star; + tmpChroma = XCMS_CIELAB_PMETRIC_CHROMA(tmp.spec.CIELab.a_star, + tmp.spec.CIELab.b_star); + tmpDist = XCMS_SQRT(((chroma - tmpChroma) * (chroma - tmpChroma)) + + ((Lstar - tmpLstar) * (Lstar - tmpLstar))); + if (tmpDist < saveDist) + { saveDist = tmpDist; - bestLstar = pColor->spec.CIELab.L_star; - bestastar = pColor->spec.CIELab.a_star; - bestbstar = pColor->spec.CIELab.b_star; - bestChroma = chroma; - } - if (nI == nILast || nI == 0) { - break; - } - } - if (bestChroma >= maxChroma) { - pColor->spec.CIELab.L_star = maxLstar; - pColor->spec.CIELab.a_star = Lab_max.spec.CIELab.a_star; - pColor->spec.CIELab.b_star = Lab_max.spec.CIELab.b_star; - } else { - pColor->spec.CIELab.L_star = bestLstar; - pColor->spec.CIELab.a_star = bestastar; - pColor->spec.CIELab.b_star = bestbstar; + memcpy((char *)pColor, (char *)&tmp, sizeof(XcmsColor)); } + } + retval = _XcmsDIConvertColors(&myCCC, pColor, ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); if (retval != XcmsFailure && pCompressed != NULL) { *(pCompressed + i) = True; } - } return(retval); } Index: xc/lib/X11/LabMnL.c =================================================================== --- xc.orig/lib/X11/LabMnL.c 2005-11-22 08:07:53.000000000 +0100 +++ xc/lib/X11/LabMnL.c 2005-11-22 08:20:00.000000000 +0100 @@ -41,9 +41,9 @@ /* * DEFINES */ -#define MAXBISECTCOUNT 100 +#define MAXBISECTCOUNT 200 #define EPS (XcmsFloat)0.001 -#define START_L_STAR (XcmsFloat)40.0 +#define START_L_STAR (XcmsFloat)0.0 /*black.*/ /************************************************************************ @@ -54,7 +54,7 @@ /* * NAME - * XcmsCIELabQueryMinL - Compute max Lstar for a hue and chroma + * XcmsCIELabQueryMinL - Compute min Lstar for a hue and chroma * * SYNOPSIS */ @@ -66,7 +66,7 @@ XcmsColor *pColor_return; /* * DESCRIPTION - * Return the maximum Lstar for a specified hue_angle and chroma. + * Return the minumum Lstar for a specified hue_angle and chroma. * * ASSUMPTIONS * This routine assumes that the white point associated with @@ -81,11 +81,9 @@ */ { XcmsCCCRec myCCC; - XcmsColor max_lc, tmp, prev; - XcmsFloat max_chroma, tmp_chroma; - XcmsFloat hue, nT, nChroma, lastChroma, prevChroma; - XcmsFloat rFactor; - XcmsRGBi rgb_saved; + XcmsColor tmp; + XcmsFloat tmp_L_star, prev_L_star; + XcmsFloat hue, Factor; int nCount, nMaxCount; /* @@ -108,108 +106,56 @@ } hue = radians(hue_angle); - tmp.spec.CIELab.L_star = START_L_STAR; - tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, chroma); - tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, chroma); - tmp.pixel = pColor_return->pixel; - tmp.format = XcmsCIELabFormat; - - /* Step 1: Obtain the maximum L_star and chroma for this hue. */ - if (_XcmsCIELabQueryMaxLCRGB(&myCCC, hue, &max_lc, &rgb_saved) - == XcmsFailure) { - return(XcmsFailure); - } - - max_chroma = XCMS_CIELAB_PMETRIC_CHROMA(max_lc.spec.CIELab.a_star, - max_lc.spec.CIELab.b_star); - - if (max_chroma <= chroma) { - /* - * If the chroma is greater than the chroma for the - * maximum L/chroma point then the L_star is the - * the L_star for the maximum L_star/chroma point. - * This is an error but I return the best approximation I can. - * Thus the inconsistency. - */ - memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); - return(XcmsSuccess); - } - - /* - * If the chroma is equal to the chroma for the - * maximum L_star/chroma point then the L_star is the - * the L_star for the maximum L* and chroma point. - */ - /* if (max_chroma == chroma) { - * memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); - * return(XcmsSuccess); - * } - */ - - /* must do a bisection here to compute the maximum L* */ - /* save the structure input so that any elements that */ - /* are not touched are recopied later in the routine. */ - nChroma = chroma; - tmp_chroma = max_chroma; - lastChroma = -1.0; + tmp_L_star = START_L_STAR; + prev_L_star = tmp_L_star; nMaxCount = MAXBISECTCOUNT; - rFactor = 1.0; + Factor = 10.0; for (nCount = 0; nCount < nMaxCount; nCount++) { - prevChroma = lastChroma; - lastChroma = tmp_chroma; - nT = (nChroma - max_chroma) / max_chroma * rFactor; - memcpy ((char *)&prev, (char *)&tmp, sizeof(XcmsColor)); - tmp.spec.RGBi.red = rgb_saved.red + (rgb_saved.red * nT); - tmp.spec.RGBi.green = rgb_saved.green + (rgb_saved.green * nT); - tmp.spec.RGBi.blue = rgb_saved.blue + (rgb_saved.blue * nT); - tmp.format = XcmsRGBiFormat; - - /* convert from RGB to CIELab */ - if (_XcmsConvertColorsWithWhitePt(&myCCC, &tmp, - ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELabFormat, - (Bool *) NULL) == XcmsFailure) { - return(XcmsFailure); - } - /* Now check the return against what is expected */ - tmp_chroma = XCMS_CIELAB_PMETRIC_CHROMA(tmp.spec.CIELab.a_star, - tmp.spec.CIELab.b_star); - if (tmp_chroma <= chroma + EPS && tmp_chroma >= chroma - EPS) { - /* Found It! */ - memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); - return(XcmsSuccess); + tmp.spec.CIELab.L_star = tmp_L_star; + tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, chroma); + tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, chroma); + tmp.format = XcmsCIELabFormat; + + /* convert from CIELab to RGBi */ + _XcmsConvertColorsWithWhitePt(&myCCC, &tmp, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsRGBiFormat, + (Bool *) NULL); + if ((tmp.spec.RGBi.red >= 0.0) & (tmp.spec.RGBi.green >= 0.0) & + (tmp.spec.RGBi.blue >= 0.0) & (tmp.spec.RGBi.red <= 1.0) & + (tmp.spec.RGBi.green <= 1.0) & (tmp.spec.RGBi.blue <= 1.0)) + { + tmp_L_star = prev_L_star; + Factor = Factor/10.0; } - nChroma += chroma - tmp_chroma; - if (nChroma > max_chroma) { - nChroma = max_chroma; - rFactor *= 0.5; /* selective relaxation employed */ - } else if (nChroma < 0.0) { - if (XCMS_FABS(lastChroma - chroma) < - XCMS_FABS(tmp_chroma - chroma)) { - memcpy ((char *)pColor_return, (char *)&prev, - sizeof(XcmsColor)); - } else { - memcpy ((char *)pColor_return, (char *)&tmp, - sizeof(XcmsColor)); - } - return(XcmsSuccess); - } else if (tmp_chroma <= prevChroma + EPS && - tmp_chroma >= prevChroma - EPS) { - rFactor *= 0.5; /* selective relaxation employed */ + if (Factor <= EPS) { + /* Found It! */ + tmp.spec.CIELab.L_star = tmp_L_star; + tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, chroma); + tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, chroma); + tmp.format = XcmsCIELabFormat; + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); } - } - if (nCount >= nMaxCount) { - if (XCMS_FABS(lastChroma - chroma) < - XCMS_FABS(tmp_chroma - chroma)) { - memcpy ((char *)pColor_return, (char *)&prev, - sizeof(XcmsColor)); - } else { - memcpy ((char *)pColor_return, (char *)&tmp, - sizeof(XcmsColor)); + prev_L_star = tmp_L_star; + tmp_L_star = tmp_L_star + Factor; + + if (tmp_L_star >= 100.0) + { + XcmsCIELabQueryMaxLC(&myCCC, hue_angle, pColor_return); + return(XcmsSuccess); } - } - memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); - return(XcmsSuccess); +} + +if (nCount >= nMaxCount) { + tmp.spec.CIELab.L_star = prev_L_star; + tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, chroma); + tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, chroma); + tmp.format = XcmsCIELabFormat; + memcpy ((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); +} + +return(XcmsSuccess); } Index: xc/lib/X11/LabMxC.c =================================================================== --- xc.orig/lib/X11/LabMxC.c 2005-11-22 08:07:53.000000000 +0100 +++ xc/lib/X11/LabMxC.c 2005-11-22 08:21:30.000000000 +0100 @@ -43,10 +43,9 @@ /* * DEFINES */ -#define MAXBISECTCOUNT 100 +#define MAXBISECTCOUNT 200 #define EPS (XcmsFloat)0.001 -#define START_CHROMA (XcmsFloat)3.6 -#define TOPL (XcmsFloat)100.0 +#define START_CHROMA (XcmsFloat)0.0 /************************************************************************ @@ -86,11 +85,9 @@ */ { XcmsCCCRec myCCC; - XcmsColor tmp; - XcmsColor max_lc; - XcmsFloat n_L_star, last_L_star, prev_L_star; - XcmsFloat hue, lastaStar, lastbStar, /*lastChroma,*/ maxDist, nT, rFactor; - XcmsRGBi rgb_saved; + XcmsColor tmp; + XcmsFloat tmp_chroma, prev_chroma; + XcmsFloat hue, Factor; int nCount, nMaxCount; /* @@ -113,90 +110,63 @@ } hue = radians(hue_angle); - tmp.spec.CIELab.L_star = L_star; - tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, START_CHROMA); - tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, START_CHROMA); - tmp.pixel = pColor_return->pixel; - tmp.format = XcmsCIELabFormat; - - /* Step 1: compute the maximum L_star and chroma for this hue. */ - memcpy((char *)&max_lc, (char *)&tmp, sizeof(XcmsColor)); - if (_XcmsCIELabQueryMaxLCRGB(&myCCC, hue, &max_lc, &rgb_saved) - == XcmsFailure) { - return(XcmsFailure); - } - - /* - * Step 2: Do a bisection here to compute the maximum chroma - * Note the differences between when the point to be found - * is above the maximum LC point and when it is below. - */ - if (L_star <= max_lc.spec.CIELab.L_star) { - maxDist = max_lc.spec.CIELab.L_star; - } else { - maxDist = TOPL - max_lc.spec.CIELab.L_star; - } - - n_L_star = L_star; - last_L_star = -1.0; + tmp_chroma = START_CHROMA; + prev_chroma = tmp_chroma; nMaxCount = MAXBISECTCOUNT; - rFactor = 1.0; - - for (nCount = 0; nCount < nMaxCount; nCount++) { - prev_L_star = last_L_star; - last_L_star = tmp.spec.CIELab.L_star; -/* lastChroma = XCMS_CIELAB_PMETRIC_CHROMA(tmp.spec.CIELab.a_star, */ -/* tmp.spec.CIELab.b_star); */ - lastaStar = tmp.spec.CIELab.a_star; - lastbStar = tmp.spec.CIELab.b_star; - nT = (n_L_star - max_lc.spec.CIELab.L_star) / maxDist * rFactor; - if (nT > 0) { - tmp.spec.RGBi.red = rgb_saved.red * (1.0 - nT) + nT; - tmp.spec.RGBi.green = rgb_saved.green * (1.0 - nT) + nT; - tmp.spec.RGBi.blue = rgb_saved.blue * (1.0 - nT) + nT; - } else { - tmp.spec.RGBi.red = rgb_saved.red + (rgb_saved.red * nT); - tmp.spec.RGBi.green = rgb_saved.green + (rgb_saved.green * nT); - tmp.spec.RGBi.blue = rgb_saved.blue + (rgb_saved.blue * nT); - } - tmp.format = XcmsRGBiFormat; + Factor = 10.0; - /* convert from RGB to CIELab */ - if (_XcmsConvertColorsWithWhitePt(&myCCC, &tmp, - ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELabFormat, - (Bool *) NULL) == XcmsFailure) { - return(XcmsFailure); - } + for (nCount = 0; nCount < nMaxCount; nCount++) + { - /* - * Now check if we've reached the target L_star - */ - /* printf("result Lstar = %lf\n", tmp.spec.CIELab.L_star); */ - if (tmp.spec.CIELab.L_star <= L_star + EPS && - tmp.spec.CIELab.L_star >= L_star - EPS) { + tmp.spec.CIELab.L_star = L_star; + tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, tmp_chroma); + tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, tmp_chroma); + tmp.format = XcmsCIELabFormat; + + if (((L_star == 0.0) & (tmp_chroma == 0.0)) | + ((L_star == 100.0) & (tmp_chroma == 0.0))) + { + tmp.spec.CIELab.L_star = L_star; + tmp.spec.CIELab.a_star = 0.0; + tmp.spec.CIELab.b_star = 0.0; + tmp.format = XcmsCIELabFormat; memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); return(XcmsSuccess); } - if (nT > 0) { - n_L_star += ((TOPL - n_L_star) * - (L_star - tmp.spec.CIELab.L_star)) / (TOPL - L_star); - } else { - n_L_star *= L_star / tmp.spec.CIELuv.L_star; + + + /* convert from CIELab to RGBi. */ + _XcmsConvertColorsWithWhitePt(&myCCC, &tmp, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsRGBiFormat, + (Bool *) NULL); + + if ((tmp.spec.RGBi.red < 0.0) | (tmp.spec.RGBi.green < 0.0) | + (tmp.spec.RGBi.blue < 0.0) | (tmp.spec.RGBi.red > 1.0) | + (tmp.spec.RGBi.green > 1.0) | (tmp.spec.RGBi.blue > 1.0)) + { + tmp_chroma = prev_chroma; + Factor = Factor/10.0; } - if (tmp.spec.CIELab.L_star <= prev_L_star + EPS && - tmp.spec.CIELab.L_star >= prev_L_star - EPS) { - rFactor *= 0.5; /* selective relaxation employed */ - /* printf("rFactor = %lf\n", rFactor); */ + if (Factor <= EPS) + { + tmp.spec.CIELab.L_star = L_star; + tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, tmp_chroma); + tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, tmp_chroma); + tmp.format = XcmsCIELabFormat; + memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); + return(XcmsSuccess); } + prev_chroma = tmp_chroma; + tmp_chroma = tmp_chroma + Factor; } - if (XCMS_FABS(last_L_star - L_star) < - XCMS_FABS(tmp.spec.CIELab.L_star - L_star)) { - tmp.spec.CIELab.a_star = lastaStar; - tmp.spec.CIELab.b_star = lastbStar; -/* tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, lastChroma); */ -/* tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, lastChroma); */ + + if (nCount >= nMaxCount) + { + tmp.spec.CIELab.L_star = L_star; + tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, prev_chroma); + tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, prev_chroma); + tmp.format = XcmsCIELabFormat; + memcpy ((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); } - tmp.spec.CIELab.L_star = L_star; - memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); - return(XcmsSuccess); +return(XcmsSuccess); } Index: xc/lib/X11/LabMxL.c =================================================================== --- xc.orig/lib/X11/LabMxL.c 2005-11-22 08:07:53.000000000 +0100 +++ xc/lib/X11/LabMxL.c 2005-11-22 08:22:29.000000000 +0100 @@ -41,9 +41,9 @@ /* * DEFINES */ -#define MAXBISECTCOUNT 100 +#define MAXBISECTCOUNT 200 #define EPS (XcmsFloat)0.001 -#define START_L_STAR (XcmsFloat)40 +#define START_L_STAR (XcmsFloat)100.0 /*white.*/ /************************************************************************ @@ -61,7 +61,7 @@ Status XcmsCIELabQueryMaxL(ccc, hue_angle, chroma, pColor_return) XcmsCCC ccc; - XcmsFloat hue_angle; /* hue in degrees */ + XcmsFloat hue_angle; /* hue angle in degrees */ XcmsFloat chroma; XcmsColor *pColor_return; /* @@ -81,11 +81,9 @@ */ { XcmsCCCRec myCCC; - XcmsColor max_lc, tmp, prev; - XcmsFloat max_chroma, tmp_chroma; - XcmsFloat hue, nT, nChroma, lastChroma, prevChroma; - XcmsFloat rFactor; - XcmsRGBi rgb_saved; + XcmsColor tmp; + XcmsFloat tmp_L_star, prev_L_star; + XcmsFloat hue, Factor; int nCount, nMaxCount; /* @@ -108,108 +106,56 @@ } hue = radians(hue_angle); - tmp.spec.CIELab.L_star = START_L_STAR; - tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, chroma); - tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, chroma); - tmp.pixel = pColor_return->pixel; - tmp.format = XcmsCIELabFormat; - - /* Step 1: Obtain the maximum L_star and chroma for this hue. */ - if (_XcmsCIELabQueryMaxLCRGB(&myCCC, hue, &max_lc, &rgb_saved) - == XcmsFailure) { - return(XcmsFailure); - } - - max_chroma = XCMS_CIELAB_PMETRIC_CHROMA(max_lc.spec.CIELab.a_star, - max_lc.spec.CIELab.b_star); - - if (max_chroma <= chroma) { - /* - * If the chroma is greater than the chroma for the - * maximum L/chroma point then the L_star is the - * the L_star for the maximum L_star/chroma point. - * This is an error but I return the best approximation I can. - * Thus the inconsistency. - */ - memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); - return(XcmsSuccess); - } - - /* - * If the chroma is equal to the chroma for the - * maximum L_star/chroma point then the L_star is the - * the L_star for the maximum L* and chroma point. - */ - /* if (max_chroma == chroma) { - * memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); - * return(XcmsSuccess); - * } - */ - - /* must do a bisection here to compute the maximum L* */ - /* save the structure input so that any elements that */ - /* are not touched are recopied later in the routine. */ - nChroma = chroma; - tmp_chroma = max_chroma; - lastChroma = -1.0; + tmp_L_star = START_L_STAR; + prev_L_star = tmp_L_star; nMaxCount = MAXBISECTCOUNT; - rFactor = 1.0; + Factor = 10.0; for (nCount = 0; nCount < nMaxCount; nCount++) { - prevChroma = lastChroma; - lastChroma = tmp_chroma; - nT = (1.0 - (nChroma / max_chroma)) * rFactor; - memcpy ((char *)&prev, (char *)&tmp, sizeof(XcmsColor)); - tmp.spec.RGBi.red = rgb_saved.red * (1.0 - nT) + nT; - tmp.spec.RGBi.green = rgb_saved.green * (1.0 - nT) + nT; - tmp.spec.RGBi.blue = rgb_saved.blue * (1.0 - nT) + nT; - tmp.format = XcmsRGBiFormat; - - /* convert from RGB to CIELab */ - if (_XcmsConvertColorsWithWhitePt(&myCCC, &tmp, - ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELabFormat, - (Bool *) NULL) == XcmsFailure) { - return(XcmsFailure); - } - /* Now check the return against what is expected */ - tmp_chroma = XCMS_CIELAB_PMETRIC_CHROMA(tmp.spec.CIELab.a_star, - tmp.spec.CIELab.b_star); - if (tmp_chroma <= chroma + EPS && tmp_chroma >= chroma - EPS) { - /* Found It! */ - memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); - return(XcmsSuccess); + tmp.spec.CIELab.L_star = tmp_L_star; + tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, chroma); + tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, chroma); + tmp.format = XcmsCIELabFormat; + + /* convert from CIELab to RGBi */ + _XcmsConvertColorsWithWhitePt(&myCCC, &tmp, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsRGBiFormat, + (Bool *) NULL); + if ((tmp.spec.RGBi.red >= 0.0) & (tmp.spec.RGBi.green >= 0.0) & + (tmp.spec.RGBi.blue >= 0.0) & (tmp.spec.RGBi.red <= 1.0) & + (tmp.spec.RGBi.green <= 1.0) & (tmp.spec.RGBi.blue <= 1.0)) + { + tmp_L_star = prev_L_star; + Factor = Factor/10.0; } - nChroma += chroma - tmp_chroma; - if (nChroma > max_chroma) { - nChroma = max_chroma; - rFactor *= 0.5; /* selective relaxation employed */ - } else if (nChroma < 0.0) { - if (XCMS_FABS(lastChroma - chroma) < - XCMS_FABS(tmp_chroma - chroma)) { - memcpy ((char *)pColor_return, (char *)&prev, - sizeof(XcmsColor)); - } else { - memcpy ((char *)pColor_return, (char *)&tmp, - sizeof(XcmsColor)); - } - return(XcmsSuccess); - } else if (tmp_chroma <= prevChroma + EPS && - tmp_chroma >= prevChroma - EPS) { - rFactor *= 0.5; /* selective relaxation employed */ + if (Factor <= EPS) { + /* Found It! */ + tmp.spec.CIELab.L_star = tmp_L_star; + tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, chroma); + tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, chroma); + tmp.format = XcmsCIELabFormat; + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); } - } - if (nCount >= nMaxCount) { - if (XCMS_FABS(lastChroma - chroma) < - XCMS_FABS(tmp_chroma - chroma)) { - memcpy ((char *)pColor_return, (char *)&prev, - sizeof(XcmsColor)); - } else { - memcpy ((char *)pColor_return, (char *)&tmp, - sizeof(XcmsColor)); + prev_L_star = tmp_L_star; + tmp_L_star = tmp_L_star - Factor; + + if (tmp_L_star <= 0.0) + { + XcmsCIELabQueryMaxLC(&myCCC, hue_angle, pColor_return); + return(XcmsSuccess); } - } - memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); - return(XcmsSuccess); +} + +if (nCount >= nMaxCount) { + tmp.spec.CIELab.L_star = prev_L_star; + tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, chroma); + tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, chroma); + tmp.format = XcmsCIELabFormat; + memcpy ((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); +} + +return(XcmsSuccess); } Index: xc/lib/X11/LabMxLC.c =================================================================== --- xc.orig/lib/X11/LabMxLC.c 2005-11-22 08:07:53.000000000 +0100 +++ xc/lib/X11/LabMxLC.c 2005-11-22 08:23:53.000000000 +0100 @@ -53,109 +53,11 @@ #define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z)))) #define START_LSTAR (XcmsFloat)40.0 #define START_CHROMA (XcmsFloat)3.6 +#define START_LSTAR2 (XcmsFloat)0.0 +#define START_CHROMA2 (XcmsFloat)0.0 +#define MAXBISECTCOUNT 200 +#define EPS (XcmsFloat)0.001 - -/************************************************************************ - * * - * API PRIVATE ROUTINES * - * * - ************************************************************************/ - -/* - * NAME - * _XcmsCIELabQueryMaxLCRGB - Compute maximum L* and chroma. - * - * SYNOPSIS - */ -Status -_XcmsCIELabQueryMaxLCRGB( - XcmsCCC ccc, - XcmsFloat hue, /* hue in radians */ - XcmsColor *pColor_return, - XcmsRGBi *pRGB_return) -/* - * DESCRIPTION - * Return the maximum psychometric chroma for a specified - * hue, and the corresponding L*. This is computed - * by a binary search of all possible chromas. An assumption - * is made that there are no local maxima. Use the unrounded - * Max psychometric chroma because the difference check can be - * small. - * - * NOTE: No local CCC is used because this is a private - * routine and all routines that call it are expected - * to behave properly, i.e. send a local CCC with - * no white adjust function and no gamut compression - * function. - * - * This routine only accepts hue in radians as input and outputs - * Lab and RGBi. - * - * RETURNS - * XcmsFailure - Failure - * XcmsSuccess - Succeeded - * - */ -{ - XcmsFloat nSmall, nLarge; - XcmsColor tmp; - - tmp.format = XcmsCIELabFormat; - /* Use some unreachable color on the given hue */ - tmp.spec.CIELab.L_star = START_LSTAR; - tmp.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, START_CHROMA); - tmp.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, START_CHROMA); - /* - * Convert from Lab to RGB - * - * Note that the CIEXYZ to RGBi conversion routine must stuff the - * out of bounds RGBi values in tmp when the ccc->gamutCompProc - * is NULL. - */ - if ((_XcmsConvertColorsWithWhitePt(ccc, &tmp, ScreenWhitePointOfCCC(ccc), - (unsigned int)1, XcmsRGBiFormat, (Bool *) NULL) - == XcmsFailure) && tmp.format != XcmsRGBiFormat) { - return (XcmsFailure); - } - - /* Now pick the smallest RGB */ - nSmall = MIN3(tmp.spec.RGBi.red, - tmp.spec.RGBi.green, - tmp.spec.RGBi.blue); - /* Make the smallest RGB equal to zero */ - tmp.spec.RGBi.red -= nSmall; - tmp.spec.RGBi.green -= nSmall; - tmp.spec.RGBi.blue -= nSmall; - - /* Now pick the largest RGB */ - nLarge = MAX3(tmp.spec.RGBi.red, - tmp.spec.RGBi.green, - tmp.spec.RGBi.blue); - /* Scale the RGB values based on the largest one */ - tmp.spec.RGBi.red /= nLarge; - tmp.spec.RGBi.green /= nLarge; - tmp.spec.RGBi.blue /= nLarge; - tmp.format = XcmsRGBiFormat; - - /* If the calling routine wants RGB value give them the ones used. */ - if (pRGB_return) { - pRGB_return->red = tmp.spec.RGBi.red; - pRGB_return->green = tmp.spec.RGBi.green; - pRGB_return->blue = tmp.spec.RGBi.blue; - } - - /* Convert from RGBi to Lab */ - if (_XcmsConvertColorsWithWhitePt(ccc, &tmp, - ScreenWhitePointOfCCC(ccc), 1, XcmsCIELabFormat, (Bool *) NULL) - == XcmsFailure) { - return (XcmsFailure); - } - - memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); - return (XcmsSuccess); -} - - /************************************************************************ * * * PUBLIC ROUTINES * @@ -192,6 +94,11 @@ */ { XcmsCCCRec myCCC; + XcmsFloat tmp_chroma, prev1_chroma, prev2_chroma; + XcmsFloat tmp_L_star, prev1_L_star, prev2_L_star; + XcmsFloat hue, Factor; + XcmsColor tmp_color; + int nCount, nMaxCount; /* * Check Arguments @@ -212,6 +119,55 @@ hue_angle -= 360.0; } - return(_XcmsCIELabQueryMaxLCRGB (&myCCC, radians(hue_angle), pColor_return, - (XcmsRGBi *)NULL)); + hue = radians(hue_angle); + tmp_L_star = START_LSTAR2; + prev1_L_star = tmp_L_star; + prev2_L_star = prev1_L_star; + tmp_chroma = START_CHROMA2; + prev1_chroma = tmp_chroma; + prev2_chroma = prev1_chroma; + nMaxCount = MAXBISECTCOUNT; + Factor = 10.0; + + for (nCount = 0; nCount < nMaxCount; nCount++) { + + XcmsCIELabQueryMaxC(&myCCC, hue_angle, tmp_L_star, &tmp_color); + + prev2_chroma = prev1_chroma; + prev1_chroma = tmp_chroma; + tmp_chroma = XCMS_CIELAB_PMETRIC_CHROMA(tmp_color.spec.CIELab.a_star, + tmp_color.spec.CIELab.b_star); + if (tmp_chroma <= prev1_chroma) + { + tmp_chroma = prev2_chroma; + prev1_chroma = prev2_chroma; + tmp_L_star = prev2_L_star; + prev1_L_star = prev2_L_star; + Factor = Factor/10.0; + + if (Factor <= EPS) + { + tmp_color.spec.CIELab.L_star = tmp_L_star; + tmp_color.spec.CIELab.a_star = XCMS_CIEASTAROFHUE(hue, tmp_chroma); + tmp_color.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, tmp_chroma); + tmp_color.format = XcmsCIELabFormat; + memcpy((char *)pColor_return, (char *)&tmp_color, sizeof(XcmsColor)); + return(XcmsSuccess); + } + } + prev2_L_star = prev1_L_star; + prev1_L_star = tmp_L_star; + tmp_L_star = tmp_L_star + Factor; + if (tmp_L_star >= 100.0) {tmp_L_star = 100.0;} + } + +if (nCount >= nMaxCount) { + tmp_color.spec.CIELab.L_star = prev1_L_star; + tmp_color.spec.CIELab .a_star = XCMS_CIEASTAROFHUE(hue, prev1_chroma); + tmp_color.spec.CIELab.b_star = XCMS_CIEBSTAROFHUE(hue, prev1_chroma); + tmp_color.format = XcmsCIELabFormat; + memcpy((char *)pColor_return, (char *)&tmp_color, sizeof(XcmsColor)); +} + +return(XcmsSuccess); } Index: xc/lib/X11/LuvGcL.c =================================================================== --- xc.orig/lib/X11/LuvGcL.c 2005-11-22 08:07:53.000000000 +0100 +++ xc/lib/X11/LuvGcL.c 2005-11-22 08:26:38.000000000 +0100 @@ -115,10 +115,13 @@ /* Step 1: compute the maximum L* and chroma for this hue. */ /* This copy may be overkill but it preserves the pixel etc. */ memcpy((char *)&Luv_max, (char *)pColor, sizeof(XcmsColor)); - if (_XcmsCIELuvQueryMaxLCRGB (&myCCC, hue, &Luv_max, - (XcmsRGBi *)NULL) == XcmsFailure) { - return (XcmsFailure); + + if (XcmsCIELuvQueryMaxLC(&myCCC, degrees(hue), &Luv_max) + == XcmsFailure) + { + return (XcmsFailure); } + maxChroma = XCMS_CIELUV_PMETRIC_CHROMA(Luv_max.spec.CIELuv.u_star, Luv_max.spec.CIELuv.v_star); @@ -133,7 +136,9 @@ /* When the chroma input is greater than the maximum chroma */ /* merely return the L* and chroma for the given hue. */ memcpy((char *)pColor, (char *)&Luv_max, sizeof(XcmsColor)); - return (XcmsFailure); + retval = _XcmsDIConvertColors(&myCCC, pColor, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); +/* return (XcmsFailure); Principle of ClipL is to return something.*/ } else if (pColor->spec.CIELuv.L_star < Luv_max.spec.CIELuv.L_star) { /* Find the minimum lightness for the given chroma. */ if (pColor->format != XcmsCIELuvFormat) { Index: xc/lib/X11/LuvGcLC.c =================================================================== --- xc.orig/lib/X11/LuvGcLC.c 2005-11-22 08:07:53.000000000 +0100 +++ xc/lib/X11/LuvGcLC.c 2005-11-22 08:25:48.000000000 +0100 @@ -42,7 +42,7 @@ * Internal defines that need NOT be exported to any package or * program using this package. */ -#define MAXBISECTCOUNT 100 +#define EPS (XcmsFloat) 0.5 /*CIELuv units*/ /************************************************************************ @@ -84,13 +84,12 @@ Status retval; XcmsCCCRec myCCC; XcmsColor *pColor; - XcmsColor Luv_max; - XcmsFloat hue, chroma, maxChroma; - XcmsFloat Chroma, bestChroma, Lstar, maxLstar, saveLstar; - XcmsFloat bestLstar, bestustar, bestvstar; - XcmsFloat nT, saveDist, tmpDist; - XcmsRGBi rgb_max; - int nCount, nMaxCount, nI, nILast; + XcmsColor Luv_max, tmp; + XcmsFloat hue, Lstar, chroma; + XcmsFloat maxLstar, maxChroma, saveDist; + XcmsFloat tmpLstar, tmpChroma, tmpDist; + XcmsFloat nMaxCountLstar, nMinCountLstar, count; + int nCount; /* Use my own CCC */ memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); @@ -129,94 +128,64 @@ return(XcmsFailure); } - /* Step 1: compute the maximum L* and chroma for this hue. */ - /* This copy may be overkill but it preserves the pixel etc. */ - saveLstar = pColor->spec.CIELuv.L_star; + Lstar = pColor->spec.CIELuv.L_star; hue = XCMS_CIELUV_PMETRIC_HUE(pColor->spec.CIELuv.u_star, pColor->spec.CIELuv.v_star); chroma = XCMS_CIELUV_PMETRIC_CHROMA(pColor->spec.CIELuv.u_star, pColor->spec.CIELuv.v_star); + + /* Step 1: compute the maximum L* and chroma for this hue. */ + /* This copy may be overkill but it preserves the pixel etc. */ + memcpy((char *)&Luv_max, (char *)pColor, sizeof(XcmsColor)); - if (_XcmsCIELuvQueryMaxLCRGB (&myCCC, hue, &Luv_max, &rgb_max) + if (XcmsCIELuvQueryMaxLC (&myCCC, degrees(hue), &Luv_max) == XcmsFailure) { return (XcmsFailure); } maxLstar = Luv_max.spec.CIELuv.L_star; - - /* Now check and return the appropriate L* */ - if (saveLstar == maxLstar) { - /* When the L* input is equal to the maximum L* */ - /* merely return the maximum Luv point. */ - memcpy((char *)pColor, (char *)&Luv_max, sizeof(XcmsColor)); - retval = _XcmsDIConvertColors(&myCCC, pColor, - ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); - } else { - /* return the closest point on the hue leaf. */ - /* must do a bisection here to compute the delta e. */ - maxChroma = XCMS_CIELUV_PMETRIC_CHROMA(Luv_max.spec.CIELuv.u_star, - Luv_max.spec.CIELuv.v_star); - nMaxCount = MAXBISECTCOUNT; - nI = nMaxCount / 2; - bestLstar = Lstar = pColor->spec.CIELuv.L_star; - bestustar = pColor->spec.CIELuv.u_star; - bestvstar = pColor->spec.CIELuv.v_star; - bestChroma = Chroma = chroma; - saveDist = XCMS_SQRT(((Chroma - maxChroma) * (Chroma - maxChroma)) + + maxChroma = XCMS_CIELUV_PMETRIC_CHROMA(Luv_max.spec.CIELuv.u_star, + Luv_max.spec.CIELuv.v_star); + + saveDist = XCMS_SQRT(((chroma - maxChroma) * (chroma - maxChroma)) + ((Lstar - maxLstar) * (Lstar - maxLstar))); - for (nCount = 0; nCount < nMaxCount; nCount++) { - nT = (XcmsFloat) nI / (XcmsFloat) nMaxCount; - if (saveLstar > maxLstar) { - pColor->spec.RGBi.red = rgb_max.red * (1.0 - nT) + nT; - pColor->spec.RGBi.green = rgb_max.green * (1.0 - nT) + nT; - pColor->spec.RGBi.blue = rgb_max.blue * (1.0 - nT) + nT; - } else { - pColor->spec.RGBi.red = rgb_max.red - (rgb_max.red * nT); - pColor->spec.RGBi.green = rgb_max.green - (rgb_max.green * nT); - pColor->spec.RGBi.blue = rgb_max.blue - (rgb_max.blue * nT); - } - pColor->format = XcmsRGBiFormat; - - /* Convert from RGBi to CIE Luv */ - if (_XcmsConvertColorsWithWhitePt(&myCCC, pColor, - ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELuvFormat, - (Bool *) NULL) == XcmsFailure) { - return (XcmsFailure); - } - chroma = XCMS_CIELUV_PMETRIC_CHROMA(pColor->spec.CIELuv.u_star, - pColor->spec.CIELuv.v_star); - tmpDist = XCMS_SQRT(((Chroma - chroma) * (Chroma - chroma)) + - ((Lstar - pColor->spec.CIELuv.L_star) * - (Lstar - pColor->spec.CIELuv.L_star))); - nILast = nI; - if (tmpDist > saveDist) { - nI /= 2; - } else { - nI = (nMaxCount + nI) / 2; + + memcpy((char *)pColor, (char *)&Luv_max, sizeof(XcmsColor)); + + /* Initialized the variables.*/ + + nMaxCountLstar = 100; + nMinCountLstar = 0; + + if (Lstar < maxLstar) { + nMaxCountLstar = maxLstar; + } + if (Lstar > maxLstar) { + nMinCountLstar = maxLstar; + } + + /* Now check and return the appropriate L* */ + + for(nCount = 0; nCount <= (nMaxCountLstar-nMinCountLstar)/EPS; nCount ++) + { + count = nCount*EPS + nMinCountLstar; + XcmsCIELuvQueryMaxC(&myCCC, degrees(hue), nCount, &tmp); + tmpLstar = tmp.spec.CIELuv.L_star; + tmpChroma = XCMS_CIELUV_PMETRIC_CHROMA(tmp.spec.CIELuv.u_star, + tmp.spec.CIELuv.v_star); + tmpDist = XCMS_SQRT(((chroma - tmpChroma) * (chroma - tmpChroma)) + + ((Lstar - tmpLstar) * (Lstar - tmpLstar))); + if (tmpDist < saveDist) + { saveDist = tmpDist; - bestLstar = pColor->spec.CIELuv.L_star; - bestustar = pColor->spec.CIELuv.u_star; - bestvstar = pColor->spec.CIELuv.v_star; - bestChroma = chroma; - } - if (nI == nILast || nI == 0) { - break; - } - } - if (bestChroma >= maxChroma) { - pColor->spec.CIELuv.L_star = maxLstar; - pColor->spec.CIELuv.u_star = Luv_max.spec.CIELuv.u_star; - pColor->spec.CIELuv.v_star = Luv_max.spec.CIELuv.v_star; - } else { - pColor->spec.CIELuv.L_star = bestLstar; - pColor->spec.CIELuv.u_star = bestustar; - pColor->spec.CIELuv.v_star = bestvstar; + memcpy((char *)pColor, (char *)&tmp, sizeof(XcmsColor)); } + } + retval = _XcmsDIConvertColors(&myCCC, pColor, ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIEXYZFormat); if (retval != XcmsFailure && pCompressed != NULL) { *(pCompressed + i) = True; } - } return(retval); } Index: xc/lib/X11/LuvMnL.c =================================================================== --- xc.orig/lib/X11/LuvMnL.c 2005-11-22 08:07:53.000000000 +0100 +++ xc/lib/X11/LuvMnL.c 2005-11-22 08:28:20.000000000 +0100 @@ -41,9 +41,9 @@ /* * DEFINES */ -#define MAXBISECTCOUNT 100 +#define MAXBISECTCOUNT 200 #define EPS (XcmsFloat)0.001 -#define START_L_STAR (XcmsFloat)40.0 +#define START_L_STAR (XcmsFloat)0.0 /*black.*/ /************************************************************************ @@ -54,7 +54,7 @@ /* * NAME - * XcmsCIELuvQueryMinL - Compute max Lstar for a hue and chroma + * XcmsCIELuvQueryMinL - Compute min Lstar for a hue and chroma * * SYNOPSIS */ @@ -66,7 +66,7 @@ XcmsColor *pColor_return; /* * DESCRIPTION - * Return the maximum Lstar for a specified hue_angle and chroma. + * Return the minumum Lstar for a specified hue_angle and chroma. * * ASSUMPTIONS * This routine assumes that the white point associated with @@ -81,11 +81,9 @@ */ { XcmsCCCRec myCCC; - XcmsColor max_lc, tmp, prev; - XcmsFloat max_chroma, tmp_chroma; - XcmsFloat hue, nT, nChroma, lastChroma, prevChroma; - XcmsFloat rFactor; - XcmsRGBi rgb_saved; + XcmsColor tmp; + XcmsFloat tmp_L_star, prev_L_star; + XcmsFloat hue, Factor; int nCount, nMaxCount; /* @@ -108,108 +106,55 @@ } hue = radians(hue_angle); - tmp.spec.CIELuv.L_star = START_L_STAR; - tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, chroma); - tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, chroma); - tmp.pixel = pColor_return->pixel; - tmp.format = XcmsCIELuvFormat; - - /* Step 1: Obtain the maximum L_star and chroma for this hue. */ - if (_XcmsCIELuvQueryMaxLCRGB(&myCCC, hue, &max_lc, &rgb_saved) - == XcmsFailure) { - return(XcmsFailure); - } - - max_chroma = XCMS_CIELUV_PMETRIC_CHROMA(max_lc.spec.CIELuv.u_star, - max_lc.spec.CIELuv.v_star); - - if (max_chroma <= chroma) { - /* - * If the chroma is greater than the chroma for the - * maximum L/chroma point then the L_star is the - * the L_star for the maximum L_star/chroma point. - * This is an error but I return the best approximation I can. - * Thus the inconsistency. - */ - memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); - return(XcmsSuccess); - } - - /* - * If the chroma is equal to the chroma for the - * maximum L_star/chroma point then the L_star is the - * the L_star for the maximum L* and chroma point. - */ - /* if (max_chroma == chroma) { - * memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); - * return(XcmsSuccess); - * } - */ - - /* must do a bisection here to compute the maximum L* */ - /* save the structure input so that any elements that */ - /* are not touched are recopied later in the routine. */ - nChroma = chroma; - tmp_chroma = max_chroma; - lastChroma = -1.0; + tmp_L_star = START_L_STAR; + prev_L_star = tmp_L_star; nMaxCount = MAXBISECTCOUNT; - rFactor = 1.0; + Factor = 10.0; for (nCount = 0; nCount < nMaxCount; nCount++) { - prevChroma = lastChroma; - lastChroma = tmp_chroma; - nT = (nChroma - max_chroma) / max_chroma * rFactor; - memcpy ((char *)&prev, (char *)&tmp, sizeof(XcmsColor)); - tmp.spec.RGBi.red = rgb_saved.red + (rgb_saved.red * nT); - tmp.spec.RGBi.green = rgb_saved.green + (rgb_saved.green * nT); - tmp.spec.RGBi.blue = rgb_saved.blue + (rgb_saved.blue * nT); - tmp.format = XcmsRGBiFormat; - - /* convert from RGB to CIELuv */ - if (_XcmsConvertColorsWithWhitePt(&myCCC, &tmp, - ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELuvFormat, - (Bool *) NULL) == XcmsFailure) { - return(XcmsFailure); - } - /* Now check the return against what is expected */ - tmp_chroma = XCMS_CIELUV_PMETRIC_CHROMA(tmp.spec.CIELuv.u_star, - tmp.spec.CIELuv.v_star); - if (tmp_chroma <= chroma + EPS && tmp_chroma >= chroma - EPS) { - /* Found It! */ - memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); - return(XcmsSuccess); + tmp.spec.CIELuv.L_star = tmp_L_star; + tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, chroma); + tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, chroma); + tmp.format = XcmsCIELuvFormat; + + /* convert from CIELuv to RGBi */ + _XcmsConvertColorsWithWhitePt(&myCCC, &tmp, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsRGBiFormat, + (Bool *) NULL); + if ((tmp.spec.RGBi.red >= 0.0) & (tmp.spec.RGBi.green >= 0.0) & + (tmp.spec.RGBi.blue >= 0.0) & (tmp.spec.RGBi.red <= 1.0) & + (tmp.spec.RGBi.green <= 1.0) & (tmp.spec.RGBi.blue <= 1.0)) + { + tmp_L_star = prev_L_star; + Factor = Factor/10.0; } - nChroma += chroma - tmp_chroma; - if (nChroma > max_chroma) { - nChroma = max_chroma; - rFactor *= 0.5; /* selective relaxation employed */ - } else if (nChroma < 0.0) { - if (XCMS_FABS(lastChroma - chroma) < - XCMS_FABS(tmp_chroma - chroma)) { - memcpy ((char *)pColor_return, (char *)&prev, - sizeof(XcmsColor)); - } else { - memcpy ((char *)pColor_return, (char *)&tmp, - sizeof(XcmsColor)); - } - return(XcmsSuccess); - } else if (tmp_chroma <= prevChroma + EPS && - tmp_chroma >= prevChroma - EPS) { - rFactor *= 0.5; /* selective relaxation employed */ + if (Factor <= EPS) { + /* Found It! */ + tmp.spec.CIELuv.L_star = tmp_L_star; + tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, chroma); + tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, chroma); + tmp.format = XcmsCIELuvFormat; + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); } - } + prev_L_star = tmp_L_star; + tmp_L_star = tmp_L_star + Factor; - if (nCount >= nMaxCount) { - if (XCMS_FABS(lastChroma - chroma) < - XCMS_FABS(tmp_chroma - chroma)) { - memcpy ((char *)pColor_return, (char *)&prev, - sizeof(XcmsColor)); - } else { - memcpy ((char *)pColor_return, (char *)&tmp, - sizeof(XcmsColor)); + if (tmp_L_star >= 100.0) + { + XcmsCIELuvQueryMaxLC(&myCCC, hue_angle, pColor_return); + return(XcmsSuccess); } - } - memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); - return(XcmsSuccess); +} + +if (nCount >= nMaxCount) { + tmp.spec.CIELuv.L_star = prev_L_star; + tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, chroma); + tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, chroma); + tmp.format = XcmsCIELuvFormat; + memcpy ((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); +} + +return(XcmsSuccess); } Index: xc/lib/X11/LuvMxC.c =================================================================== --- xc.orig/lib/X11/LuvMxC.c 2005-11-22 08:07:53.000000000 +0100 +++ xc/lib/X11/LuvMxC.c 2005-11-22 08:29:21.000000000 +0100 @@ -43,10 +43,9 @@ /* * DEFINES */ -#define MAXBISECTCOUNT 100 +#define MAXBISECTCOUNT 200 #define EPS (XcmsFloat)0.001 -#define START_CHROMA (XcmsFloat)2.2 -#define TOPL (XcmsFloat)100.0 +#define START_CHROMA (XcmsFloat)0.0 /************************************************************************ @@ -86,11 +85,9 @@ */ { XcmsCCCRec myCCC; - XcmsColor tmp; - XcmsColor max_lc; - XcmsFloat n_L_star, last_L_star, prev_L_star; - XcmsFloat hue, lastuStar, lastvStar, /*lastChroma,*/ maxDist, nT, rFactor; - XcmsRGBi rgb_saved; + XcmsColor tmp; + XcmsFloat tmp_chroma, prev_chroma; + XcmsFloat hue, Factor; int nCount, nMaxCount; /* @@ -100,7 +97,7 @@ return(XcmsFailure); } - /* Use my own CCC and inherit screen white Pt */ + /* Use my own CCC and inherit screen white Pt */ memcpy ((char *)&myCCC, (char *)ccc, sizeof(XcmsCCCRec)); myCCC.clientWhitePt.format = XcmsUndefinedFormat; myCCC.gamutCompProc = (XcmsCompressionProc)NULL;/* no gamut comp func */ @@ -113,91 +110,62 @@ } hue = radians(hue_angle); - tmp.spec.CIELuv.L_star = L_star; - tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, START_CHROMA); - tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, START_CHROMA); - tmp.pixel = pColor_return->pixel; - tmp.format = XcmsCIELuvFormat; - - /* Step 1: compute the maximum L_star and chroma for this hue. */ - memcpy((char *)&max_lc, (char *)&tmp, sizeof(XcmsColor)); - if (_XcmsCIELuvQueryMaxLCRGB(&myCCC, hue, &max_lc, &rgb_saved) - == XcmsFailure) { - return(XcmsFailure); - } - - /* - * Step 2: Do a bisection here to compute the maximum chroma - * Note the differences between when the point to be found - * is above the maximum LC point and when it is below. - */ - if (L_star <= max_lc.spec.CIELuv.L_star) { - maxDist = max_lc.spec.CIELuv.L_star; - } else { - maxDist = TOPL - max_lc.spec.CIELuv.L_star; - } - - n_L_star = L_star; - last_L_star = -1.0; + tmp_chroma = START_CHROMA; + prev_chroma = tmp_chroma; nMaxCount = MAXBISECTCOUNT; - rFactor = 1.0; + Factor = 10.0; - for (nCount = 0; nCount < nMaxCount; nCount++) { - prev_L_star = last_L_star; - last_L_star = tmp.spec.CIELuv.L_star; -/* lastChroma = XCMS_CIELUV_PMETRIC_CHROMA(tmp.spec.CIELuv.u_star, */ -/* tmp.spec.CIELuv.v_star); */ - lastuStar = tmp.spec.CIELuv.u_star; - lastvStar = tmp.spec.CIELuv.v_star; - nT = (n_L_star - max_lc.spec.CIELuv.L_star) / maxDist * rFactor; - /* printf("(n_L_star, nT) = %lf %lf ", n_L_star, nT); */ - if (nT > 0) { - tmp.spec.RGBi.red = rgb_saved.red * (1.0 - nT) + nT; - tmp.spec.RGBi.green = rgb_saved.green * (1.0 - nT) + nT; - tmp.spec.RGBi.blue = rgb_saved.blue * (1.0 - nT) + nT; - } else { - tmp.spec.RGBi.red = rgb_saved.red + (rgb_saved.red * nT); - tmp.spec.RGBi.green = rgb_saved.green + (rgb_saved.green * nT); - tmp.spec.RGBi.blue = rgb_saved.blue + (rgb_saved.blue * nT); - } - tmp.format = XcmsRGBiFormat; + for (nCount = 0; nCount < nMaxCount; nCount++) + { - /* convert from RGB to CIELuv */ - if (_XcmsConvertColorsWithWhitePt(&myCCC, &tmp, - ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELuvFormat, - (Bool *) NULL) == XcmsFailure) { - return(XcmsFailure); - } - - /* - * Now check if we've reached the target L_star - */ - /* printf("result Lstar = %lf\n", tmp.spec.CIELuv.L_star); */ - if (tmp.spec.CIELuv.L_star <= L_star + EPS && - tmp.spec.CIELuv.L_star >= L_star - EPS) { + tmp.spec.CIELuv.L_star = L_star; + tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, tmp_chroma); + tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, tmp_chroma); + tmp.format = XcmsCIELuvFormat; + + if (((L_star == 0.0) & (tmp_chroma == 0.0)) | + ((L_star == 100.0) & (tmp_chroma == 0.0))) + { + tmp.spec.CIELuv.L_star = L_star; + tmp.spec.CIELuv.u_star = 0.0; + tmp.spec.CIELuv.v_star = 0.0; + tmp.format = XcmsCIELuvFormat; memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); return(XcmsSuccess); } - if (nT > 0) { - n_L_star += ((TOPL - n_L_star) * - (L_star - tmp.spec.CIELuv.L_star)) / (TOPL - L_star); - } else { - n_L_star *= L_star / tmp.spec.CIELuv.L_star; + + /* convert from CIELuv to RGBi. */ + _XcmsConvertColorsWithWhitePt(&myCCC, &tmp, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsRGBiFormat, + (Bool *) NULL); + + if ((tmp.spec.RGBi.red < 0.0) | (tmp.spec.RGBi.green < 0.0) | + (tmp.spec.RGBi.blue < 0.0) | (tmp.spec.RGBi.red > 1.0) | + (tmp.spec.RGBi.green > 1.0) | (tmp.spec.RGBi.blue > 1.0)) + { + tmp_chroma = prev_chroma; + Factor = Factor/10.0; } - if (tmp.spec.CIELuv.L_star <= prev_L_star + EPS && - tmp.spec.CIELuv.L_star >= prev_L_star - EPS) { - rFactor *= 0.5; /* selective relaxation employed */ - /* printf("rFactor = %lf\n", rFactor); */ + if (Factor <= EPS) + { + tmp.spec.CIELuv.L_star = L_star; + tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, tmp_chroma); + tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, tmp_chroma); + tmp.format = XcmsCIELuvFormat; + memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); + return(XcmsSuccess); } + prev_chroma = tmp_chroma; + tmp_chroma = tmp_chroma + Factor; } - if (XCMS_FABS(last_L_star - L_star) < - XCMS_FABS(tmp.spec.CIELuv.L_star - L_star)) { - tmp.spec.CIELuv.u_star = lastuStar; - tmp.spec.CIELuv.v_star = lastvStar; -/* tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, lastChroma); */ -/* tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, lastChroma); */ + + if (nCount >= nMaxCount) + { + tmp.spec.CIELuv.L_star = L_star; + tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, prev_chroma); + tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, prev_chroma); + tmp.format = XcmsCIELuvFormat; + memcpy ((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); } - tmp.spec.CIELuv.L_star = L_star; - memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); - return(XcmsSuccess); +return(XcmsSuccess); } Index: xc/lib/X11/LuvMxL.c =================================================================== --- xc.orig/lib/X11/LuvMxL.c 2005-11-22 08:07:53.000000000 +0100 +++ xc/lib/X11/LuvMxL.c 2005-11-22 08:30:29.000000000 +0100 @@ -41,9 +41,9 @@ /* * DEFINES */ -#define MAXBISECTCOUNT 100 +#define MAXBISECTCOUNT 200 #define EPS (XcmsFloat)0.001 -#define START_L_STAR (XcmsFloat)40.0 +#define START_L_STAR (XcmsFloat)100.0 /*white.*/ /************************************************************************ @@ -54,7 +54,7 @@ /* * NAME - * XcmsCIELuvQueryMaxL - Compute max Lstar for a hue and chroma + * XcmsCIELuvQueryMaxL - Compute min Lstar for a hue and chroma * * SYNOPSIS */ @@ -81,11 +81,9 @@ */ { XcmsCCCRec myCCC; - XcmsColor max_lc, tmp, prev; - XcmsFloat max_chroma, tmp_chroma; - XcmsFloat hue, nT, nChroma, lastChroma, prevChroma; - XcmsFloat rFactor; - XcmsRGBi rgb_saved; + XcmsColor tmp; + XcmsFloat tmp_L_star, prev_L_star; + XcmsFloat hue, Factor; int nCount, nMaxCount; /* @@ -108,108 +106,55 @@ } hue = radians(hue_angle); - tmp.spec.CIELuv.L_star = START_L_STAR; - tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, chroma); - tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, chroma); - tmp.pixel = pColor_return->pixel; - tmp.format = XcmsCIELuvFormat; - - /* Step 1: Obtain the maximum L_star and chroma for this hue. */ - if (_XcmsCIELuvQueryMaxLCRGB(&myCCC, hue, &max_lc, &rgb_saved) - == XcmsFailure) { - return(XcmsFailure); - } - - max_chroma = XCMS_CIELUV_PMETRIC_CHROMA(max_lc.spec.CIELuv.u_star, - max_lc.spec.CIELuv.v_star); - - if (max_chroma <= chroma) { - /* - * If the chroma is greater than the chroma for the - * maximum L/chroma point then the L_star is the - * the L_star for the maximum L_star/chroma point. - * This is an error but I return the best approximation I can. - * Thus the inconsistency. - */ - memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); - return(XcmsSuccess); - } - - /* - * If the chroma is equal to the chroma for the - * maximum L_star/chroma point then the L_star is the - * the L_star for the maximum L* and chroma point. - */ - /* if (max_chroma == chroma) { - * memcpy ((char *) pColor_return, (char *) &max_lc, sizeof (XcmsColor)); - * return(XcmsSuccess); - * } - */ - - /* must do a bisection here to compute the maximum L* */ - /* save the structure input so that any elements that */ - /* are not touched are recopied later in the routine. */ - nChroma = chroma; - tmp_chroma = max_chroma; - lastChroma = -1.0; + tmp_L_star = START_L_STAR; + prev_L_star = tmp_L_star; nMaxCount = MAXBISECTCOUNT; - rFactor = 1.0; + Factor = 10.0; for (nCount = 0; nCount < nMaxCount; nCount++) { - prevChroma = lastChroma; - lastChroma = tmp_chroma; - nT = (1.0 - (nChroma / max_chroma)) * rFactor; - memcpy ((char *)&prev, (char *)&tmp, sizeof(XcmsColor)); - tmp.spec.RGBi.red = rgb_saved.red * (1.0 - nT) + nT; - tmp.spec.RGBi.green = rgb_saved.green * (1.0 - nT) + nT; - tmp.spec.RGBi.blue = rgb_saved.blue * (1.0 - nT) + nT; - tmp.format = XcmsRGBiFormat; - - /* convert from RGB to CIELuv */ - if (_XcmsConvertColorsWithWhitePt(&myCCC, &tmp, - ScreenWhitePointOfCCC(&myCCC), 1, XcmsCIELuvFormat, - (Bool *) NULL) == XcmsFailure) { - return(XcmsFailure); - } - /* Now check the return against what is expected */ - tmp_chroma = XCMS_CIELUV_PMETRIC_CHROMA(tmp.spec.CIELuv.u_star, - tmp.spec.CIELuv.v_star); - if (tmp_chroma <= chroma + EPS && tmp_chroma >= chroma - EPS) { - /* Found It! */ - memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); - return(XcmsSuccess); + tmp.spec.CIELuv.L_star = tmp_L_star; + tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, chroma); + tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, chroma); + tmp.format = XcmsCIELuvFormat; + + /* convert from CIELuv to RGBi */ + _XcmsConvertColorsWithWhitePt(&myCCC, &tmp, + ScreenWhitePointOfCCC(&myCCC), 1, XcmsRGBiFormat, + (Bool *) NULL); + if ((tmp.spec.RGBi.red >= 0.0) & (tmp.spec.RGBi.green >= 0.0) & + (tmp.spec.RGBi.blue >= 0.0) & (tmp.spec.RGBi.red <= 1.0) & + (tmp.spec.RGBi.green <= 1.0) & (tmp.spec.RGBi.blue <= 1.0)) + { + tmp_L_star = prev_L_star; + Factor = Factor/10.0; } - nChroma += chroma - tmp_chroma; - if (nChroma > max_chroma) { - nChroma = max_chroma; - rFactor *= 0.5; /* selective relaxation employed */ - } else if (nChroma < 0.0) { - if (XCMS_FABS(lastChroma - chroma) < - XCMS_FABS(tmp_chroma - chroma)) { - memcpy ((char *)pColor_return, (char *)&prev, - sizeof(XcmsColor)); - } else { - memcpy ((char *)pColor_return, (char *)&tmp, - sizeof(XcmsColor)); - } - return(XcmsSuccess); - } else if (tmp_chroma <= prevChroma + EPS && - tmp_chroma >= prevChroma - EPS) { - rFactor *= 0.5; /* selective relaxation employed */ + if (Factor <= EPS) { + /* Found It! */ + tmp.spec.CIELuv.L_star = tmp_L_star; + tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, chroma); + tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, chroma); + tmp.format = XcmsCIELuvFormat; + memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); + return(XcmsSuccess); } - } + prev_L_star = tmp_L_star; + tmp_L_star = tmp_L_star - Factor; - if (nCount >= nMaxCount) { - if (XCMS_FABS(lastChroma - chroma) < - XCMS_FABS(tmp_chroma - chroma)) { - memcpy ((char *)pColor_return, (char *)&prev, - sizeof(XcmsColor)); - } else { - memcpy ((char *)pColor_return, (char *)&tmp, - sizeof(XcmsColor)); + if (tmp_L_star <= 0.0) + { + XcmsCIELuvQueryMaxLC(&myCCC, hue_angle, pColor_return); + return(XcmsSuccess); } - } - memcpy ((char *) pColor_return, (char *) &tmp, sizeof (XcmsColor)); - return(XcmsSuccess); +} + +if (nCount >= nMaxCount) { + tmp.spec.CIELuv.L_star = prev_L_star; + tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, chroma); + tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, chroma); + tmp.format = XcmsCIELuvFormat; + memcpy ((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); + } + +return(XcmsSuccess); } Index: xc/lib/X11/LuvMxLC.c =================================================================== --- xc.orig/lib/X11/LuvMxLC.c 2005-11-22 08:07:53.000000000 +0100 +++ xc/lib/X11/LuvMxLC.c 2005-11-22 08:31:36.000000000 +0100 @@ -52,108 +52,11 @@ #define MAX(x,y) ((x) > (y) ? (x) : (y)) #define MAX3(x,y,z) ((x) > (MAX((y), (z))) ? (x) : (MAX((y), (z)))) #define START_LSTAR (XcmsFloat)40.0 -#define START_CHROMA (XcmsFloat)2.2 - - -/************************************************************************ - * * - * API PRIVATE ROUTINES * - * * - ************************************************************************/ - -/* - * NAME - * _XcmsCIELuvQueryMaxLCRGB - Compute maximum L* and chroma. - * - * SYNOPSIS - */ -Status -_XcmsCIELuvQueryMaxLCRGB( - XcmsCCC ccc, - XcmsFloat hue, /* hue in radians */ - XcmsColor *pColor_return, - XcmsRGBi *pRGB_return) -/* - * DESCRIPTION - * Return the maximum psychometric chroma for a specified - * hue angle(radians), and the corresponding L*. This is computed - * by a binary search of all possible chromas. An assumption - * is made that there are no local maxima. Use the unrounded - * Max psychometric chroma because the difference check can be - * small. - * - * NOTE: No local CCC is used because this is a private - * routine and all routines that call it are expected - * to behave properly, i.e. send a local CCC with - * no white adjust function and no gamut compression - * function. - * - * This routine only accepts hue as input and outputs - * Luv and RGBi. - * - * RETURNS - * XcmsFailure - Failure - * XcmsSuccess - Succeeded - * - */ -{ - XcmsFloat nSmall, nLarge; - XcmsColor tmp; - - tmp.format = XcmsCIELuvFormat; - /* Use some unreachable color on the given hue angle */ - tmp.spec.CIELuv.L_star = START_LSTAR; - tmp.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, START_CHROMA); - tmp.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, START_CHROMA); - /* - * Convert from Luv to RGB - * - * Note that the CIEXYZ to RGBi conversion routine must stuff the - * out of bounds RGBi values in tmp when the ccc->gamutCompProc - * is NULL. - */ - if ((_XcmsConvertColorsWithWhitePt(ccc, &tmp, ScreenWhitePointOfCCC(ccc), - (unsigned int)1, XcmsRGBiFormat, (Bool *) NULL) - == XcmsFailure) && tmp.format != XcmsRGBiFormat) { - return (XcmsFailure); - } - - /* Now pick the smallest RGB */ - nSmall = MIN3(tmp.spec.RGBi.red, - tmp.spec.RGBi.green, - tmp.spec.RGBi.blue); - /* Make the smallest RGB equal to zero */ - tmp.spec.RGBi.red -= nSmall; - tmp.spec.RGBi.green -= nSmall; - tmp.spec.RGBi.blue -= nSmall; - - /* Now pick the largest RGB */ - nLarge = MAX3(tmp.spec.RGBi.red, - tmp.spec.RGBi.green, - tmp.spec.RGBi.blue); - /* Scale the RGB values based on the largest one */ - tmp.spec.RGBi.red /= nLarge; - tmp.spec.RGBi.green /= nLarge; - tmp.spec.RGBi.blue /= nLarge; - tmp.format = XcmsRGBiFormat; - - /* If the calling routine wants RGB value give them the ones used. */ - if (pRGB_return) { - pRGB_return->red = tmp.spec.RGBi.red; - pRGB_return->green = tmp.spec.RGBi.green; - pRGB_return->blue = tmp.spec.RGBi.blue; - } - - /* Convert from RGBi to Luv */ - if (_XcmsConvertColorsWithWhitePt(ccc, &tmp, - ScreenWhitePointOfCCC(ccc), 1, XcmsCIELuvFormat, (Bool *) NULL) - == XcmsFailure) { - return (XcmsFailure); - } - - memcpy((char *)pColor_return, (char *)&tmp, sizeof(XcmsColor)); - return (XcmsSuccess); -} +#define START_CHROMA (XcmsFloat)3.6 +#define START_LSTAR2 (XcmsFloat)0.0 +#define START_CHROMA2 (XcmsFloat)0.0 +#define MAXBISECTCOUNT 200 +#define EPS (XcmsFloat)0.001 /************************************************************************ @@ -192,6 +95,11 @@ */ { XcmsCCCRec myCCC; + XcmsFloat tmp_chroma, prev1_chroma, prev2_chroma; + XcmsFloat tmp_L_star, prev1_L_star, prev2_L_star; + XcmsFloat hue, Factor; + XcmsColor tmp_color; + int nCount, nMaxCount; /* * Check Arguments @@ -211,7 +119,56 @@ while (hue_angle >= 360.0) { hue_angle -= 360.0; } + hue = radians(hue_angle); + tmp_L_star = START_LSTAR2; + prev1_L_star = tmp_L_star; + prev2_L_star = prev1_L_star; + tmp_chroma = START_CHROMA2; + prev1_chroma = tmp_chroma; + prev2_chroma = prev1_chroma; + nMaxCount = MAXBISECTCOUNT; + Factor = 10.0; + + for (nCount = 0; nCount < nMaxCount; nCount++) { - return(_XcmsCIELuvQueryMaxLCRGB (&myCCC, radians(hue_angle), pColor_return, - (XcmsRGBi *)NULL)); + XcmsCIELuvQueryMaxC(&myCCC, hue_angle, tmp_L_star, &tmp_color); + + prev2_chroma = prev1_chroma; + prev1_chroma = tmp_chroma; + tmp_chroma = XCMS_CIELUV_PMETRIC_CHROMA(tmp_color.spec.CIELuv.u_star, + tmp_color.spec.CIELuv.v_star); + if (tmp_chroma <= prev1_chroma) + { + tmp_chroma = prev2_chroma; + prev1_chroma = prev2_chroma; + tmp_L_star = prev2_L_star; + prev1_L_star = prev2_L_star; + Factor = Factor/10.0; + + if (Factor <= EPS) + { + tmp_color.spec.CIELuv.L_star = tmp_L_star; + tmp_color.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, tmp_chroma); + tmp_color.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, tmp_chroma); + tmp_color.format = XcmsCIELuvFormat; + memcpy ((char *)pColor_return, (char *)&tmp_color, sizeof(XcmsColor)); + return(XcmsSuccess); + } + } + prev2_L_star = prev1_L_star; + prev1_L_star = tmp_L_star; + tmp_L_star = tmp_L_star + Factor; + if (tmp_L_star >= 100.0) {tmp_L_star = 100.0;} + } + +if (nCount >= nMaxCount) { + tmp_color.spec.CIELuv.L_star = prev1_L_star; + tmp_color.spec.CIELuv.u_star = XCMS_CIEUSTAROFHUE(hue, prev1_chroma); + tmp_color.spec.CIELuv.v_star = XCMS_CIEVSTAROFHUE(hue, prev1_chroma); + tmp_color.format = XcmsCIELuvFormat; + memcpy ((char *)pColor_return, (char *)&tmp_color, sizeof(XcmsColor)); } + +return(XcmsSuccess); +} +