/* * NAME * XcmsFormatOfPrefix * * SYNOPSIS */ XcmsColorFormat XcmsFormatOfPrefix(char *prefix) /* * DESCRIPTION * Returns the Color Space ID for the specified prefix * if the color space is found in the Color Conversion * Context. * * RETURNS * Color Space ID if found; zero otherwise. */ { XcmsColorSpace **papColorSpaces; char string_buf[64]; char *string_lowered; int len; /* * While copying prefix to string_lowered, convert to lowercase */ if ((len = strlen(prefix)) >= sizeof(string_buf)) { string_lowered = (char *) Xmalloc(len+1); } else { string_lowered = string_buf; } _XcmsCopyISOLatin1Lowered(string_lowered, prefix); /* * First try Device-Independent color spaces */ papColorSpaces = _XcmsDIColorSpaces; if (papColorSpaces != NULL) { while (*papColorSpaces != NULL) { if (strcmp((*papColorSpaces)->prefix, string_lowered) == 0) { if (len >= sizeof(string_buf)) Xfree(string_lowered); return((*papColorSpaces)->id); } papColorSpaces++; } } /* * Next try Device-Dependent color spaces */ papColorSpaces = _XcmsDDColorSpaces; if (papColorSpaces != NULL) { while (*papColorSpaces != NULL) { if (strcmp((*papColorSpaces)->prefix, string_lowered) == 0) { if (len >= sizeof(string_buf)) Xfree(string_lowered); return((*papColorSpaces)->id); } papColorSpaces++; } } if (len >= sizeof(string_buf)) Xfree(string_lowered); return(XcmsUndefinedFormat); }
/* * NAME * _XcmsParseColorString * * SYNOPSIS */ static int _XcmsParseColorString( XcmsCCC ccc, const char *color_string, XcmsColor *pColor) /* * DESCRIPTION * Assuming color_string contains a numerical string color * specification, attempts to parse a string into an * XcmsColor structure. * * RETURNS * 0 if failed; otherwise non-zero. * * CAVEATS * A color string containing a numerical color specification * must be in ISO Latin-1 encoding! */ { XcmsColorSpace *pColorSpace; char string_buf[64]; char *string_lowered; int len; int res; if (ccc == NULL) { return(0); } /* * While copying color_string to string_lowered, convert to lowercase */ if ((len = strlen(color_string)) >= sizeof(string_buf)) { string_lowered = Xmalloc(len+1); } else { string_lowered = string_buf; } _XcmsCopyISOLatin1Lowered(string_lowered, color_string); if (*string_lowered == '#') { if ((pColorSpace = _XcmsColorSpaceOfString(ccc, "rgb:")) != NULL) { res = (*pColorSpace->parseString)(string_lowered, pColor); if (len >= sizeof(string_buf)) Xfree(string_lowered); return res; } } if ((pColorSpace = _XcmsColorSpaceOfString(ccc, string_lowered)) != NULL) { res = (*pColorSpace->parseString)(string_lowered, pColor); if (len >= sizeof(string_buf)) Xfree(string_lowered); return res; } if (len >= sizeof(string_buf)) Xfree(string_lowered); return(0); }
/* * NAME * ReadColornameDB - Read the Color Name Database * * SYNOPSIS */ static Status ReadColornameDB( FILE *stream, XcmsPair *pRec, char *pString) /* * DESCRIPTION * Loads the Color Name Database from a text file. * * RETURNS * XcmsSuccess if succeeded, otherwise XcmsFailure. * */ { char buf[XCMSDB_MAXLINELEN]; char token[XCMSDB_MAXLINELEN]; char token2[XCMSDB_MAXLINELEN]; char *f1; char *f2; char *pBuf; /* * Advance to START_TOKEN * Anything before is just considered as comments. */ while((pBuf = fgets(buf, XCMSDB_MAXLINELEN, stream)) != NULL) { if ((sscanf(buf, "%s %s", token, token2)) && (strcmp(token, START_TOKEN) == 0)) { if (strcmp(token2, FORMAT_VERSION) != 0) { /* text file not in the right format */ return(XcmsFailure); } break; } /* else it was just a blank line or comment */ } if (pBuf == NULL) { return(XcmsFailure); } /* * Process lines between START_TOKEN to END_TOKEN */ while ((fgets(buf, XCMSDB_MAXLINELEN, stream)) != NULL) { if ((sscanf(buf, "%s", token)) && (strcmp(token, END_TOKEN) == 0)) { /* * Found END_TOKEN so break out of for loop */ break; } /* * Get pairs */ if (field2(buf, DELIM_CHAR, &f1, &f2) != XcmsSuccess) { /* Invalid line */ continue; } /* * Add strings */ /* Left String */ pRec->first = pString; _XcmsCopyISOLatin1Lowered(pString, f1); pString += (1 + RemoveSpaces(pString)); pRec->second = pString; /* Right String */ _XcmsCopyISOLatin1Lowered(pString, f2); pString += RemoveSpaces(pString) + 1; pRec++; } return(XcmsSuccess); }
/* * NAME * _XcmsLookupColorName - Lookup DB entry for a color name * * SYNOPSIS */ static Status _XcmsLookupColorName( XcmsCCC ccc, const char **name, XcmsColor *pColor) /* * DESCRIPTION * Searches for an entry in the Device-Independent Color Name * Database for the specified string. * * RETURNS * XcmsFailure if failed to find a matching entry in * the database. * XcmsSuccess if succeeded in converting color name to * XcmsColor. * _XCMS_NEWNAME if succeeded in converting color string (which * is a color name to yet another color name. Note * that the new name is passed back via 'name'. */ { Status retval = 0; char name_lowered_64[64]; char *name_lowered; register int i, j, left, right; int len; const char *tmpName; XcmsPair *pair = NULL; /* * Check state of Database: * XcmsDbInitNone * XcmsDbInitSuccess * XcmsDbInitFailure */ if (XcmsColorDbState == XcmsDbInitFailure) { return(XcmsFailure); } if (XcmsColorDbState == XcmsDbInitNone) { if (!LoadColornameDB()) { return(XcmsFailure); } } SetNoVisit(); /* * While copying name to name_lowered, convert to lowercase */ tmpName = *name; Retry: if ((len = strlen(tmpName)) > 63) { name_lowered = Xmalloc(len+1); } else { name_lowered = name_lowered_64; } _XcmsCopyISOLatin1Lowered(name_lowered, tmpName); /* * Now, remove spaces. */ for (i = 0, j = 0; j < len; j++) { if (!isspace(name_lowered[j])) { name_lowered[i++] = name_lowered[j]; } } name_lowered[i] = '\0'; left = 0; right = nEntries - 1; while (left <= right) { i = (left + right) >> 1; pair = &pairs[i]; j = strcmp(name_lowered, pair->first); if (j < 0) right = i - 1; else if (j > 0) left = i + 1; else { break; } } if (len > 63) Xfree(name_lowered); if (left > right) { if (retval == 2) { if (*name != tmpName) { *name = tmpName; } return(_XCMS_NEWNAME); } return(XcmsFailure); } if (pair->flag == CYCLE) { return(XcmsFailure); } if (pair->flag == VISITED) { pair->flag = CYCLE; return(XcmsFailure); } if (_XcmsParseColorString(ccc, pair->second, pColor) == XcmsSuccess) { /* f2 contains a numerical string specification */ return(XcmsSuccess); } else { /* f2 does not contain a numerical string specification */ tmpName = pair->second; pair->flag = VISITED; retval = 2; goto Retry; } }