📄 xcmslrgb.c
字号:
* XcmsFailure if failed. * XcmsSuccess if succeeded. * */{ unsigned int nElements; IntensityRec *pIRec; nElements = pTbl->nEntries = _XcmsGetElement(format, pChar, pCount) + 1; if (!(pIRec = pTbl->pBase = (IntensityRec *) Xcalloc (nElements, sizeof(IntensityRec)))) { return(XcmsFailure); } switch (format) { case 8: for (; nElements--; pIRec++) { /* 0xFFFF/0xFF = 0x101 */ pIRec->value = _XcmsGetElement (format, pChar, pCount) * 0x101; pIRec->intensity = _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)255.0; } break; case 16: for (; nElements--; pIRec++) { pIRec->value = _XcmsGetElement (format, pChar, pCount); pIRec->intensity = _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)65535.0; } break; case 32: for (; nElements--; pIRec++) { pIRec->value = _XcmsGetElement (format, pChar, pCount); pIRec->intensity = _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)4294967295.0; } break; default: return(XcmsFailure); } return(XcmsSuccess);}/* * NAME * _XcmsGetTableType1 * * SYNOPSIS */Status_XcmsGetTableType1(pTbl, format, pChar, pCount) IntensityTbl *pTbl; int format; char **pChar; unsigned long *pCount;/* * DESCRIPTION * * RETURNS * XcmsFailure if failed. * XcmsSuccess if succeeded. * */{ int count; unsigned int max_index; IntensityRec *pIRec; max_index = _XcmsGetElement(format, pChar, pCount); pTbl->nEntries = max_index + 1; if (!(pIRec = pTbl->pBase = (IntensityRec *) Xcalloc (max_index+1, sizeof(IntensityRec)))) { return(XcmsFailure); } switch (format) { case 8: for (count = 0; count < max_index+1; count++, pIRec++) { pIRec->value = (count * 65535) / max_index; pIRec->intensity = _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)255.0; } break; case 16: for (count = 0; count < max_index+1; count++, pIRec++) { pIRec->value = (count * 65535) / max_index; pIRec->intensity = _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)65535.0; } break; case 32: for (count = 0; count < max_index+1; count++, pIRec++) { pIRec->value = (count * 65535) / max_index; pIRec->intensity = _XcmsGetElement (format, pChar, pCount) / (XcmsFloat)4294967295.0; } break; default: return(XcmsFailure); } return(XcmsSuccess);}/* * NAME * ValueCmp * * SYNOPSIS */int_XcmsValueCmp (p1, p2) IntensityRec *p1, *p2;/* * DESCRIPTION * Compares the value component of two IntensityRec * structures. * * RETURNS * 0 if p1->value is equal to p2->value * < 0 if p1->value is less than p2->value * > 0 if p1->value is greater than p2->value * */{ return (p1->value - p2->value);}/* * NAME * IntensityCmp * * SYNOPSIS */int_XcmsIntensityCmp (p1, p2) IntensityRec *p1, *p2;/* * DESCRIPTION * Compares the intensity component of two IntensityRec * structures. * * RETURNS * 0 if equal; * < 0 if first precedes second * > 0 if first succeeds second * */{ if (p1->intensity < p2->intensity) { return (-1); } if (p1->intensity > p2->intensity) { return (XcmsSuccess); } return (XcmsFailure);}/* * NAME * ValueInterpolation * * SYNOPSIS *//* ARGSUSED */int_XcmsValueInterpolation (key, lo, hi, answer, bitsPerRGB) IntensityRec *key, *lo, *hi, *answer; int bitsPerRGB;/* * DESCRIPTION * Based on a given value, performs a linear interpolation * on the intensities between two IntensityRec structures. * Note that the bitsPerRGB parameter is ignored. * * RETURNS * Returns 0 if failed; otherwise non-zero. */{ XcmsFloat ratio; ratio = ((XcmsFloat)key->value - (XcmsFloat)lo->value) / ((XcmsFloat)hi->value - (XcmsFloat)lo->value); answer->value = key->value; answer->intensity = (hi->intensity - lo->intensity) * ratio; answer->intensity += lo->intensity; return (XcmsSuccess);}/* * NAME * IntensityInterpolation * * SYNOPSIS */int_XcmsIntensityInterpolation (key, lo, hi, answer, bitsPerRGB) IntensityRec *key, *lo, *hi, *answer; int bitsPerRGB;/* * DESCRIPTION * Based on a given intensity, performs a linear interpolation * on the values between two IntensityRec structures. * The bitsPerRGB parameter is necessary to perform rounding * to the correct number of significant bits. * * RETURNS * Returns 0 if failed; otherwise non-zero. */{ XcmsFloat ratio; long target, up, down; int shift = 16 - bitsPerRGB; int max_color = (1 << bitsPerRGB) - 1; ratio = (key->intensity - lo->intensity) / (hi->intensity - lo->intensity); answer->intensity = key->intensity; target = hi->value - lo->value; target *= ratio; target += lo->value; /* * Ok now, lets find the closest in respects to bits per RGB */ up = ((target >> shift) * 0xFFFF) / max_color; if (up < target) { down = up; up = (MIN((down >> shift) + 1, max_color) * 0xFFFF) / max_color; } else { down = (MAX((up >> shift) - 1, 0) * 0xFFFF) / max_color; } answer->value = ((up - target) < (target - down) ? up : down); answer->value &= MASK[bitsPerRGB]; return (XcmsSuccess);}/* * NAME * _XcmsTableSearch * * SYNOPSIS */int_XcmsTableSearch (key, bitsPerRGB, base, nel, nKeyPtrSize, compar, interpol, answer) char *key; int bitsPerRGB; char *base; unsigned nel; unsigned nKeyPtrSize; int (*compar)(); int (*interpol)(); char *answer;/* * DESCRIPTION * A binary search through the specificied table. * * RETURNS * Returns 0 if failed; otherwise non-zero. * */{ char *hi, *lo, *mid, *last; int result; last = hi = base + ((nel - 1) * nKeyPtrSize); mid = lo = base; /* use only the significants bits, then scale into 16 bits */ ((IntensityRec *)key)->value = ((unsigned long) (((IntensityRec *)key)->value >> (16 - bitsPerRGB)) * 0xFFFF) / ((1 << bitsPerRGB) - 1); /* Special case so that zero intensity always maps to zero value */ if ((*compar) (key,lo) == 0) { bcopy (lo, answer, nKeyPtrSize); ((IntensityRec *)answer)->value &= MASK[bitsPerRGB]; return XcmsSuccess; } while (mid != last) { last = mid; mid = lo + (((unsigned)(hi - lo) / nKeyPtrSize) / 2) * nKeyPtrSize; result = (*compar) (key, mid); if (result == 0) { bcopy(mid, answer, nKeyPtrSize); ((IntensityRec *)answer)->value &= MASK[bitsPerRGB]; return (XcmsSuccess); } else if (result < 0) { hi = mid; } else { lo = mid; } } /* * If we got to here, we didn't find a solution, so we * need to apply interpolation. */ return ((*interpol)(key, lo, hi, answer, bitsPerRGB));}/* * NAME * _XcmsMatVec - multiply a 3 x 3 by a 3 x 1 vector * * SYNOPSIS */void _XcmsMatVec(pMat, pIn, pOut) XcmsFloat *pMat, *pIn, *pOut;/* * DESCRIPTION * Multiply the passed vector by the passed matrix to return a * vector. Matrix is 3x3, vectors are of length 3. * * RETURNS * void */{ int i, j; for (i = 0; i < 3; i++) { pOut[i] = 0.0; for (j = 0; j < 3; j++) pOut[i] += *(pMat+(i*3)+j) * pIn[j]; }}/************************************************************************ * * * PUBLIC ROUTINES * * * ************************************************************************//* * NAME * XcmsLRGB_RGB_ParseString * * SYNOPSIS */intXcmsLRGB_RGB_ParseString(spec, pColor) register char *spec; XcmsColor *pColor;/* * DESCRIPTION * This routines takes a string and attempts to convert * it into a XcmsColor structure with XcmsRGBFormat. * * RETURNS * 0 if failed, non-zero otherwise. */{ register int n, i; unsigned short r, g, b; char c; char *pchar; unsigned short *pShort; /* * Check for old # format */ if (*spec == '#') { /* * Attempt to parse the value portion. */ spec++; n = strlen(spec); if (n != 3 && n != 6 && n != 9 && n != 12) { return(XcmsFailure); } n /= 3; g = b = 0; do { r = g; g = b; b = 0; for (i = n; --i >= 0; ) { c = *spec++; b <<= 4; if (c >= '0' && c <= '9') b |= c - '0'; /* assume string in lowercase else if (c >= 'A' && c <= 'F') b |= c - ('A' - 10); */ else if (c >= 'a' && c <= 'f') b |= c - ('a' - 10); else return (XcmsFailure); } } while (*spec != '\0'); /* * Succeeded ! */ n <<= 2; n = 16 - n; /* shift instead of scale, to match old broken semantics */ pColor->spec.RGB.red = r << n; pColor->spec.RGB.green = g << n; pColor->spec.RGB.blue = b << n; } else { if ((pchar = strchr(spec, ':')) == NULL) { return(XcmsFailure); } n = (int)(pchar - spec); /* * Check for proper prefix. */ if (strncmp(spec, XcmsRGB_prefix, n) != 0) { return(XcmsFailure); } /* * Attempt to parse the value portion. */ spec += (n + 1); pShort = &pColor->spec.RGB.red; for (i = 0; i < 3; i++, pShort++, spec++) { n = 0; *pShort = 0; while (*spec != '/' && *spec != '\0') { if (++n > 4) { return(XcmsFailure); } c = *spec++; *pShort <<= 4; if (c >= '0' && c <= '9') *pShort |= c - '0'; /* assume string in lowercase else if (c >= 'A' && c <= 'F') *pShort |= c - ('A' - 10); */ else if (c >= 'a' && c <= 'f') *pShort |= c - ('a' - 10); else return (XcmsFailure); } if (n < 4) { *pShort = ((unsigned long)*pShort * 0xFFFF) / ((1 << n*4) - 1); } } } pColor->format = XcmsRGBFormat;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -