/src/rgb.c

# · C · 287 lines · 154 code · 35 blank · 98 comment · 35 complexity · 3fd48912dfcebd96a953dfb1dbd936d8 MD5 · raw file

  1. /*
  2. * Copyright (C) 1989-95 GROUPE BULL
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to
  6. * deal in the Software without restriction, including without limitation the
  7. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. * sell copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  18. * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. *
  21. * Except as contained in this notice, the name of GROUPE BULL shall not be
  22. * used in advertising or otherwise to promote the sale, use or other dealings
  23. * in this Software without prior written authorization from GROUPE BULL.
  24. */
  25. /*****************************************************************************\
  26. * rgb.c: *
  27. * *
  28. * XPM library *
  29. * Rgb file utilities *
  30. * *
  31. * Developed by Arnaud Le Hors *
  32. \*****************************************************************************/
  33. /*
  34. * The code related to FOR_MSW has been added by
  35. * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
  36. */
  37. /*
  38. * Part of this code has been taken from the ppmtoxpm.c file written by Mark
  39. * W. Snitily but has been modified for my special need
  40. */
  41. #ifdef HAVE_CONFIG_H
  42. #include <config.h>
  43. #endif
  44. #include "XpmI.h"
  45. #include <ctype.h>
  46. #ifndef FOR_MSW /* normal part first, MSW part at
  47. * the end, (huge ifdef!) */
  48. /*
  49. * Read a rgb text file. It stores the rgb values (0->65535)
  50. * and the rgb mnemonics (malloc'ed) into the "rgbn" array. Returns the
  51. * number of entries stored.
  52. */
  53. int
  54. xpmReadRgbNames(
  55. char *rgb_fname,
  56. xpmRgbName rgbn[])
  57. {
  58. FILE *rgbf;
  59. int n, items, red, green, blue;
  60. char line[512], name[512], *rgbname, *s1, *s2;
  61. xpmRgbName *rgb;
  62. /* Open the rgb text file. Abort if error. */
  63. if ((rgbf = fopen(rgb_fname, "r")) == NULL)
  64. return 0;
  65. /* Loop reading each line in the file. */
  66. n = 0;
  67. rgb = rgbn;
  68. /* Quit if rgb text file has too many entries. */
  69. while (fgets(line, sizeof(line), rgbf) && n < MAX_RGBNAMES) {
  70. /* Skip silently if line is bad. */
  71. items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name);
  72. if (items != 4)
  73. continue;
  74. /*
  75. * Make sure rgb values are within 0->255 range. Skip silently if
  76. * bad.
  77. */
  78. if (red < 0 || red > 0xFF ||
  79. green < 0 || green > 0xFF ||
  80. blue < 0 || blue > 0xFF)
  81. continue;
  82. /* Allocate memory for ascii name. If error give up here. */
  83. if (!(rgbname = (char *) XpmMalloc(strlen(name) + 1)))
  84. break;
  85. /* Copy string to ascii name and lowercase it. */
  86. for (s1 = name, s2 = rgbname; *s1; s1++)
  87. *s2++ = tolower(*s1);
  88. *s2 = '\0';
  89. /* Save the rgb values and ascii name in the array. */
  90. rgb->r = red * 257; /* 65535/255 = 257 */
  91. rgb->g = green * 257;
  92. rgb->b = blue * 257;
  93. rgb->name = rgbname;
  94. rgb++;
  95. n++;
  96. }
  97. fclose(rgbf);
  98. /* Return the number of read rgb names. */
  99. return n < 0 ? 0 : n;
  100. }
  101. /*
  102. * Return the color name corresponding to the given rgb values
  103. */
  104. char *
  105. xpmGetRgbName(
  106. xpmRgbName rgbn[], /* rgb mnemonics from rgb text file */
  107. int rgbn_max, /* number of rgb mnemonics in table */
  108. int red, /* rgb values */
  109. int green,
  110. int blue)
  111. {
  112. int i;
  113. xpmRgbName *rgb;
  114. /*
  115. * Just perform a dumb linear search over the rgb values of the color
  116. * mnemonics. One could speed things up by sorting the rgb values and
  117. * using a binary search, or building a hash table, etc...
  118. */
  119. for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
  120. if (red == rgb->r && green == rgb->g && blue == rgb->b)
  121. return rgb->name;
  122. /* if not found return NULL */
  123. return NULL;
  124. }
  125. /*
  126. * Free the strings which have been malloc'ed in xpmReadRgbNames
  127. */
  128. void
  129. xpmFreeRgbNames(
  130. xpmRgbName rgbn[],
  131. int rgbn_max)
  132. {
  133. int i;
  134. xpmRgbName *rgb;
  135. for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
  136. XpmFree(rgb->name);
  137. }
  138. #else /* here comes the MSW part, the
  139. * second part of the huge ifdef */
  140. #include "rgbtab.h" /* hard coded rgb.txt table */
  141. int
  142. xpmReadRgbNames(
  143. char *rgb_fname,
  144. xpmRgbName rgbn[])
  145. {
  146. /*
  147. * check for consistency???
  148. * table has to be sorted for calls on strcasecmp
  149. */
  150. return (numTheRGBRecords);
  151. }
  152. /*
  153. * MSW rgb values are made from 3 BYTEs, this is different from X XColor.red,
  154. * which has something like #0303 for one color
  155. */
  156. char *
  157. xpmGetRgbName(
  158. xpmRgbName rgbn[], /* rgb mnemonics from rgb text file
  159. * not used */
  160. int rgbn_max, /* not used */
  161. int red, /* rgb values */
  162. int green,
  163. int blue)
  164. {
  165. int i;
  166. unsigned long rgbVal;
  167. i = 0;
  168. while (i < numTheRGBRecords) {
  169. rgbVal = theRGBRecords[i].rgb;
  170. if (GetRValue(rgbVal) == red &&
  171. GetGValue(rgbVal) == green &&
  172. GetBValue(rgbVal) == blue)
  173. return (theRGBRecords[i].name);
  174. i++;
  175. }
  176. return (NULL);
  177. }
  178. /* used in XParseColor in simx.c */
  179. int
  180. xpmGetRGBfromName(
  181. char *inname,
  182. int *r,
  183. int *g,
  184. int *b)
  185. {
  186. int left, right, middle;
  187. int cmp;
  188. unsigned long rgbVal;
  189. char *name;
  190. char *grey, *p;
  191. name = xpmstrdup(inname);
  192. /*
  193. * the table in rgbtab.c has no names with spaces, and no grey, but a
  194. * lot of gray
  195. */
  196. /* so first extract ' ' */
  197. while (p = strchr(name, ' ')) {
  198. while (*(p)) { /* till eof of string */
  199. *p = *(p + 1); /* copy to the left */
  200. p++;
  201. }
  202. }
  203. /* fold to lower case */
  204. p = name;
  205. while (*p) {
  206. *p = tolower(*p);
  207. p++;
  208. }
  209. /*
  210. * substitute Grey with Gray, else rgbtab.h would have more than 100
  211. * 'duplicate' entries
  212. */
  213. if (grey = strstr(name, "grey"))
  214. grey[2] = 'a';
  215. /* binary search */
  216. left = 0;
  217. right = numTheRGBRecords - 1;
  218. do {
  219. middle = (left + right) / 2;
  220. cmp = xpmstrcasecmp(name, theRGBRecords[middle].name);
  221. if (cmp == 0) {
  222. rgbVal = theRGBRecords[middle].rgb;
  223. *r = GetRValue(rgbVal);
  224. *g = GetGValue(rgbVal);
  225. *b = GetBValue(rgbVal);
  226. free(name);
  227. return (1);
  228. } else if (cmp < 0) {
  229. right = middle - 1;
  230. } else { /* > 0 */
  231. left = middle + 1;
  232. }
  233. } while (left <= right);
  234. /*
  235. * I don't like to run in a ColorInvalid error and to see no pixmap at
  236. * all, so simply return a red pixel. Should be wrapped in an #ifdef
  237. * HeDu
  238. */
  239. *r = 255;
  240. *g = 0;
  241. *b = 0; /* red error pixel */
  242. free(name);
  243. return (1);
  244. }
  245. void
  246. xpmFreeRgbNames(
  247. xpmRgbName rgbn[],
  248. int rgbn_max)
  249. {
  250. /* nothing to do */
  251. }
  252. #endif /* MSW part */