group.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  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 *, 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, "", NULL, ref);
  102. }
  103. /*!
  104. * \brief read group REF file
  105. *
  106. * Reads the contents of the REF file for the specified <b>group</b> into
  107. * the <b>ref</b> structure.
  108. * Returns 1 if successful; 0 otherwise (but no error messages are printed).
  109. *
  110. * \param group
  111. * \param mapset
  112. * \param ref
  113. * \return int
  114. */
  115. int I_get_group_ref2(const char *group, const char *mapset, struct Ref *ref)
  116. {
  117. return get_ref(group, "", mapset, ref);
  118. }
  119. /*!
  120. * \brief read subgroup REF file
  121. *
  122. * Reads the contents of the REF file for the
  123. * specified <b>subgroup</b> of the specified <b>group</b> into the
  124. * <b>ref</b> structure.
  125. * Returns 1 if successful; 0 otherwise (but no error messages are printed).
  126. *
  127. * \param group
  128. * \param subgroup
  129. * \param ref
  130. * \return int
  131. */
  132. int I_get_subgroup_ref(const char *group,
  133. const char *subgroup, struct Ref *ref)
  134. {
  135. return get_ref(group, subgroup, NULL, ref);
  136. }
  137. /*!
  138. * \brief read subgroup REF file
  139. *
  140. * Reads the contents of the REF file for the
  141. * specified <b>subgroup</b> of the specified <b>group</b> into the
  142. * <b>ref</b> structure.
  143. * Returns 1 if successful; 0 otherwise (but no error messages are printed).
  144. *
  145. * \param group
  146. * \param subgroup
  147. * \param mapset
  148. * \param ref
  149. * \return int
  150. */
  151. int I_get_subgroup_ref2(const char *group,
  152. const char *subgroup, const char *mapset,
  153. struct Ref *ref)
  154. {
  155. return get_ref(group, subgroup, mapset, ref);
  156. }
  157. static int get_ref(const char *group, const char *subgroup, const char *gmapset, struct Ref *ref)
  158. {
  159. int n;
  160. char buf[1024];
  161. char name[INAME_LEN], mapset[INAME_LEN];
  162. char color[20];
  163. FILE *fd;
  164. I_init_group_ref(ref);
  165. if (gmapset == NULL || *gmapset == 0)
  166. gmapset = G_mapset();
  167. G_suppress_warnings(1);
  168. if (*subgroup == 0)
  169. fd = I_fopen_group_ref_old2(group, gmapset);
  170. else
  171. fd = I_fopen_subgroup_ref_old2(group, subgroup, gmapset);
  172. G_suppress_warnings(0);
  173. if (!fd)
  174. return 0;
  175. while (G_getl2(buf, sizeof buf, fd)) {
  176. n = sscanf(buf, "%255s %255s %15s", name, mapset, color); /* better use INAME_LEN */
  177. if (n == 2 || n == 3) {
  178. I_add_file_to_group_ref(name, mapset, ref);
  179. if (n == 3)
  180. set_color(name, mapset, color, ref);
  181. }
  182. }
  183. /* make sure we have a color assignment */
  184. I_init_ref_color_nums(ref);
  185. fclose(fd);
  186. return 1;
  187. }
  188. static int set_color(const char *name, const char *mapset, const char *color,
  189. struct Ref *ref)
  190. {
  191. int n;
  192. for (n = 0; n < ref->nfiles; n++) {
  193. if (strcmp(ref->file[n].name, name) == 0
  194. && strcmp(ref->file[n].mapset, mapset) == 0)
  195. break;
  196. }
  197. if (n < ref->nfiles)
  198. while (*color) {
  199. switch (*color) {
  200. case 'r':
  201. case 'R':
  202. if (ref->red.n < 0)
  203. ref->red.n = n;
  204. break;
  205. case 'g':
  206. case 'G':
  207. if (ref->grn.n < 0)
  208. ref->grn.n = n;
  209. break;
  210. case 'b':
  211. case 'B':
  212. if (ref->blu.n < 0)
  213. ref->blu.n = n;
  214. break;
  215. }
  216. color++;
  217. }
  218. return 0;
  219. }
  220. int I_init_ref_color_nums(struct Ref *ref)
  221. {
  222. ref->red.table = NULL;
  223. ref->grn.table = NULL;
  224. ref->blu.table = NULL;
  225. ref->red.index = NULL;
  226. ref->grn.index = NULL;
  227. ref->blu.index = NULL;
  228. if (ref->nfiles <= 0 || ref->red.n >= 0 || ref->blu.n >= 0 ||
  229. ref->blu.n >= 0)
  230. return 1;
  231. switch (ref->nfiles) {
  232. case 1:
  233. ref->red.n = 0;
  234. ref->grn.n = 0;
  235. ref->blu.n = 0;
  236. break;
  237. case 2:
  238. ref->blu.n = 0;
  239. ref->grn.n = 1;
  240. break;
  241. case 3:
  242. ref->blu.n = 0;
  243. ref->grn.n = 1;
  244. ref->red.n = 2;
  245. break;
  246. case 4:
  247. ref->blu.n = 0;
  248. ref->grn.n = 1;
  249. ref->red.n = 3;
  250. break;
  251. default:
  252. ref->blu.n = 1;
  253. ref->grn.n = 2;
  254. ref->red.n = 4;
  255. break;
  256. }
  257. return 0;
  258. }
  259. /*!
  260. * \brief write group REF file
  261. *
  262. * Writes the contents of the <b>ref</b> structure to the REF file for
  263. * the specified <b>group.</b>
  264. * Returns 1 if successful; 0 otherwise (and prints a diagnostic error).
  265. * <b>Note.</b> This routine will create the <b>group</b>, if it does not
  266. * already exist.
  267. *
  268. * \param group
  269. * \param ref
  270. * \return int
  271. */
  272. int I_put_group_ref(const char *group, const struct Ref *ref)
  273. {
  274. return put_ref(group, "", ref);
  275. }
  276. /*!
  277. * \brief write subgroup REF file
  278. *
  279. * Writes the contents of the <b>ref</b>
  280. * structure into the REF file for the specified <b>subgroup</b> of the
  281. * specified <b>group.</b>
  282. * Returns 1 if successful; 0 otherwise (and prints a diagnostic error).
  283. * <b>Note.</b> This routine will create the <b>subgroup</b>, if it does not
  284. * already exist.
  285. *
  286. * \param group
  287. * \param subgroup
  288. * \param ref
  289. * \return int
  290. */
  291. int I_put_subgroup_ref(const char *group, const char *subgroup,
  292. const struct Ref *ref)
  293. {
  294. return put_ref(group, subgroup, ref);
  295. }
  296. static int put_ref(const char *group, const char *subgroup,
  297. const struct Ref *ref)
  298. {
  299. int n;
  300. FILE *fd;
  301. if (*subgroup == 0)
  302. fd = I_fopen_group_ref_new(group);
  303. else
  304. fd = I_fopen_subgroup_ref_new(group, subgroup);
  305. if (!fd)
  306. return 0;
  307. for (n = 0; n < ref->nfiles; n++) {
  308. fprintf(fd, "%s %s", ref->file[n].name, ref->file[n].mapset);
  309. if (n == ref->red.n || n == ref->grn.n || n == ref->blu.n) {
  310. fprintf(fd, " ");
  311. if (n == ref->red.n)
  312. fprintf(fd, "r");
  313. if (n == ref->grn.n)
  314. fprintf(fd, "g");
  315. if (n == ref->blu.n)
  316. fprintf(fd, "b");
  317. }
  318. fprintf(fd, "\n");
  319. }
  320. fclose(fd);
  321. return 1;
  322. }
  323. /*!
  324. * \brief add file name to Ref structure
  325. *
  326. * This routine adds the file
  327. * <b>name</b> and <b>mapset</b> to the list contained in the <b>ref</b>
  328. * structure, if it is not already in the list. The <b>ref</b> structure must
  329. * have been properly initialized. This routine is used by programs, such as
  330. * <i>i.maxlik</i>, to add to the group new raster maps created from files
  331. * already in the group.
  332. * Returns the index into the <i>file</i> array within the <b>ref</b>
  333. * structure for the file after insertion; see
  334. * Imagery_Library_Data_Structures.
  335. *
  336. * \param name
  337. * \param mapset
  338. * \param ref
  339. * \return int
  340. */
  341. int I_add_file_to_group_ref(const char *name, const char *mapset,
  342. struct Ref *ref)
  343. {
  344. int n;
  345. for (n = 0; n < ref->nfiles; n++) {
  346. if (strcmp(ref->file[n].name, name) == 0
  347. && strcmp(ref->file[n].mapset, mapset) == 0)
  348. return n;
  349. }
  350. if ((n = ref->nfiles++))
  351. ref->file =
  352. (struct Ref_Files *)G_realloc(ref->file,
  353. ref->nfiles *
  354. sizeof(struct Ref_Files));
  355. else
  356. ref->file =
  357. (struct Ref_Files *)G_malloc(ref->nfiles *
  358. sizeof(struct Ref_Files));
  359. strcpy(ref->file[n].name, name);
  360. strcpy(ref->file[n].mapset, mapset);
  361. return n;
  362. }
  363. /*!
  364. * \brief copy Ref lists
  365. *
  366. * This routine is used to copy file names from one
  367. * <i>Ref</i> structure to another. The name and mapset for file <b>n</b>
  368. * from the <b>src</b> structure are copied into the <b>dst</b> structure
  369. * (which must be properly initialized).
  370. * For example, the following code copies one <i>Ref</i> structure to another:
  371. \code
  372. struct Ref src,dst;
  373. int n;
  374. // some code to get information into <b>src</b>
  375. ...
  376. I_init_group_ref (&dst);
  377. for (n = 0; n < src.nfiles; n++)
  378. I_transfer_group_ref_file (&src, n, &dst);
  379. \endcode
  380. * This routine is used by <i>g.gui.gcp</i> to create the REF file for a
  381. * subgroup.
  382. *
  383. * \param src
  384. * \param n
  385. * \param dst
  386. * \return int
  387. */
  388. int I_transfer_group_ref_file(const struct Ref *ref2, int n, struct Ref *ref1)
  389. {
  390. int k;
  391. /* insert old name into new ref */
  392. k = I_add_file_to_group_ref(ref2->file[n].name, ref2->file[n].mapset,
  393. ref1);
  394. /* preserve color assignment */
  395. if (n == ref2->red.n)
  396. ref1->red.n = k;
  397. if (n == ref2->grn.n)
  398. ref1->grn.n = k;
  399. if (n == ref2->blu.n)
  400. ref1->blu.n = k;
  401. return 0;
  402. }
  403. /*!
  404. * \brief initialize Ref
  405. * structure
  406. *
  407. * This routine initializes the <b>ref</b> structure for other
  408. * library calls which require a <i>Ref</i> structure. This routine must be
  409. * called before any use of the structure can be made.
  410. * <b>Note.</b> The routines I_get_group_ref and I_get_subgroup_ref call
  411. * this routine automatically.
  412. *
  413. * \param ref
  414. * \return int
  415. */
  416. int I_init_group_ref(struct Ref *ref)
  417. {
  418. ref->nfiles = 0;
  419. ref->red.n = ref->grn.n = ref->blu.n = -1;
  420. ref->red.table = ref->grn.table = ref->blu.table = NULL;
  421. return 0;
  422. }
  423. /*!
  424. * \brief free Ref structure
  425. *
  426. * This routine frees memory allocated to the <b>ref</b> structure.
  427. *
  428. * \param ref
  429. * \return int
  430. */
  431. int I_free_group_ref(struct Ref *ref)
  432. {
  433. if (ref->nfiles > 0)
  434. free(ref->file);
  435. ref->nfiles = 0;
  436. return 0;
  437. }