color.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <unistd.h>
  6. #include <grass/gis.h>
  7. #include <grass/raster.h>
  8. #include <grass/glocale.h>
  9. #include "raster3d_intern.h"
  10. static int read_colors(const char *, const char *, struct Colors *);
  11. static int read_new_colors(FILE *, struct Colors *);
  12. static int read_old_colors(FILE *, struct Colors *);
  13. /*---------------------------------------------------------------------------*/
  14. int Rast3d_remove_color(const char *name)
  15. /* adapted from G_remove_colr */
  16. {
  17. return G_remove_misc(RASTER3D_DIRECTORY, RASTER3D_COLOR_ELEMENT, name);
  18. }
  19. /*---------------------------------------------------------------------------*/
  20. int
  21. Rast3d_read_colors(const char *name, const char *mapset, struct Colors *colors)
  22. /* adapted from Rast_read_colors */
  23. {
  24. const char *err;
  25. struct FPRange drange;
  26. DCELL dmin, dmax;
  27. Rast_init_colors(colors);
  28. Rast_mark_colors_as_fp(colors);
  29. switch (read_colors(name, mapset, colors)) {
  30. case -2:
  31. if (Rast3d_read_range(name, mapset, &drange) >= 0) {
  32. Rast_get_fp_range_min_max(&drange, &dmin, &dmax);
  33. if (!Rast_is_d_null_value(&dmin) && !Rast_is_d_null_value(&dmax))
  34. Rast_make_rainbow_fp_colors(colors, dmin, dmax);
  35. return 0;
  36. }
  37. err = "missing";
  38. break;
  39. case -1:
  40. err = "invalid";
  41. break;
  42. default:
  43. return 1;
  44. }
  45. G_warning("color support for [%s] in mapset [%s] %s", name, mapset, err);
  46. return -1;
  47. }
  48. static int read_colors(const char *name, const char *mapset,
  49. struct Colors *colors)
  50. {
  51. FILE *fd;
  52. int stat;
  53. char buf[1024];
  54. fd = G_fopen_old_misc(RASTER3D_DIRECTORY, RASTER3D_COLOR_ELEMENT, name, mapset);
  55. if (!fd)
  56. return -2;
  57. /*
  58. * first line in 4.0 color files is %
  59. * otherwise it is pre 4.0
  60. */
  61. if (fgets(buf, sizeof buf, fd) == NULL) {
  62. fclose(fd);
  63. return -1;
  64. }
  65. G_fseek(fd, 0L, 0);
  66. G_strip(buf);
  67. if (*buf == '%') { /* 4.0 format */
  68. stat = read_new_colors(fd, colors);
  69. colors->version = 0; /* 4.0 format */
  70. }
  71. else {
  72. stat = read_old_colors(fd, colors);
  73. colors->version = -1; /* pre 4.0 format */
  74. }
  75. fclose(fd);
  76. return stat;
  77. }
  78. /* parse input lines with the following formats
  79. * val1:r:g:b val2:r:g:b
  80. * val:r:g:b (implies cat1==cat2)
  81. *
  82. * r:g:b can be just a single grey level
  83. * cat1:x cat2:y
  84. * cat:x
  85. *
  86. * optional lines are
  87. * invert invert color table
  88. * shift:n where n is the amount to shift the color table
  89. */
  90. static int read_new_colors(FILE * fd, struct Colors *colors)
  91. {
  92. double val1, val2;
  93. long cat1, cat2;
  94. int r1, g1, b1;
  95. int r2, g2, b2;
  96. char buf[1024];
  97. char word1[256], word2[256];
  98. int n, fp_rule;
  99. int null, undef;
  100. int modular;
  101. DCELL shift;
  102. if (fgets(buf, sizeof buf, fd) == NULL)
  103. return -1;
  104. G_strip(buf);
  105. if (sscanf(buf + 1, "%lf %lf", &val1, &val2) == 2)
  106. Rast_set_d_color_range((DCELL) val1, (DCELL) val2, colors);
  107. modular = 0;
  108. while (fgets(buf, sizeof buf, fd)) {
  109. null = undef = fp_rule = 0;
  110. *word1 = *word2 = 0;
  111. n = sscanf(buf, "%s %s", word1, word2);
  112. if (n < 1)
  113. continue;
  114. if (sscanf(word1, "shift:%lf", &shift) == 1
  115. || (strcmp(word1, "shift:") == 0 &&
  116. sscanf(word2, "%lf", &shift) == 1)) {
  117. Rast_shift_d_colors(shift, colors);
  118. continue;
  119. }
  120. if (strcmp(word1, "invert") == 0) {
  121. Rast_invert_colors(colors);
  122. continue;
  123. }
  124. if (strcmp(word1, "%%") == 0) {
  125. modular = !modular;
  126. continue;
  127. }
  128. switch (sscanf(word1, "nv:%d:%d:%d", &r1, &g1, &b1)) {
  129. case 1:
  130. null = 1;
  131. b1 = g1 = r1;
  132. break;
  133. case 3:
  134. null = 1;
  135. break;
  136. }
  137. if (!null)
  138. switch (sscanf(word1, "*:%d:%d:%d", &r1, &g1, &b1)) {
  139. case 1:
  140. undef = 1;
  141. b1 = g1 = r1;
  142. break;
  143. case 3:
  144. undef = 1;
  145. break;
  146. }
  147. if (!null && !undef)
  148. switch (sscanf(word1, "%ld:%d:%d:%d", &cat1, &r1, &g1, &b1)) {
  149. case 2:
  150. b1 = g1 = r1;
  151. break;
  152. case 4:
  153. break;
  154. default:
  155. if (sscanf(word1, "%lf:%d:%d:%d", &val1, &r1, &g1, &b1) == 4)
  156. fp_rule = 1;
  157. else if (sscanf(word1, "%lf:%d", &val1, &r1) == 2) {
  158. fp_rule = 1;
  159. b1 = g1 = r1;
  160. }
  161. else
  162. continue; /* other lines are ignored */
  163. }
  164. if (n == 2) {
  165. switch (sscanf(word2, "%ld:%d:%d:%d", &cat2, &r2, &g2, &b2)) {
  166. case 2:
  167. b2 = g2 = r2;
  168. if (fp_rule)
  169. val2 = (DCELL) cat2;
  170. break;
  171. case 4:
  172. if (fp_rule)
  173. val2 = (DCELL) cat2;
  174. break;
  175. default:
  176. if (sscanf(word2, "%lf:%d:%d:%d", &val2, &r2, &g2, &b2) == 4) {
  177. if (!fp_rule)
  178. val1 = (DCELL) cat1;
  179. fp_rule = 1;
  180. }
  181. else if (sscanf(word2, "%lf:%d", &val2, &r2) == 2) {
  182. if (!fp_rule)
  183. val1 = (DCELL) cat1;
  184. fp_rule = 1;
  185. b2 = g2 = r2;
  186. }
  187. else
  188. continue; /* other lines are ignored */
  189. }
  190. }
  191. else {
  192. if (!fp_rule)
  193. cat2 = cat1;
  194. else
  195. val2 = val1;
  196. r2 = r1;
  197. g2 = g1;
  198. b2 = b1;
  199. }
  200. if (null)
  201. Rast_set_null_value_color(r1, g1, b1, colors);
  202. else if (undef)
  203. Rast_set_default_color(r1, g1, b1, colors);
  204. else if (modular) {
  205. if (fp_rule)
  206. Rast_add_modular_d_color_rule((DCELL *) & val1, r1, g1,
  207. b1, (DCELL *) & val2, r2,
  208. g2, b2, colors);
  209. else
  210. Rast_add_modular_c_color_rule((CELL *) &cat1, r1, g1, b1,
  211. (CELL *) &cat2, r2, g2, b2, colors);
  212. }
  213. else {
  214. if (fp_rule)
  215. Rast_add_d_color_rule((DCELL *) & val1, r1, g1, b1,
  216. (DCELL *) & val2, r2, g2, b2,
  217. colors);
  218. else
  219. Rast_add_c_color_rule((CELL *) &cat1, r1, g1, b1,
  220. (CELL *) &cat2, r2, g2, b2, colors);
  221. }
  222. /*
  223. 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);
  224. */
  225. }
  226. return 1;
  227. }
  228. static int read_old_colors(FILE * fd, struct Colors *colors)
  229. {
  230. char buf[256];
  231. long n;
  232. long min;
  233. float red_f, grn_f, blu_f;
  234. int red, grn, blu;
  235. int old;
  236. int zero;
  237. Rast_init_colors(colors);
  238. /*
  239. * first line in pre 3.0 color files is number of colors - ignore
  240. * otherwise it is #min first color, and the next line is for color 0
  241. */
  242. if (fgets(buf, sizeof buf, fd) == NULL)
  243. return -1;
  244. G_strip(buf);
  245. if (*buf == '#') { /* 3.0 format */
  246. old = 0;
  247. if (sscanf(buf + 1, "%ld", &min) != 1) /* first color */
  248. return -1;
  249. zero = 1;
  250. }
  251. else {
  252. old = 1;
  253. min = 0;
  254. zero = 0;
  255. }
  256. colors->cmin = min;
  257. n = min;
  258. while (fgets(buf, sizeof buf, fd)) {
  259. if (old) {
  260. if (sscanf(buf, "%f %f %f", &red_f, &grn_f, &blu_f) != 3)
  261. return -1;
  262. red = 256 * red_f;
  263. grn = 256 * grn_f;
  264. blu = 256 * blu_f;
  265. }
  266. else {
  267. switch (sscanf(buf, "%d %d %d", &red, &grn, &blu)) {
  268. case 1:
  269. blu = grn = red;
  270. break;
  271. case 2:
  272. blu = grn;
  273. break;
  274. case 3:
  275. break;
  276. default:
  277. return -1;
  278. }
  279. }
  280. if (zero) {
  281. Rast__insert_color_into_lookup((CELL) 0, red, grn, blu,
  282. &colors->fixed);
  283. zero = 0;
  284. }
  285. else
  286. Rast__insert_color_into_lookup((CELL) n++, red, grn, blu,
  287. &colors->fixed);
  288. }
  289. colors->cmax = n - 1;
  290. return 0;
  291. }
  292. /*---------------------------------------------------------------------------*/
  293. int
  294. Rast3d_write_colors(const char *name, const char *mapset, struct Colors *colors)
  295. /* adapted from Rast_write_colors */
  296. {
  297. FILE *fd;
  298. if (strcmp(mapset, G_mapset()) != 0) {
  299. G_warning(_("mapset <%s> is not the current mapset"), mapset);
  300. return -1;
  301. }
  302. fd = G_fopen_new_misc(RASTER3D_DIRECTORY, RASTER3D_COLOR_ELEMENT, name);
  303. if (!fd)
  304. return -1;
  305. Rast__write_colors(fd, colors);
  306. fclose(fd);
  307. return 1;
  308. }
  309. /*---------------------------------------------------------------------------*/
  310. /*---------------------------------------------------------------------------*/
  311. /*---------------------------------------------------------------------------*/