color.c 7.7 KB

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