group.c 11 KB

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