GRASS GIS 8 Programmer's Manual  8.2.2dev(2023)-3d2c704037
sigset.c
Go to the documentation of this file.
1 #include <string.h>
2 #include <stdlib.h>
3 #include <grass/gis.h>
4 #include <grass/glocale.h>
5 #include <grass/imagery.h>
6 
7 static int gettag(FILE *, char *);
8 static int get_semantic_labels(FILE *, struct SigSet *);
9 static int get_title(FILE *, struct SigSet *);
10 static int get_class(FILE *, struct SigSet *);
11 static int get_classnum(FILE *, struct ClassSig *);
12 static int get_classtype(FILE *, struct ClassSig *);
13 static int get_classtitle(FILE *, struct ClassSig *);
14 static int get_subclass(FILE *, struct SigSet *, struct ClassSig *);
15 static int get_subclass_pi(FILE *, struct SubSig *);
16 static int get_subclass_means(FILE *, struct SubSig *, int);
17 static int get_subclass_covar(FILE *, struct SubSig *, int);
18 
19 static double **alloc_matrix(int rows, int cols)
20 {
21  double **m;
22  int i;
23 
24  m = (double **)G_calloc(rows, sizeof(double *));
25  m[0] = (double *)G_calloc(rows * cols, sizeof(double));
26  for (i = 1; i < rows; i++)
27  m[i] = m[i - 1] + cols;
28 
29  return m;
30 }
31 
32 int I_SigSetNClasses(struct SigSet *S)
33 {
34  int i, count;
35 
36  for (i = 0, count = 0; i < S->nclasses; i++)
37  if (S->ClassSig[i].used)
38  count++;
39 
40  return count;
41 }
42 
43 
44 struct ClassData *I_AllocClassData(struct SigSet *S,
45  struct ClassSig *C, int npixels)
46 {
47  struct ClassData *Data;
48 
49  Data = &(C->ClassData);
50  Data->npixels = npixels;
51  Data->count = 0;
52  Data->x = alloc_matrix(npixels, S->nbands);
53  Data->p = alloc_matrix(npixels, C->nsubclasses);
54  return Data;
55 }
56 
57 /*!
58  * \brief Initialize struct SigSet before use
59  *
60  * No need to call before calling I_ReadSigSet.
61  *
62  * \param *Signature to initialize
63  * \param nbands band (imagery group member) count
64  */
65 int I_InitSigSet(struct SigSet *S, int nbands)
66 {
67  S->nbands = nbands;
68  S->semantic_labels = (char **)G_malloc(nbands * sizeof(char **));
69  for (int i = 0; i < nbands; i++)
70  S->semantic_labels[i] = NULL;
71  S->nclasses = 0;
72  S->ClassSig = NULL;
73  S->title = NULL;
74 
75  return 0;
76 }
77 
78 struct ClassSig *I_NewClassSig(struct SigSet *S)
79 {
80  struct ClassSig *Sp;
81 
82  if (S->nclasses == 0)
83  S->ClassSig = (struct ClassSig *)G_malloc(sizeof(struct ClassSig));
84  else
85  S->ClassSig = (struct ClassSig *)G_realloc((char *)S->ClassSig,
86  sizeof(struct ClassSig) *
87  (S->nclasses + 1));
88 
89  Sp = &S->ClassSig[S->nclasses++];
90  Sp->classnum = 0;
91  Sp->nsubclasses = 0;
92  Sp->used = 1;
94  Sp->title = NULL;
95  return Sp;
96 }
97 
98 struct SubSig *I_NewSubSig(struct SigSet *S, struct ClassSig *C)
99 {
100  struct SubSig *Sp;
101  int i;
102 
103  if (C->nsubclasses == 0)
104  C->SubSig = (struct SubSig *)G_malloc(sizeof(struct SubSig));
105  else
106  C->SubSig = (struct SubSig *)G_realloc((char *)C->SubSig,
107  sizeof(struct SubSig) *
108  (C->nsubclasses + 1));
109 
110  Sp = &C->SubSig[C->nsubclasses++];
111  Sp->used = 1;
112  Sp->R = (double **)G_calloc(S->nbands, sizeof(double *));
113  Sp->R[0] = (double *)G_calloc(S->nbands * S->nbands, sizeof(double));
114  for (i = 1; i < S->nbands; i++)
115  Sp->R[i] = Sp->R[i - 1] + S->nbands;
116  Sp->Rinv = (double **)G_calloc(S->nbands, sizeof(double *));
117  Sp->Rinv[0] = (double *)G_calloc(S->nbands * S->nbands, sizeof(double));
118  for (i = 1; i < S->nbands; i++)
119  Sp->Rinv[i] = Sp->Rinv[i - 1] + S->nbands;
120  Sp->means = (double *)G_calloc(S->nbands, sizeof(double));
121  Sp->N = 0;
122  Sp->pi = 0;
123  Sp->cnst = 0;
124  return Sp;
125 }
126 
127 #define eq(a,b) strcmp(a,b)==0
128 
129 /*!
130  * \brief Read sigset signatures from file
131  *
132  * File stream should be opened in advance by call to
133  * I_fopen_sigset_file_old()
134  * It is up to caller to fclose the file stream afterwards.
135  *
136  * There is no need to initialise struct SigSet in advance, as this
137  * function internally calls I_InitSigSet.
138  *
139  * \param pointer to FILE*
140  * \param pointer to struct SigSet *S
141  *
142  * \return 1 on success, -1 on failure
143  */
144 int I_ReadSigSet(FILE * fd, struct SigSet *S)
145 {
146  char tag[256];
147  unsigned int version;
148 
149  if (fscanf(fd, "%u", &version) != 1) {
150  G_warning(_("Invalid signature file"));
151  return -1;
152  }
153  if (version != 1) {
154  G_warning(_("Invalid signature file version"));
155  return -1;
156  }
157 
158  I_InitSigSet(S, 0);
159  while (gettag(fd, tag)) {
160  if (eq(tag, "title:"))
161  if (get_title(fd, S) != 0)
162  return -1;
163  if (eq(tag, "semantic_labels:"))
164  if (get_semantic_labels(fd, S) != 0)
165  return -1;
166  if (eq(tag, "class:"))
167  if (get_class(fd, S) != 0)
168  return -1;
169  }
170  return 1; /* for now assume success */
171 }
172 
173 static int gettag(FILE * fd, char *tag)
174 {
175  if (fscanf(fd, "%255s", tag) != 1)
176  return 0;
177  G_strip(tag);
178  return 1;
179 }
180 
181 static int get_semantic_labels(FILE * fd, struct SigSet *S)
182 {
183  int n, pos;
184  char c, prev;
185  char semantic_label[GNAME_MAX];
186 
187  /* Read semantic labels and count them to set nbands */
188  n = 0;
189  pos = 0;
190  S->semantic_labels = (char **)G_realloc(S->semantic_labels, (n + 1) * sizeof(char **));
191  while ((c = (char)fgetc(fd)) != EOF) {
192  if (c == '\n') {
193  if (prev != ' ') {
194  semantic_label[pos] = '\0';
195  if (strlen(semantic_label) > 0) {
196  S->semantic_labels[n] = G_store(semantic_label);
197  n++;
198  }
199  }
200  S->nbands = n;
201  break;
202  }
203  if (c == ' ') {
204  semantic_label[pos] = '\0';
205  if (strlen(semantic_label) > 0) {
206  S->semantic_labels[n] = G_store(semantic_label);
207  n++;
208  /* [n] is 0 based thus: (n + 1) */
209  S->semantic_labels =
210  (char **)G_realloc(S->semantic_labels,
211  (n + 1) * sizeof(char **));
212  }
213  pos = 0;
214  prev = c;
215  continue;
216  }
217  /* Semantic labels are limited to GNAME_MAX - 1 + \0 in length;
218  * n is 0-based */
219  if (pos == (GNAME_MAX - 2)) {
220  G_warning(_("Invalid signature file: semantic label length limit exceeded"));
221  return -1;
222  }
223  semantic_label[pos] = c;
224  pos++;
225  prev = c;
226  }
227  if (!(S->nbands > 0)) {
228  G_warning(_("Signature file does not contain bands"));
229  return -1;
230  }
231 
232  return 0;
233 }
234 
235 static int get_title(FILE * fd, struct SigSet *S)
236 {
237  char title[1024];
238 
239  *title = 0;
240  if (fscanf(fd, "%1024[^\n]", title) != 1)
241  return -1;
242  G_strip(title);
243  I_SetSigTitle(S, title);
244 
245  return 0;
246 }
247 
248 static int get_class(FILE * fd, struct SigSet *S)
249 {
250  char tag[1024];
251  struct ClassSig *C;
252 
253  C = I_NewClassSig(S);
254  while (gettag(fd, tag)) {
255  if (eq(tag, "endclass:"))
256  break;
257  if (eq(tag, "classnum:"))
258  if (get_classnum(fd, C) != 0)
259  return -1;
260  if (eq(tag, "classtype:"))
261  if (get_classtype(fd, C) != 0)
262  return -1;
263  if (eq(tag, "classtitle:"))
264  if (get_classtitle(fd, C) != 0)
265  return -1;
266  if (eq(tag, "subclass:"))
267  if (get_subclass(fd, S, C) != 0)
268  return -1;
269  }
270 
271  return 0;
272 }
273 
274 static int get_classnum(FILE * fd, struct ClassSig *C)
275 {
276  if (fscanf(fd, "%ld", &C->classnum) != 1)
277  return -1;
278 
279  return 0;
280 }
281 
282 static int get_classtype(FILE * fd, struct ClassSig *C)
283 {
284  if (fscanf(fd, "%d", &C->type) != 1)
285  return -1;
286 
287  return 0;
288 }
289 
290 static int get_classtitle(FILE * fd, struct ClassSig *C)
291 {
292  char title[1024];
293 
294  *title = 0;
295  if (fscanf(fd, "%1024[^\n]", title) != 1)
296  return -1;
297  G_strip(title);
298  I_SetClassTitle(C, title);
299 
300  return 0;
301 }
302 
303 static int get_subclass(FILE * fd, struct SigSet *S, struct ClassSig *C)
304 {
305  struct SubSig *Sp;
306  char tag[1024];
307 
308  Sp = I_NewSubSig(S, C);
309 
310  while (gettag(fd, tag)) {
311  if (eq(tag, "endsubclass:"))
312  break;
313  if (eq(tag, "pi:"))
314  if (get_subclass_pi(fd, Sp) != 0)
315  return -1;
316  if (eq(tag, "means:"))
317  if (get_subclass_means(fd, Sp, S->nbands) != 0)
318  return -1;
319  if (eq(tag, "covar:"))
320  if (get_subclass_covar(fd, Sp, S->nbands) != 0)
321  return -1;
322  }
323 
324  return 0;
325 }
326 
327 static int get_subclass_pi(FILE * fd, struct SubSig *Sp)
328 {
329  if (fscanf(fd, "%lf", &Sp->pi) != 1)
330  return -1;
331 
332  return 0;
333 }
334 
335 static int get_subclass_means(FILE * fd, struct SubSig *Sp, int nbands)
336 {
337  int i;
338 
339  for (i = 0; i < nbands; i++)
340  if (fscanf(fd, "%lf", &Sp->means[i]) != 1)
341  return -1;
342 
343  return 0;
344 }
345 
346 static int get_subclass_covar(FILE * fd, struct SubSig *Sp, int nbands)
347 {
348  int i, j;
349 
350  for (i = 0; i < nbands; i++)
351  for (j = 0; j < nbands; j++)
352  if (fscanf(fd, "%lf", &Sp->R[i][j]) != 1)
353  return -1;
354 
355  return 0;
356 }
357 
358 int I_SetSigTitle(struct SigSet *S, const char *title)
359 {
360  if (title == NULL)
361  title = "";
362  if (S->title)
363  free(S->title);
364  S->title = G_store(title);
365 
366  return 0;
367 }
368 
369 const char *I_GetSigTitle(const struct SigSet *S)
370 {
371  if (S->title)
372  return S->title;
373  else
374  return "";
375 }
376 
377 int I_SetClassTitle(struct ClassSig *C, const char *title)
378 {
379  if (title == NULL)
380  title = "";
381  if (C->title)
382  free(C->title);
383  C->title = G_store(title);
384 
385  return 0;
386 }
387 
388 const char *I_GetClassTitle(const struct ClassSig *C)
389 {
390  if (C->title)
391  return C->title;
392  else
393  return "";
394 }
395 
396 int I_WriteSigSet(FILE * fd, const struct SigSet *S)
397 {
398  const struct ClassSig *Cp;
399  const struct SubSig *Sp;
400  int i, j, b1, b2;
401 
402  /* This is version 1 sigset file format */
403  fprintf(fd, "1\n");
404  fprintf(fd, "title: %s\n", I_GetSigTitle(S));
405  fprintf(fd, "semantic_labels: ");
406  for (i = 0; i < S->nbands; i++) {
407  fprintf(fd, "%s ", S->semantic_labels[i]);
408  }
409  fprintf(fd, "\n");
410  for (i = 0; i < S->nclasses; i++) {
411  Cp = &S->ClassSig[i];
412  if (!Cp->used)
413  continue;
414  if (Cp->nsubclasses <= 0)
415  continue;
416  fprintf(fd, "class:\n");
417  fprintf(fd, " classnum: %ld\n", Cp->classnum);
418  fprintf(fd, " classtitle: %s\n", I_GetClassTitle(Cp));
419  fprintf(fd, " classtype: %d\n", Cp->type);
420 
421  for (j = 0; j < Cp->nsubclasses; j++) {
422  Sp = &Cp->SubSig[j];
423  fprintf(fd, " subclass:\n");
424  fprintf(fd, " pi: %g\n", Sp->pi);
425  fprintf(fd, " means:");
426  for (b1 = 0; b1 < S->nbands; b1++)
427  fprintf(fd, " %g", Sp->means[b1]);
428  fprintf(fd, "\n");
429  fprintf(fd, " covar:\n");
430  for (b1 = 0; b1 < S->nbands; b1++) {
431  fprintf(fd, " ");
432  for (b2 = 0; b2 < S->nbands; b2++)
433  fprintf(fd, " %g", Sp->R[b1][b2]);
434  fprintf(fd, "\n");
435  }
436  fprintf(fd, " endsubclass:\n");
437  }
438  fprintf(fd, "endclass:\n");
439  }
440 
441  return 0;
442 }
443 
444 /*!
445  * \brief Reorder struct SigSet to match imagery group member order
446  *
447  * The function will check for semantic label match between sigset struct
448  * and imagery group.
449  *
450  * In the case of a complete semantic label match, values of passed in
451  * struct SigSet are reordered to match the order of imagery group items.
452  * This reordering is done only for items present in the sigset file.
453  * Thus reordering should be done only after calling I_ReadSigSet.
454  *
455  * If all semantic labels are not identical (in
456  * arbitrary order), function will return two dimensional array with
457  * comma separated list of:
458  * - [0] semantic labels present in the signature struct but
459  * absent in the imagery group
460  * - [1] semantic labels present in the imagery group but
461  * absent in the signature struct
462  *
463  * If no mismatch of semantic labels for signatures or imagery group are
464  * detected (== all are present in the other list), a NULL value will be
465  * returned in the particular list of mismatches (not an empty string).
466  * For example:
467  * \code if (ret && ret[1]) printf("List of imagery group bands without signatures: %s\n, ret[1]); \endcode
468  *
469  * \param *SigSet existing signatures to check & sort
470  * \param *Ref group reference
471  *
472  * \return NULL successfully sorted
473  * \return err_array two comma separated lists of mismatches
474  */
475 char **I_SortSigSetBySemanticLabel(struct SigSet *S, const struct Ref *R)
476 {
477  unsigned int total, complete;
478  unsigned int *match1, *match2, mc1, mc2, *new_order;
479  double ***new_means, ****new_vars;
480  char **group_semantic_labels, **mismatches, **new_semantic_labels;
481 
482  /* Safety measure. Untranslated as this should not happen in production! */
483  if (S->nbands < 1 || R->nfiles < 1)
484  G_fatal_error("Programming error. Invalid length structs passed to "
485  "I_sort_signatures_by_semantic_label(%d, %d);", S->nbands,
486  R->nfiles);
487 
488  /* Obtain group semantic labels */
489  group_semantic_labels = (char **)G_malloc(R->nfiles * sizeof(char *));
490  for (unsigned int j = R->nfiles; j--;) {
491  group_semantic_labels[j] = Rast_get_semantic_label_or_name(R->file[j].name, R->file[j].mapset);
492  }
493 
494  /* If lengths are not equal, there will be a mismatch */
495  complete = S->nbands == R->nfiles;
496 
497  /* Initialize match tracker */
498  new_order = (unsigned int *)G_malloc(S->nbands * sizeof(unsigned int));
499  match1 = (unsigned int *)G_calloc(S->nbands, sizeof(unsigned int));
500  match2 = (unsigned int *)G_calloc(R->nfiles, sizeof(unsigned int));
501 
502  /* Allocate memory for temporary storage of sorted values */
503  new_semantic_labels = (char **)G_malloc(S->nbands * sizeof(char *));
504  new_means = (double ***)G_malloc(S->nclasses * sizeof(double **));
505  // new_vars[S.ClassSig[x]][.SubSig[y]][R[band1]][R[band1]]
506  new_vars = (double ****)G_malloc(S->nclasses * sizeof(double ***));
507  for (unsigned int c = S->nclasses; c--;) {
508  new_means[c] =
509  (double **)G_malloc(S->ClassSig[c].nsubclasses *
510  sizeof(double *));
511  new_vars[c] =
512  (double ***)G_malloc(S->ClassSig[c].nsubclasses *
513  sizeof(double **));
514  for (unsigned int s = S->ClassSig[c].nsubclasses; s--;) {
515  new_means[c][s] = (double *)G_malloc(S->nbands * sizeof(double));
516  new_vars[c][s] =
517  (double **)G_malloc(S->nbands * sizeof(double *));
518  for (unsigned int i = S->nbands; i--;)
519  new_vars[c][s][i] =
520  (double *)G_malloc(S->nbands * sizeof(double));
521  }
522  }
523 
524  /* Obtain order of matching items */
525  for (unsigned int j = R->nfiles; j--;) {
526  for (unsigned int i = S->nbands; i--;) {
527  if (S->semantic_labels[i] && group_semantic_labels[j] &&
528  !strcmp(S->semantic_labels[i], group_semantic_labels[j])) {
529  if (complete) {
530  /* Reorder pointers to existing strings only */
531  new_semantic_labels[j] = S->semantic_labels[i];
532  new_order[i] = j;
533  }
534  /* Keep a track of matching items for error reporting */
535  match1[i] = 1;
536  match2[j] = 1;
537  break;
538  }
539  }
540  }
541 
542  /* Check for semantic label mismatch */
543  mc1 = mc2 = 0;
544  mismatches = (char **)G_malloc(2 * sizeof(char **));
545  mismatches[0] = NULL;
546  mismatches[1] = NULL;
547  total = 1;
548  for (unsigned int i = 0; i < S->nbands; i++) {
549  if (!match1[i]) {
550  if (S->semantic_labels[i])
551  total = total + strlen(S->semantic_labels[i]);
552  else
553  total = total + 24;
554  mismatches[0] =
555  (char *)G_realloc(mismatches[0], total * sizeof(char *));
556  if (mc1)
557  strcat(mismatches[0], ",");
558  else
559  mismatches[0][0] = '\0';
560  if (S->semantic_labels[i])
561  strcat(mismatches[0], S->semantic_labels[i]);
562  else
563  strcat(mismatches[0], "<semantic label missing>");
564  mc1++;
565  total = total + 1;
566  }
567  }
568  total = 1;
569  for (unsigned int j = 0; j < R->nfiles; j++) {
570  if (!match2[j]) {
571  if (group_semantic_labels[j])
572  total = total + strlen(group_semantic_labels[j]);
573  else
574  total = total + 24;
575  mismatches[1] =
576  (char *)G_realloc(mismatches[1], total * sizeof(char *));
577  if (mc2)
578  strcat(mismatches[1], ",");
579  else
580  mismatches[1][0] = '\0';
581  if (group_semantic_labels[j])
582  strcat(mismatches[1], group_semantic_labels[j]);
583  else
584  strcat(mismatches[1], "<semantic label missing>");
585  mc2++;
586  total = total + 1;
587  }
588  }
589 
590  /* Swap mean and var matrix values in each of classes */
591  if (!mc1 && !mc2) {
592  for (unsigned int c = S->nclasses; c--;) {
593  for (unsigned int s = S->ClassSig[c].nsubclasses; s--;) {
594  for (unsigned int b1 = 0; b1 < S->nbands; b1++) {
595  new_means[c][s][new_order[b1]] =
596  S->ClassSig[c].SubSig[s].means[b1];
597  for (unsigned int b2 = 0; b2 < S->nbands; b2++) {
598  new_vars[c][s][new_order[b1]][new_order[b2]] =
599  S->ClassSig[c].SubSig[s].R[b1][b2];
600  }
601  }
602  }
603  }
604 
605  /* Replace values in struct with ordered ones */
606  memcpy(S->semantic_labels, new_semantic_labels, S->nbands * sizeof(char **));
607  for (unsigned int c = S->nclasses; c--;) {
608  for (unsigned int s = S->ClassSig[c].nsubclasses; s--;) {
609  memcpy(S->ClassSig[c].SubSig[s].means, new_means[c][s],
610  S->nbands * sizeof(double));
611  for (unsigned int i = S->nbands; i--;)
612  memcpy(S->ClassSig[c].SubSig[s].R[i], new_vars[c][s][i],
613  S->nbands * sizeof(double));
614  }
615  }
616  }
617 
618  /* Clean up */
619  for (unsigned int j = R->nfiles; j--;)
620  free(group_semantic_labels[j]);
621  free(group_semantic_labels);
622  free(new_order);
623  free(match1);
624  free(match2);
625  free(new_semantic_labels);
626  for (unsigned int c = S->nclasses; c--;) {
627  for (unsigned int s = S->ClassSig[c].nsubclasses; s--;) {
628  free(new_means[c][s]);
629  for (unsigned int i = S->nbands; i--;)
630  free(new_vars[c][s][i]);
631  free(new_vars[c][s]);
632  }
633  free(new_means[c]);
634  free(new_vars[c]);
635  }
636 
637  free(new_means);
638  free(new_vars);
639 
640  if (mc1 || mc2) {
641  return mismatches;
642  }
643  free(mismatches);
644  return NULL;
645 }
#define G_malloc(n)
Definition: defs/gis.h:112
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
int nclasses
Definition: imagery.h:106
char name[INAME_LEN]
Definition: imagery.h:22
double ** Rinv
Definition: imagery.h:78
Definition: imagery.h:72
const char * I_GetSigTitle(const struct SigSet *S)
Definition: sigset.c:369
Definition: imagery.h:26
int count
char ** semantic_labels
Definition: imagery.h:105
char * title
Definition: imagery.h:107
#define SIGNATURE_TYPE_MIXED
Definition: imagery.h:209
double pi
Definition: imagery.h:75
double ** x
Definition: imagery.h:87
void G_strip(char *)
Removes all leading and trailing white space from string.
Definition: strings.c:300
struct SubSig * SubSig
Definition: imagery.h:98
void free(void *)
#define NULL
Definition: ccmath.h:32
#define eq(a, b)
Definition: sigset.c:127
int type
Definition: imagery.h:96
int I_SetClassTitle(struct ClassSig *C, const char *title)
Definition: sigset.c:377
int I_SetSigTitle(struct SigSet *S, const char *title)
Definition: sigset.c:358
#define G_calloc(m, n)
Definition: defs/gis.h:113
char ** I_SortSigSetBySemanticLabel(struct SigSet *S, const struct Ref *R)
Reorder struct SigSet to match imagery group member order.
Definition: sigset.c:475
struct ClassSig * I_NewClassSig(struct SigSet *S)
Definition: sigset.c:78
char * title
Definition: imagery.h:94
struct ClassSig * ClassSig
Definition: imagery.h:108
double ** R
Definition: imagery.h:77
int nbands
Definition: imagery.h:104
double * means
Definition: imagery.h:76
int I_SigSetNClasses(struct SigSet *S)
Definition: sigset.c:32
char mapset[INAME_LEN]
Definition: imagery.h:23
struct ClassData * I_AllocClassData(struct SigSet *S, struct ClassSig *C, int npixels)
Definition: sigset.c:44
double N
Definition: imagery.h:74
long classnum
Definition: imagery.h:93
int I_WriteSigSet(FILE *fd, const struct SigSet *S)
Definition: sigset.c:396
int nfiles
Definition: imagery.h:28
struct Ref_Files * file
Definition: imagery.h:29
#define GNAME_MAX
Definition: gis.h:177
void G_warning(const char *,...) __attribute__((format(printf
struct SubSig * I_NewSubSig(struct SigSet *S, struct ClassSig *C)
Definition: sigset.c:98
int npixels
Definition: imagery.h:85
#define G_realloc(p, n)
Definition: defs/gis.h:114
#define _(str)
Definition: glocale.h:10
double cnst
Definition: imagery.h:79
char * Rast_get_semantic_label_or_name(const char *, const char *)
Get a raster map semantic label or fall back to its name.
char * G_store(const char *)
Copy string to allocated memory.
Definition: strings.c:87
int used
Definition: imagery.h:80
double ** p
Definition: imagery.h:88
int I_ReadSigSet(FILE *fd, struct SigSet *S)
Read sigset signatures from file.
Definition: sigset.c:144
int used
Definition: imagery.h:95
const char * I_GetClassTitle(const struct ClassSig *C)
Definition: sigset.c:388
int I_InitSigSet(struct SigSet *S, int nbands)
Initialize struct SigSet before use.
Definition: sigset.c:65
struct ClassData ClassData
Definition: imagery.h:99
int nsubclasses
Definition: imagery.h:97
int count
Definition: imagery.h:86