color_read.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. /**********************************************************************
  2. *
  3. * G_read_colors (name, mapset, colors)
  4. * char *name name of map
  5. * char *mapset mapset that map belongs to
  6. * struct Colors *colors structure to hold color info
  7. *
  8. * Reads the color information associated with map layer "map"
  9. * in mapset "mapset" into the structure "colors".
  10. *
  11. * returns: 1 if successful
  12. * 0 if missing, but default colors generated
  13. * -1 on fail
  14. *
  15. * note: If a secondary color file for map name "name" exists
  16. * in the current project, that color file is read. This
  17. * allows the user to define their own color lookup tables
  18. * for cell maps found in other mapsets.
  19. *
  20. * Warning message is printed if the color file is
  21. * missing or invalid.
  22. *********************************************************************/
  23. #include <grass/gis.h>
  24. #include <grass/glocale.h>
  25. #include <string.h>
  26. static int read_colors(const char *, const char *, const char *,
  27. struct Colors *);
  28. static int read_new_colors(FILE *, struct Colors *);
  29. static int read_old_colors(FILE *, struct Colors *);
  30. /*!
  31. * \brief read map layer color table
  32. *
  33. * The color table for the raster map
  34. * <b>name</b> in the specified <b>mapset</b> is read into the
  35. * <b>colors</b> structure.
  36. * If the data layer has no color table, a default color table is generated and
  37. * 0 is returned. If there is an error reading the color table, a diagnostic
  38. * message is printed and -1 is returned. If the color table is read ok, 1 is
  39. * returned.
  40. *
  41. * \param name
  42. * \param mapset
  43. * \param colors
  44. * \return int
  45. */
  46. /*!
  47. * \brief
  48. *
  49. * This routine reads the rules from the color
  50. * file. If the input raster map is is a floating-point map it calls <tt>G_mark_colors_as_fp()</tt>.
  51. *
  52. * \return int
  53. */
  54. int G_read_colors(const char *name, const char *mapset, struct Colors *colors)
  55. {
  56. int fp;
  57. char buf[GNAME_MAX];
  58. char *err;
  59. char xname[GNAME_MAX], xmapset[GMAPSET_MAX];
  60. struct Range range;
  61. struct FPRange drange;
  62. CELL min, max;
  63. DCELL dmin, dmax;
  64. fp = G_raster_map_is_fp(name, mapset);
  65. G_init_colors(colors);
  66. if (G__name_is_fully_qualified(name, xname, xmapset)) {
  67. if (strcmp(xmapset, mapset) != 0)
  68. return -1;
  69. name = xname;
  70. }
  71. if (fp)
  72. G_mark_colors_as_fp(colors);
  73. /* first look for secondary color table in current mapset */
  74. sprintf(buf, "colr2/%s", mapset);
  75. if (read_colors(buf, name, G_mapset(), colors) >= 0)
  76. return 1;
  77. /* now look for the regular color table */
  78. switch (read_colors("colr", name, mapset, colors)) {
  79. case -2:
  80. if (!fp) {
  81. if (G_read_range(name, mapset, &range) >= 0) {
  82. G_get_range_min_max(&range, &min, &max);
  83. if (!G_is_c_null_value(&min) && !G_is_c_null_value(&max))
  84. G_make_rainbow_colors(colors, min, max);
  85. return 0;
  86. }
  87. }
  88. else {
  89. if (G_read_fp_range(name, mapset, &drange) >= 0) {
  90. G_get_fp_range_min_max(&drange, &dmin, &dmax);
  91. if (!G_is_d_null_value(&dmin) && !G_is_d_null_value(&dmax))
  92. G_make_rainbow_fp_colors(colors, dmin, dmax);
  93. return 0;
  94. }
  95. }
  96. err = "missing";
  97. break;
  98. case -1:
  99. err = "invalid";
  100. break;
  101. default:
  102. return 1;
  103. }
  104. sprintf(buf, _("color support for [%s] in mapset [%s] %s"), name, mapset,
  105. err);
  106. G_warning(buf);
  107. return -1;
  108. }
  109. static int read_colors(const char *element, const char *name,
  110. const char *mapset, struct Colors *colors)
  111. {
  112. FILE *fd;
  113. int stat;
  114. char buf[1024];
  115. if (!(fd = G_fopen_old(element, name, mapset)))
  116. return -2;
  117. /*
  118. * first line in 4.0 color files is %
  119. * otherwise it is pre 4.0
  120. */
  121. if (fgets(buf, sizeof buf, fd) == NULL) {
  122. fclose(fd);
  123. return -1;
  124. }
  125. fseek(fd, 0L, 0);
  126. G_strip(buf);
  127. if (*buf == '%') { /* 4.0 format */
  128. stat = read_new_colors(fd, colors);
  129. colors->version = 0; /* 4.0 format */
  130. }
  131. else {
  132. stat = read_old_colors(fd, colors);
  133. colors->version = -1; /* pre 4.0 format */
  134. }
  135. fclose(fd);
  136. return stat;
  137. }
  138. /* parse input lines with the following formats
  139. * val1:r:g:b val2:r:g:b
  140. * val:r:g:b (implies cat1==cat2)
  141. *
  142. * r:g:b can be just a single grey level
  143. * cat1:x cat2:y
  144. * cat:x
  145. *
  146. * optional lines are
  147. * invert invert color table
  148. * shift:n where n is the amount to shift the color table
  149. * nv:r:g:b color to use for NULL values
  150. * *:r:g:b color to use for undefined (beyond color rules)
  151. */
  152. static int read_new_colors(FILE * fd, struct Colors *colors)
  153. {
  154. double val1, val2;
  155. long cat1, cat2;
  156. int r1, g1, b1;
  157. int r2, g2, b2;
  158. char buf[1024];
  159. char word1[256], word2[256];
  160. int n, fp_rule;
  161. int null, undef;
  162. int modular;
  163. DCELL shift;
  164. if (fgets(buf, sizeof buf, fd) == NULL)
  165. return -1;
  166. G_strip(buf);
  167. if (sscanf(buf + 1, "%lf %lf", &val1, &val2) == 2)
  168. G_set_d_color_range((DCELL) val1, (DCELL) val2, colors);
  169. modular = 0;
  170. while (fgets(buf, sizeof buf, fd)) {
  171. null = undef = fp_rule = 0;
  172. *word1 = *word2 = 0;
  173. n = sscanf(buf, "%s %s", word1, word2);
  174. if (n < 1)
  175. continue;
  176. if (sscanf(word1, "shift:%lf", &shift) == 1
  177. || (strcmp(word1, "shift:") == 0 &&
  178. sscanf(word2, "%lf", &shift) == 1)) {
  179. G_shift_d_colors(shift, colors);
  180. continue;
  181. }
  182. if (strcmp(word1, "invert") == 0) {
  183. G_invert_colors(colors);
  184. continue;
  185. }
  186. if (strcmp(word1, "%%") == 0) {
  187. modular = !modular;
  188. continue;
  189. }
  190. switch (sscanf(word1, "nv:%d:%d:%d", &r1, &g1, &b1)) {
  191. case 1:
  192. null = 1;
  193. b1 = g1 = r1;
  194. break;
  195. case 3:
  196. null = 1;
  197. break;
  198. }
  199. if (!null)
  200. switch (sscanf(word1, "*:%d:%d:%d", &r1, &g1, &b1)) {
  201. case 1:
  202. undef = 1;
  203. b1 = g1 = r1;
  204. break;
  205. case 3:
  206. undef = 1;
  207. break;
  208. }
  209. if (!null && !undef)
  210. switch (sscanf(word1, "%ld:%d:%d:%d", &cat1, &r1, &g1, &b1)) {
  211. case 2:
  212. b1 = g1 = r1;
  213. break;
  214. case 4:
  215. break;
  216. default:
  217. if (sscanf(word1, "%lf:%d:%d:%d", &val1, &r1, &g1, &b1) == 4)
  218. fp_rule = 1;
  219. else if (sscanf(word1, "%lf:%d", &val1, &r1) == 2) {
  220. fp_rule = 1;
  221. b1 = g1 = r1;
  222. }
  223. else
  224. continue; /* other lines are ignored */
  225. }
  226. if (n == 2) {
  227. switch (sscanf(word2, "%ld:%d:%d:%d", &cat2, &r2, &g2, &b2)) {
  228. case 2:
  229. b2 = g2 = r2;
  230. if (fp_rule)
  231. val2 = (DCELL) cat2;
  232. break;
  233. case 4:
  234. if (fp_rule)
  235. val2 = (DCELL) cat2;
  236. break;
  237. default:
  238. if (sscanf(word2, "%lf:%d:%d:%d", &val2, &r2, &g2, &b2) == 4) {
  239. if (!fp_rule)
  240. val1 = (DCELL) cat1;
  241. fp_rule = 1;
  242. }
  243. else if (sscanf(word2, "%lf:%d", &val2, &r2) == 2) {
  244. if (!fp_rule)
  245. val1 = (DCELL) cat1;
  246. fp_rule = 1;
  247. b2 = g2 = r2;
  248. }
  249. else
  250. continue; /* other lines are ignored */
  251. }
  252. }
  253. else {
  254. if (!fp_rule)
  255. cat2 = cat1;
  256. else
  257. val2 = val1;
  258. r2 = r1;
  259. g2 = g1;
  260. b2 = b1;
  261. }
  262. if (null)
  263. G_set_null_value_color(r1, g1, b1, colors);
  264. else if (undef)
  265. G_set_default_color(r1, g1, b1, colors);
  266. else if (modular) {
  267. if (fp_rule)
  268. G_add_modular_d_raster_color_rule((DCELL *) & val1, r1, g1,
  269. b1, (DCELL *) & val2, r2,
  270. g2, b2, colors);
  271. else
  272. G_add_modular_color_rule((CELL) cat1, r1, g1, b1,
  273. (CELL) cat2, r2, g2, b2, colors);
  274. }
  275. else {
  276. if (fp_rule)
  277. G_add_d_raster_color_rule((DCELL *) & val1, r1, g1, b1,
  278. (DCELL *) & val2, r2, g2, b2,
  279. colors);
  280. else
  281. G_add_color_rule((CELL) cat1, r1, g1, b1,
  282. (CELL) cat2, r2, g2, b2, colors);
  283. }
  284. /*
  285. fprintf (stderr, "adding rule %d=%.2lf %d %d %d %d=%.2lf %d %d %d\n", cat1,val1, r1, g1, b1, cat2, val2, r2, g2, b2);
  286. */
  287. }
  288. return 1;
  289. }
  290. static int read_old_colors(FILE * fd, struct Colors *colors)
  291. {
  292. char buf[256];
  293. long n;
  294. long min;
  295. float red_f, grn_f, blu_f;
  296. int red, grn, blu;
  297. int old;
  298. int zero;
  299. G_init_colors(colors);
  300. /*
  301. * first line in pre 3.0 color files is number of colors - ignore
  302. * otherwise it is #min first color, and the next line is for color 0
  303. */
  304. if (fgets(buf, sizeof buf, fd) == NULL)
  305. return -1;
  306. G_strip(buf);
  307. if (*buf == '#') { /* 3.0 format */
  308. old = 0;
  309. if (sscanf(buf + 1, "%ld", &min) != 1) /* first color */
  310. return -1;
  311. zero = 1;
  312. }
  313. else {
  314. old = 1;
  315. min = 0;
  316. zero = 0;
  317. }
  318. colors->cmin = min;
  319. n = min;
  320. while (fgets(buf, sizeof buf, fd)) {
  321. if (old) {
  322. if (sscanf(buf, "%f %f %f", &red_f, &grn_f, &blu_f) != 3)
  323. return -1;
  324. red = 256 * red_f;
  325. grn = 256 * grn_f;
  326. blu = 256 * blu_f;
  327. }
  328. else {
  329. switch (sscanf(buf, "%d %d %d", &red, &grn, &blu)) {
  330. case 1:
  331. blu = grn = red;
  332. break;
  333. case 2:
  334. blu = grn;
  335. break;
  336. case 3:
  337. break;
  338. default:
  339. return -1;
  340. }
  341. }
  342. if (zero) {
  343. G__insert_color_into_lookup((CELL) 0, red, grn, blu,
  344. &colors->fixed);
  345. zero = 0;
  346. }
  347. else
  348. G__insert_color_into_lookup((CELL) n++, red, grn, blu,
  349. &colors->fixed);
  350. }
  351. colors->cmax = n - 1;
  352. return 0;
  353. }
  354. /*!
  355. * \brief
  356. *
  357. * Sets a flag in
  358. * the <em>colors</em> structure that indicates that these colors should only be
  359. * looked up using floating-point raster data (not integer data).
  360. * In particular if this flag is set, the routine <tt>G_get_colors_min_max()</tt> should return min=-255$^3$ and max=255$^3$.
  361. *
  362. * \param colors
  363. * \return int
  364. */
  365. int G_mark_colors_as_fp(struct Colors *colors)
  366. {
  367. colors->is_float = 1;
  368. return 0;
  369. }