group.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. /****************************************************************************
  2. *
  3. * MODULE: imagery library
  4. * AUTHOR(S): Original author(s) name(s) unknown - written by CERL
  5. * PURPOSE: Image processing library
  6. * COPYRIGHT: (C) 1999, 2005 by the GRASS Development Team
  7. *
  8. * This program is free software under the GNU General Public
  9. * License (>=v2). Read the file COPYING that comes with GRASS
  10. * for details.
  11. *
  12. *****************************************************************************/
  13. /**********************************************************
  14. * I_get_group (group);
  15. * I_put_group (group);
  16. *
  17. * I_get_group_ref (group, &Ref);
  18. * I_put_group_ref (group, &Ref);
  19. * I_get_subgroup_ref_file (group, subgroup, &Ref);
  20. * I_put_subgroup_ref_file (group, subgroup, &Ref);
  21. * I_add_file_to_group_ref (name, mapset, &Ref)
  22. * I_transfer_group_ref_file (&Src_ref, n, &Dst_ref)
  23. * I_init_group_ref (&Ref);
  24. * I_free_group_ref (&Ref);
  25. **********************************************************/
  26. #include <string.h>
  27. #include <stdlib.h>
  28. #include <grass/imagery.h>
  29. static int get_ref(const char *, const char *, struct Ref *);
  30. static int set_color(const char *, const char *, const char *, struct Ref *);
  31. static int put_ref(const char *, const char *, const struct Ref *);
  32. /* get current group name from file GROUPFILE in current mapset */
  33. int I_get_group(char *group)
  34. {
  35. FILE *fd;
  36. int stat;
  37. *group = 0;
  38. G_suppress_warnings(1);
  39. fd = G_fopen_old("", GROUPFILE, G_mapset());
  40. G_suppress_warnings(0);
  41. if (fd == NULL)
  42. return 0;
  43. stat = (fscanf(fd, "%s", group) == 1);
  44. fclose(fd);
  45. return stat;
  46. }
  47. /* write group name to file GROUPFILE in current mapset */
  48. int I_put_group(const char *group)
  49. {
  50. FILE *fd;
  51. fd = G_fopen_new("", GROUPFILE);
  52. if (fd == NULL)
  53. return 0;
  54. fprintf(fd, "%s\n", group);
  55. fclose(fd);
  56. return 1;
  57. }
  58. /* get current subgroup for group in current mapset */
  59. int I_get_subgroup(const char *group, char *subgroup)
  60. {
  61. FILE *fd;
  62. int stat;
  63. *subgroup = 0;
  64. if (!I_find_group(group))
  65. return 0;
  66. G_suppress_warnings(1);
  67. fd = I_fopen_group_file_old(group, SUBGROUPFILE);
  68. G_suppress_warnings(0);
  69. if (fd == NULL)
  70. return 0;
  71. stat = (fscanf(fd, "%s", subgroup) == 1);
  72. fclose(fd);
  73. return stat;
  74. }
  75. /* write current subgroup to group in current mapset */
  76. int I_put_subgroup(const char *group, const char *subgroup)
  77. {
  78. FILE *fd;
  79. if (!I_find_group(group))
  80. return 0;
  81. fd = I_fopen_group_file_new(group, SUBGROUPFILE);
  82. if (fd == NULL)
  83. return 0;
  84. fprintf(fd, "%s\n", subgroup);
  85. fclose(fd);
  86. return 1;
  87. }
  88. /*!
  89. * \brief read group REF file
  90. *
  91. * Reads the contents of the REF file for the specified <b>group</b> into
  92. * the <b>ref</b> structure.
  93. * Returns 1 if successful; 0 otherwise (but no error messages are printed).
  94. *
  95. * \param group
  96. * \param ref
  97. * \return int
  98. */
  99. int I_get_group_ref(const char *group, struct Ref *ref)
  100. {
  101. return get_ref(group, "", ref);
  102. }
  103. /*!
  104. * \brief read subgroup REF file
  105. *
  106. * Reads the contents of the REF file for the
  107. * specified <b>subgroup</b> of the specified <b>group</b> into the
  108. * <b>ref</b> structure.
  109. * Returns 1 if successful; 0 otherwise (but no error messages are printed).
  110. *
  111. * \param group
  112. * \param subgroup
  113. * \param ref
  114. * \return int
  115. */
  116. int I_get_subgroup_ref(const char *group,
  117. const char *subgroup, struct Ref *ref)
  118. {
  119. return get_ref(group, subgroup, ref);
  120. }
  121. static int get_ref(const char *group, const char *subgroup, struct Ref *ref)
  122. {
  123. int n;
  124. char buf[1024];
  125. char name[INAME_LEN], mapset[INAME_LEN];
  126. char color[20];
  127. FILE *fd;
  128. I_init_group_ref(ref);
  129. G_suppress_warnings(1);
  130. if (*subgroup == 0)
  131. fd = I_fopen_group_ref_old(group);
  132. else
  133. fd = I_fopen_subgroup_ref_old(group, subgroup);
  134. G_suppress_warnings(0);
  135. if (!fd)
  136. return 0;
  137. while (G_getl2(buf, sizeof buf, fd)) {
  138. n = sscanf(buf, "%255s %255s %15s", name, mapset, color); /* better use INAME_LEN */
  139. if (n == 2 || n == 3) {
  140. I_add_file_to_group_ref(name, mapset, ref);
  141. if (n == 3)
  142. set_color(name, mapset, color, ref);
  143. }
  144. }
  145. /* make sure we have a color assignment */
  146. I_init_ref_color_nums(ref);
  147. fclose(fd);
  148. return 1;
  149. }
  150. static int set_color(const char *name, const char *mapset, const char *color,
  151. struct Ref *ref)
  152. {
  153. int n;
  154. for (n = 0; n < ref->nfiles; n++) {
  155. if (strcmp(ref->file[n].name, name) == 0
  156. && strcmp(ref->file[n].mapset, mapset) == 0)
  157. break;
  158. }
  159. if (n < ref->nfiles)
  160. while (*color) {
  161. switch (*color) {
  162. case 'r':
  163. case 'R':
  164. if (ref->red.n < 0)
  165. ref->red.n = n;
  166. break;
  167. case 'g':
  168. case 'G':
  169. if (ref->grn.n < 0)
  170. ref->grn.n = n;
  171. break;
  172. case 'b':
  173. case 'B':
  174. if (ref->blu.n < 0)
  175. ref->blu.n = n;
  176. break;
  177. }
  178. color++;
  179. }
  180. return 0;
  181. }
  182. int I_init_ref_color_nums(struct Ref *ref)
  183. {
  184. ref->red.table = NULL;
  185. ref->grn.table = NULL;
  186. ref->blu.table = NULL;
  187. ref->red.index = NULL;
  188. ref->grn.index = NULL;
  189. ref->blu.index = NULL;
  190. if (ref->nfiles <= 0 || ref->red.n >= 0 || ref->blu.n >= 0 ||
  191. ref->blu.n >= 0)
  192. return 1;
  193. switch (ref->nfiles) {
  194. case 1:
  195. ref->red.n = 0;
  196. ref->grn.n = 0;
  197. ref->blu.n = 0;
  198. break;
  199. case 2:
  200. ref->blu.n = 0;
  201. ref->grn.n = 1;
  202. break;
  203. case 3:
  204. ref->blu.n = 0;
  205. ref->grn.n = 1;
  206. ref->red.n = 2;
  207. break;
  208. case 4:
  209. ref->blu.n = 0;
  210. ref->grn.n = 1;
  211. ref->red.n = 3;
  212. break;
  213. default:
  214. ref->blu.n = 1;
  215. ref->grn.n = 2;
  216. ref->red.n = 4;
  217. break;
  218. }
  219. return 0;
  220. }
  221. /*!
  222. * \brief write group REF file
  223. *
  224. * Writes the contents of the <b>ref</b> structure to the REF file for
  225. * the specified <b>group.</b>
  226. * Returns 1 if successful; 0 otherwise (and prints a diagnostic error).
  227. * <b>Note.</b> This routine will create the <b>group</b>, if it does not
  228. * already exist.
  229. *
  230. * \param group
  231. * \param ref
  232. * \return int
  233. */
  234. int I_put_group_ref(const char *group, const struct Ref *ref)
  235. {
  236. return put_ref(group, "", ref);
  237. }
  238. /*!
  239. * \brief write subgroup REF file
  240. *
  241. * Writes the contents of the <b>ref</b>
  242. * structure into the REF file for the specified <b>subgroup</b> of the
  243. * specified <b>group.</b>
  244. * Returns 1 if successful; 0 otherwise (and prints a diagnostic error).
  245. * <b>Note.</b> This routine will create the <b>subgroup</b>, if it does not
  246. * already exist.
  247. *
  248. * \param group
  249. * \param subgroup
  250. * \param ref
  251. * \return int
  252. */
  253. int I_put_subgroup_ref(const char *group, const char *subgroup,
  254. const struct Ref *ref)
  255. {
  256. return put_ref(group, subgroup, ref);
  257. }
  258. static int put_ref(const char *group, const char *subgroup,
  259. const struct Ref *ref)
  260. {
  261. int n;
  262. FILE *fd;
  263. if (*subgroup == 0)
  264. fd = I_fopen_group_ref_new(group);
  265. else
  266. fd = I_fopen_subgroup_ref_new(group, subgroup);
  267. if (!fd)
  268. return 0;
  269. for (n = 0; n < ref->nfiles; n++) {
  270. fprintf(fd, "%s %s", ref->file[n].name, ref->file[n].mapset);
  271. if (n == ref->red.n || n == ref->grn.n || n == ref->blu.n) {
  272. fprintf(fd, " ");
  273. if (n == ref->red.n)
  274. fprintf(fd, "r");
  275. if (n == ref->grn.n)
  276. fprintf(fd, "g");
  277. if (n == ref->blu.n)
  278. fprintf(fd, "b");
  279. }
  280. fprintf(fd, "\n");
  281. }
  282. fclose(fd);
  283. return 1;
  284. }
  285. /*!
  286. * \brief add file name to Ref structure
  287. *
  288. * This routine adds the file
  289. * <b>name</b> and <b>mapset</b> to the list contained in the <b>ref</b>
  290. * structure, if it is not already in the list. The <b>ref</b> structure must
  291. * have been properly initialized. This routine is used by programs, such as
  292. * <i>i.maxlik</i>, to add to the group new raster maps created from files
  293. * already in the group.
  294. * Returns the index into the <i>file</i> array within the <b>ref</b>
  295. * structure for the file after insertion; see
  296. * Imagery_Library_Data_Structures.
  297. *
  298. * \param name
  299. * \param mapset
  300. * \param ref
  301. * \return int
  302. */
  303. int I_add_file_to_group_ref(const char *name, const char *mapset,
  304. struct Ref *ref)
  305. {
  306. int n;
  307. for (n = 0; n < ref->nfiles; n++) {
  308. if (strcmp(ref->file[n].name, name) == 0
  309. && strcmp(ref->file[n].mapset, mapset) == 0)
  310. return n;
  311. }
  312. if ((n = ref->nfiles++))
  313. ref->file =
  314. (struct Ref_Files *)G_realloc(ref->file,
  315. ref->nfiles *
  316. sizeof(struct Ref_Files));
  317. else
  318. ref->file =
  319. (struct Ref_Files *)G_malloc(ref->nfiles *
  320. sizeof(struct Ref_Files));
  321. strcpy(ref->file[n].name, name);
  322. strcpy(ref->file[n].mapset, mapset);
  323. return n;
  324. }
  325. /*!
  326. * \brief copy Ref lists
  327. *
  328. * This routine is used to copy file names from one
  329. * <i>Ref</i> structure to another. The name and mapset for file <b>n</b>
  330. * from the <b>src</b> structure are copied into the <b>dst</b> structure
  331. * (which must be properly initialized).
  332. * For example, the following code copies one <i>Ref</i> structure to another:
  333. \code
  334. struct Ref src,dst;
  335. int n;
  336. // some code to get information into <b>src</b>
  337. ...
  338. I_init_group_ref (&dst);
  339. for (n = 0; n < src.nfiles; n++)
  340. I_transfer_group_ref_file (&src, n, &dst);
  341. \endcode
  342. * This routine is used by <i>i.points</i> to create the REF file for a
  343. * subgroup.
  344. *
  345. * \param src
  346. * \param n
  347. * \param dst
  348. * \return int
  349. */
  350. int I_transfer_group_ref_file(const struct Ref *ref2, int n, struct Ref *ref1)
  351. {
  352. int k;
  353. /* insert old name into new ref */
  354. k = I_add_file_to_group_ref(ref2->file[n].name, ref2->file[n].mapset,
  355. ref1);
  356. /* preserve color assignment */
  357. if (n == ref2->red.n)
  358. ref1->red.n = k;
  359. if (n == ref2->grn.n)
  360. ref1->grn.n = k;
  361. if (n == ref2->blu.n)
  362. ref1->blu.n = k;
  363. return 0;
  364. }
  365. /*!
  366. * \brief initialize Ref
  367. * structure
  368. *
  369. * This routine initializes the <b>ref</b> structure for other
  370. * library calls which require a <i>Ref</i> structure. This routine must be
  371. * called before any use of the structure can be made.
  372. * <b>Note.</b> The routines I_get_group_ref and I_get_subgroup_ref call
  373. * this routine automatically.
  374. *
  375. * \param ref
  376. * \return int
  377. */
  378. int I_init_group_ref(struct Ref *ref)
  379. {
  380. ref->nfiles = 0;
  381. ref->red.n = ref->grn.n = ref->blu.n = -1;
  382. ref->red.table = ref->grn.table = ref->blu.table = NULL;
  383. return 0;
  384. }
  385. /*!
  386. * \brief free Ref structure
  387. *
  388. * This routine frees memory allocated to the <b>ref</b> structure.
  389. *
  390. * \param ref
  391. * \return int
  392. */
  393. int I_free_group_ref(struct Ref *ref)
  394. {
  395. if (ref->nfiles > 0)
  396. free(ref->file);
  397. ref->nfiles = 0;
  398. return 0;
  399. }