GRASS GIS 8 Programmer's Manual  8.4.0dev(2024)-112dd97adf
quant.c
Go to the documentation of this file.
1 /*!
2  * \file lib/raster/quant.c
3  *
4  * \brief Raster Library - Quantization rules.
5  *
6  * The quantization table is stored as a linear array. Rules are added
7  * starting from index 0. Redundant rules are not eliminated. Rules
8  * are tested from the highest index downto 0. There are two
9  * "infinite" rules. Support is provided to reverse the order of the
10  * rules.
11  *
12  * (C) 1999-2009 by the GRASS Development Team
13  *
14  * This program is free software under the GNU General Public License
15  * (>=v2). Read the file COPYING that comes with GRASS for details.
16  *
17  * \author USACERL and many others
18  */
19 
20 #include <stdlib.h>
21 #include <grass/gis.h>
22 #include <grass/raster.h>
23 
24 static int double_comp(const void *, const void *);
25 
26 #define USE_LOOKUP 1
27 #define MAX_LOOKUP_TABLE_SIZE 2048
28 #define NO_DATA (Rast_set_c_null_value(&tmp, 1), (CELL)tmp)
29 
30 #define NO_LEFT_INFINITE_RULE (!q->infiniteLeftSet)
31 #define NO_RIGHT_INFINITE_RULE (!q->infiniteRightSet)
32 #define NO_FINITE_RULE (q->nofRules <= 0)
33 #define NO_EXPLICIT_RULE \
34  (NO_FINITE_RULE && NO_LEFT_INFINITE_RULE && NO_RIGHT_INFINITE_RULE)
35 
36 /*!
37  \brief Resets the number of defined rules and number of infinite rules to 0
38 
39  \param q pointer to Quant structure to be reset
40  */
41 void Rast_quant_clear(struct Quant *q)
42 {
43  q->nofRules = 0;
45 }
46 
47 /*!
48  \brief Resets and frees allocated memory
49 
50  Resets the number of defined rules to 0 and free's space allocated
51  for rules. Calls Rast_quant_clear().
52 
53  \param q pointer to Quant structure to be reset
54  */
55 void Rast_quant_free(struct Quant *q)
56 {
58 
59  if (q->maxNofRules > 0)
60  G_free(q->table);
61  if (q->fp_lookup.active) {
62  G_free(q->fp_lookup.vals);
64  q->fp_lookup.nalloc = 0;
65  q->fp_lookup.active = 0;
66  }
67  q->maxNofRules = 0;
68 }
69 
70 /*!
71  * \brief Organized fp_lookup table.
72  *
73  * Organizes fp_lookup table for faster (logarithmic) lookup time
74  * G_quant_organize_fp_lookup() creates a list of min and max for
75  * each quant rule, sorts this list, and stores the pointer to quant
76  * rule that should be used in between any 2 numbers in this list.
77  * Also it stores extreme points for 2 infinite rules, if exist.
78  * After the call to G_quant_organize_fp_lookup()
79  * instead of linearly searching through list of rules to find
80  * a rule to apply, quant lookup will perform a binary search
81  * to find an interval containing floating point value, and then use
82  * the rule associated with this interval.
83  * when the value doesn't fall within any interval, check for the
84  * infinite rules.
85  *
86  * \param q pointer to Quant structure which holds quant rules info
87  *
88  * \return 1 on success
89  */
91 {
92  int i;
93  DCELL val;
94  CELL tmp;
95  struct Quant_table *p;
96 
97  if (q->nofRules * 2 > MAX_LOOKUP_TABLE_SIZE)
98  return -1;
99  if (q->nofRules == 0)
100  return -1;
101  q->fp_lookup.vals = (DCELL *)G_calloc(q->nofRules * 2, sizeof(DCELL));
102  /* 2 endpoints for each rule */
103  q->fp_lookup.rules = (struct Quant_table **)G_calloc(
104  q->nofRules * 2, sizeof(struct Quant_table *));
105 
106  /* first we organize finite rules into a table */
107  if (!NO_FINITE_RULE) {
108  i = 0;
109  /* get the list of DCELL values from set of all dLows and dHighs
110  of all rules */
111  /* NOTE: if dLow==DHigh in a rule, the value appears twice in a list
112  but if dLow==DHigh of the previous, rule the value appears only once
113  */
114 
115  for (p = &(q->table[q->nofRules - 1]); p >= q->table; p--) {
116  /* check if the min is the same as previous maximum */
117  if (i == 0 || p->dLow != q->fp_lookup.vals[i - 1])
118  q->fp_lookup.vals[i++] = p->dLow;
119  q->fp_lookup.vals[i++] = p->dHigh;
120  }
121  q->fp_lookup.nalloc = i;
122 
123  /* now sort the values */
124  qsort((char *)q->fp_lookup.vals, q->fp_lookup.nalloc, sizeof(DCELL),
125  double_comp);
126 
127  /* now find the rule to apply in between each 2 values in a list */
128  for (i = 0; i < q->fp_lookup.nalloc - 1; i++) {
129  /*debug
130  fprintf (stderr, "%lf %lf ", q->fp_lookup.vals[i],
131  q->fp_lookup.vals[i+1]);
132  */
133  val = (q->fp_lookup.vals[i] + q->fp_lookup.vals[i + 1]) / 2.;
134  q->fp_lookup.rules[i] =
136  /* debug
137  if(q->fp_lookup.rules[i])
138  fprintf (stderr, "%lf %lf %d %d\n", q->fp_lookup.rules[i]->dLow,
139  q->fp_lookup.rules[i]->dHigh, q->fp_lookup.rules[i]->cLow,
140  q->fp_lookup.rules[i]->cHigh); else fprintf (stderr, "null\n");
141  */
142  }
143  } /* organizing finite rules */
144 
145  if (!NO_LEFT_INFINITE_RULE) {
148  }
149  else {
150  if (q->fp_lookup.nalloc)
151  q->fp_lookup.inf_dmin = q->fp_lookup.vals[0];
153  }
154 
155  if (!NO_RIGHT_INFINITE_RULE) {
156  if (q->fp_lookup.nalloc)
159  }
160  else {
163  }
164  q->fp_lookup.active = 1;
165  return 1;
166 }
167 
168 /*!
169  * \brief Initialize the structure
170  *
171  * Initializes the <i>q</i> struct.
172  *
173  * \param quant pointer to Quant structure to be initialized
174  */
175 void Rast_quant_init(struct Quant *quant)
176 {
177  quant->fp_lookup.active = 0;
178  quant->maxNofRules = 0;
179  quant->truncate_only = 0;
180  quant->round_only = 0;
181  Rast_quant_clear(quant);
182 }
183 
184 /*!
185  \brief Returns whether or not quant rules are set to truncate map
186 
187  \param quant pointer to Quant structure which holds quant rules info
188 
189  \return 1 if truncate is enable
190  \return 0 if not truncated
191  */
192 int Rast_quant_is_truncate(const struct Quant *quant)
193 {
194  return quant->truncate_only;
195 }
196 
197 /*!
198  \brief Returns whether or not quant rules are set to round map
199  \param quant pointer to Quant structure which holds quant rules info
200 
201  \return 1 is round
202  \return 0 not round
203  */
204 int Rast_quant_is_round(const struct Quant *quant)
205 {
206  return quant->round_only;
207 }
208 
209 /*!
210  * \brief Sets the quant rules to perform simple truncation on floats.
211  *
212  * Sets the quant for <i>q</i> rules to perform simple truncation on
213  * floats.
214  *
215  * \param quant pointer to Quant structure which holds quant rules info
216  */
217 void Rast_quant_truncate(struct Quant *quant)
218 {
219  quant->truncate_only = 1;
220 }
221 
222 /*!
223  * \brief Sets the quant rules to perform simple rounding on floats.
224  *
225  * Sets the quant for <i>q</i> rules to perform simple rounding on
226  * floats.
227  *
228  * \param quant pointer to Quant structure which holds quant rules info
229  */
230 void Rast_quant_round(struct Quant *quant)
231 {
232  quant->round_only = 1;
233 }
234 
235 static void quant_set_limits(struct Quant *q, DCELL dLow, DCELL dHigh,
236  CELL cLow, CELL cHigh)
237 {
238  q->dMin = dLow;
239  q->dMax = dHigh;
240  q->cMin = cLow;
241  q->cMax = cHigh;
242 }
243 
244 static void quant_update_limits(struct Quant *q, DCELL dLow, DCELL dHigh,
245  CELL cLow, DCELL cHigh)
246 {
247  if (NO_EXPLICIT_RULE) {
248  quant_set_limits(q, dLow, dHigh, cLow, cHigh);
249  return;
250  }
251 
252  q->dMin = MIN(q->dMin, MIN(dLow, dHigh));
253  q->dMax = MAX(q->dMax, MAX(dLow, dHigh));
254  q->cMin = MIN(q->cMin, MIN(cLow, cHigh));
255  q->cMax = MAX(q->cMax, MAX(cLow, cHigh));
256 }
257 
258 /*!
259  * \brief Returns the minimum and maximum cell and dcell values of all
260  * the ranges defined.
261  *
262  * Extracts the minimum and maximum floating-point and integer values
263  * from all the rules (except the "infinite" rules) in <i>q</i> into
264  * <i>dmin</i>, <i>dmax</i>, <i>cmin</i>, and <i>cmax</i>.
265  *
266  * \param quant pointer to Quant structure which holds quant rules info
267  * \param[out] dmin minimum fp value
268  * \param[out] dmax maximum fp value
269  * \param[out] cmin minimum value
270  * \param[out] cmax maximum value
271  *
272  * \return -1 if q->truncate or q->round are true or after
273  * Rast_quant_init (), or any call to Rast_quant_clear () or Rast_quant_free()
274  * no explicit rules have been added. In this case the returned
275  * minimum and maximum CELL and DCELL values are null.
276  * \return 1 if there are any explicit rules
277  * \return 0 if there are no explicit rules (this includes cases when
278  * q is set to truncate or round map), and sets <i>dmin</i>,
279  * <i>dmax</i>, <i>cmin</i>, and <i>cmax</i> to NULL.
280  */
281 int Rast_quant_get_limits(const struct Quant *q, DCELL *dMin, DCELL *dMax,
282  CELL *cMin, CELL *cMax)
283 {
284  if (NO_EXPLICIT_RULE) {
285  Rast_set_c_null_value(cMin, 1);
286  Rast_set_c_null_value(cMax, 1);
287  Rast_set_d_null_value(dMin, 1);
288  Rast_set_d_null_value(dMax, 1);
289  return -1;
290  }
291 
292  *dMin = q->dMin;
293  *dMax = q->dMax;
294  *cMin = q->cMin;
295  *cMax = q->cMax;
296 
297  return 1;
298 }
299 
300 /*!
301  \brief Returns the number of quantization rules defined.
302 
303  This number does not include the 2 infinite intervals.
304 
305  \param q pointer to Quant structure which holds quant rules info
306 
307  \return number of quantization rules
308  */
309 int Rast_quant_nof_rules(const struct Quant *q)
310 {
311  return q->nofRules;
312 }
313 
314 /*!
315  \brief Returns the i'th quantization rule.
316 
317  For 0 <= i < Rast_quant_nof_rules(). A larger value for i means that
318  the rule has been added later.
319 
320  \param q pointer to Quant structure which holds quant rules info
321  \param i index
322  \param[out] dLow minimum fp value
323  \param[out] dHigh maximum fp value
324  \param[out] cLow minimum value
325  \param[out] cHigh maximum value
326  */
327 void Rast_quant_get_ith_rule(const struct Quant *q, int i, DCELL *dLow,
328  DCELL *dHigh, CELL *cLow, CELL *cHigh)
329 {
330  *dLow = q->table[i].dLow;
331  *dHigh = q->table[i].dHigh;
332  *cLow = q->table[i].cLow;
333  *cHigh = q->table[i].cHigh;
334 }
335 
336 static void quant_table_increase(struct Quant *q)
337 {
338  if (q->nofRules < q->maxNofRules)
339  return;
340 
341  if (q->maxNofRules == 0) {
342  q->maxNofRules = 50;
343  q->table = (struct Quant_table *)G_malloc(q->maxNofRules *
344  sizeof(struct Quant_table));
345  }
346  else {
347  q->maxNofRules += 50;
348  q->table = (struct Quant_table *)G_realloc(
349  (char *)q->table, q->maxNofRules * sizeof(struct Quant_table));
350  }
351 }
352 
353 /*!
354  \brief Defines a rule for values "dLeft" and smaller.
355 
356  Values in this range are mapped to "c" if none of the "finite"
357  quantization rules applies.
358 
359  \param q pointer to Quant structure which holds quant rules info
360 
361  \param dLeft fp value
362  \param c value
363  */
365 {
366  q->infiniteDLeft = dLeft;
367  q->infiniteCLeft = c;
368  quant_update_limits(q, dLeft, dLeft, c, c);
369 
370  /* update lookup table */
371  if (q->fp_lookup.active) {
374  }
375  q->infiniteLeftSet = 1;
376 }
377 
378 /*!
379  \brief Returns in "dLeft" and "c" the rule values.
380 
381  For the negative infinite interval (see Rast_quant_set_neg_infinite_rule()).
382 
383  \param q pointer to Quant structure which holds quant rules info
384  \param[out] dLeft fp value
385  \param[out] c value
386 
387  \return 0 if this rule is not defined
388  \return 1 otherwise
389  */
390 int Rast_quant_get_neg_infinite_rule(const struct Quant *q, DCELL *dLeft,
391  CELL *c)
392 {
393  if (q->infiniteLeftSet == 0)
394  return 0;
395 
396  *dLeft = q->infiniteDLeft;
397  *c = q->infiniteCLeft;
398 
399  return 1;
400 }
401 
402 /*!
403  \brief Defines a rule for values "dRight" and larger.
404 
405  Values in this range are mapped to "c" if none of the "finite"
406  quantization rules or the negative infinite rule applies.
407 
408  \param q pointer to Quant structure which holds quant rules info
409  \param dRight fp value
410  \param c value
411  */
413 {
414  q->infiniteDRight = dRight;
415  q->infiniteCRight = c;
416  quant_update_limits(q, dRight, dRight, c, c);
417 
418  /* update lookup table */
419  if (q->fp_lookup.active) {
422  }
423  q->infiniteRightSet = 1;
424 }
425 
426 /*!
427  \brief Returns in "dRight" and "c" the rule values.
428 
429  For the positive infinite interval (see Rast_quant_set_pos_infinite_rule()).
430 
431  \param q pointer to Quant structure which holds quant rules info
432  \param[out] dRight fp value
433  \param[out] c value
434 
435  \return 0 if this rule is not defined
436  \return 1 otherwise
437  */
438 int Rast_quant_get_pos_infinite_rule(const struct Quant *q, DCELL *dRight,
439  CELL *c)
440 {
441  if (q->infiniteRightSet == 0)
442  return 0;
443 
444  *dRight = q->infiniteDRight;
445  *c = q->infiniteCRight;
446 
447  return 1;
448 }
449 
450 /*!
451  \brief Adds a new rule to the set of quantization rules.
452 
453  If dLow < dHigh the rule will be stored with the low and high values
454  interchanged.
455 
456  Note: currently no cleanup of rules is performed, i.e. redundant
457  rules are not removed. This can't be changed because Categories
458  structure HEAVILY depends of quant rules stored in exactly the same
459  order they are entered. So if the cleanup or rearrangement is done in
460  the future make a flag for add_rule whether or not to do it, then
461  quant will not set this flag.
462 
463  \param q pointer to Quant structure which holds quant rules info
464  \param dLow minimum fp value
465  \param dHigh maximum fp value
466  \param cLow minimum value
467  \param cHigh maximum value
468  */
470  CELL cHigh)
471 {
472  int i;
473  struct Quant_table *p;
474 
475  quant_table_increase(q);
476 
477  i = q->nofRules;
478 
479  p = &(q->table[i]);
480  if (dHigh >= dLow) {
481  p->dLow = dLow;
482  p->dHigh = dHigh;
483  p->cLow = cLow;
484  p->cHigh = cHigh;
485  }
486  else {
487  p->dLow = dHigh;
488  p->dHigh = dLow;
489  p->cLow = cHigh;
490  p->cHigh = cLow;
491  }
492 
493  /* destroy lookup table, it has to be rebuilt */
494  if (q->fp_lookup.active) {
495  G_free(q->fp_lookup.vals);
496  G_free(q->fp_lookup.rules);
497  q->fp_lookup.active = 0;
498  q->fp_lookup.nalloc = 0;
499  }
500 
501  quant_update_limits(q, dLow, dHigh, cLow, cHigh);
502 
503  q->nofRules++;
504 }
505 
506 /*!
507  \brief Rreverses the order in which the qunatization rules are stored.
508 
509  See also Rast_quant_get_ith_rule() and Rast_quant_perform_d()).
510 
511  \param q pointer to Quant rules which holds quant rules info
512  */
514 {
515  struct Quant_table tmp;
516  struct Quant_table *pLeft, *pRight;
517 
518  pLeft = q->table;
519  pRight = &(q->table[q->nofRules - 1]);
520 
521  while (pLeft < pRight) {
522  tmp.dLow = pLeft->dLow;
523  tmp.dHigh = pLeft->dHigh;
524  tmp.cLow = pLeft->cLow;
525  tmp.cHigh = pLeft->cHigh;
526 
527  pLeft->dLow = pRight->dLow;
528  pLeft->dHigh = pRight->dHigh;
529  pLeft->cLow = pRight->cLow;
530  pLeft->cHigh = pRight->cHigh;
531 
532  pRight->dLow = tmp.dLow;
533  pRight->dHigh = tmp.dHigh;
534  pRight->cLow = tmp.cLow;
535  pRight->cHigh = tmp.cHigh;
536 
537  pLeft++;
538  pRight--;
539  }
540 }
541 
542 static CELL quant_interpolate(DCELL dLow, DCELL dHigh, CELL cLow, CELL cHigh,
543  DCELL dValue)
544 {
545  if (cLow == cHigh)
546  return cLow;
547  if (dLow == dHigh)
548  return cLow;
549 
550  return (CELL)((dValue - dLow) / (dHigh - dLow) * (DCELL)(cHigh - cLow) +
551  (DCELL)cLow);
552 }
553 
554 static int less_or_equal(double x, double y)
555 {
556  if (x <= y)
557  return 1;
558  else
559  return 0;
560 }
561 
562 static int less(double x, double y)
563 {
564  if (x < y)
565  return 1;
566  else
567  return 0;
568 }
569 
570 /*!
571  * \brief
572  *
573  *
574  * Returns a CELL category for the floating-point <i>value</i> based
575  * on the quantization rules in <i>q</i>. The first rule found that
576  * applies is used. The rules are searched in the reverse order they
577  * are added to <i>q</i>. If no rule is found, the <i>value</i>
578  * is first tested against the negative infinite rule, and finally
579  * against the positive infinite rule. If none of these rules apply,
580  * the NULL-value is returned.
581  *
582  * <b>Note:</b> See G_quant_organize_fp_lookup() for details on how
583  * the values are looked up from fp_lookup table when it is
584  * active. Right now fp_lookup is automatically organized during the
585  * first call to Rast_quant_get_cell_value().
586  *
587  * \param q pointer to Quant structure which holds quant rules info
588  * \param dcellValue fp cell value
589  *
590  * \return cell value (integer)
591  */
593 {
594  CELL tmp;
595  DCELL dtmp;
596  int try, min_ind, max_ind;
597  struct Quant_table *p;
598  int (*lower)(double, double);
599 
600  dtmp = dcellVal;
601  /* I know the functions which call me already check for null values,
602  but I am a public function, and can be called from outside */
603  if (Rast_is_d_null_value(&dtmp))
604  return NO_DATA;
605 
606  if (q->truncate_only)
607  return (CELL)dtmp;
608 
609  if (q->round_only) {
610  if (dcellVal > 0)
611  return (CELL)(dcellVal + .5);
612  return (CELL)(dcellVal - .5);
613  }
614 
615  if (NO_EXPLICIT_RULE)
616  return NO_DATA;
617  if (NO_EXPLICIT_RULE)
618  return NO_DATA;
619 
620  if (USE_LOOKUP &&
622  /* first check if values fall within range */
623  /* if value is below the range */
624  if (dcellVal < q->fp_lookup.vals[0]) {
625  if (dcellVal <= q->fp_lookup.inf_dmin)
626  return q->fp_lookup.inf_min;
627  else
628  return NO_DATA;
629  }
630  /* if value is below above range */
631  if (dcellVal > q->fp_lookup.vals[q->fp_lookup.nalloc - 1]) {
632  if (dcellVal >= q->fp_lookup.inf_dmax)
633  return q->fp_lookup.inf_max;
634  else
635  return NO_DATA;
636  }
637  /* make binary search to find which interval our value belongs to
638  and apply the rule for this interval */
639  try = (q->fp_lookup.nalloc - 1) / 2;
640  min_ind = 0;
641  max_ind = q->fp_lookup.nalloc - 2;
642  while (1) {
643  /* DEBUG
644  fprintf (stderr, "%d %d %d\n", min_ind, max_ind, try);
645  */
646  /* when the ruke for the interval is NULL, we exclude the end
647  points. when it exists, we include the end-points */
648  if (q->fp_lookup.rules[try])
649  lower = less;
650  else
651  lower = less_or_equal;
652 
653  if (lower(q->fp_lookup.vals[try + 1],
654  dcellVal)) { /* recurse to the second half */
655  min_ind = try + 1;
656  /* must be still < nalloc-1, since number is within the range */
657  try = (max_ind + min_ind) / 2;
658  continue;
659  }
660  if (lower(
661  dcellVal,
662  q->fp_lookup.vals[try])) { /* recurse to the second half */
663  max_ind = try - 1;
664  /* must be still >= 0, since number is within the range */
665  try = (max_ind + min_ind) / 2;
666  continue;
667  }
668  /* the value fits into the interval! */
669  p = q->fp_lookup.rules[try];
670  if (p)
671  return quant_interpolate(p->dLow, p->dHigh, p->cLow, p->cHigh,
672  dcellVal);
673  /* otherwise when finite rule for this interval doesn't exist */
674  else { /* first check if maybe infinite rule applies */
675  if (dcellVal <= q->fp_lookup.inf_dmin)
676  return q->fp_lookup.inf_min;
677  if (dcellVal >= q->fp_lookup.inf_dmax)
678  return q->fp_lookup.inf_max;
679  else
680  return NO_DATA;
681  }
682  } /* while */
683  } /* looking up in fp_lookup */
684 
685  if (!NO_FINITE_RULE) {
686  p = Rast__quant_get_rule_for_d_raster_val(q, dcellVal);
687  if (!p)
688  return NO_DATA;
689  return quant_interpolate(p->dLow, p->dHigh, p->cLow, p->cHigh,
690  dcellVal);
691  }
692 
693  if ((!NO_LEFT_INFINITE_RULE) && (dcellVal <= q->infiniteDLeft))
694  return q->infiniteCLeft;
695 
696  if ((NO_RIGHT_INFINITE_RULE) || (dcellVal < q->infiniteDRight))
697  return NO_DATA;
698 
699  return q->infiniteCRight;
700 }
701 
702 /*!
703  \brief Returns in "cell" the quantized CELL values.
704 
705  Returns in "cell" the quantized CELL values corresponding to the
706  DCELL values stored in "dcell". the number of elements quantized
707  is n. quantization is performed by repeated application of
708  Rast_quant_get_cell_value().
709 
710  \param q pointer to Quant structure which holds quant rules info
711  \param dcell pointer to fp cell values array
712  \param[out] cell pointer cell values array
713  \param n number of cells
714  */
715 void Rast_quant_perform_d(struct Quant *q, const DCELL *dcell, CELL *cell,
716  int n)
717 {
718  int i;
719 
720  for (i = 0; i < n; i++, dcell++)
721  if (!Rast_is_d_null_value(dcell))
722  *cell++ = Rast_quant_get_cell_value(q, *dcell);
723  else
724  Rast_set_c_null_value(cell++, 1);
725 }
726 
727 /*!
728  \brief Same as Rast_quant_perform_d(), except the type.
729 
730  \param q pointer to Quant structure which holds quant rules info
731  \param fcell pointer to fp cell values array
732  \param[out] cell pointer cell values array
733  \param n number of cells
734  */
735 void Rast_quant_perform_f(struct Quant *q, const FCELL *fcell, CELL *cell,
736  int n)
737 {
738  int i;
739 
740  for (i = 0; i < n; i++, fcell++)
741  if (!Rast_is_f_null_value(fcell))
742  *cell++ = Rast_quant_get_cell_value(q, (DCELL)*fcell);
743  else
744  Rast_set_c_null_value(cell++, 1);
745 }
746 
747 static int double_comp(const void *xx, const void *yy)
748 {
749  const DCELL *x = xx;
750  const DCELL *y = yy;
751 
752  if (Rast_is_d_null_value(x))
753  return 0;
754  if (*x < *y)
755  return -1;
756  else if (*x == *y)
757  return 0;
758  else
759  return 1;
760 }
761 
762 /*!
763  \brief Returns quant rule which will be applied.
764 
765  Returns quant rule which will be applied when looking up the integer
766  quant value for val (used when organizing fp_lookup).
767 
768  \param q pointer to Quant structure which holds quant rules info
769  \param val fp cell value
770 
771  \return pointer to the Quant_table (color rule)
772  \return NULL otherwise
773  */
775  DCELL val)
776 {
777  const struct Quant_table *p;
778 
779  for (p = &(q->table[q->nofRules - 1]); p >= q->table; p--)
780  if ((val >= p->dLow) && (val <= p->dHigh))
781  break;
782  if (p >= q->table)
783  return (struct Quant_table *)p;
784  else
785  return (struct Quant_table *)NULL;
786 }
#define NULL
Definition: ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
#define G_realloc(p, n)
Definition: defs/gis.h:96
#define G_calloc(m, n)
Definition: defs/gis.h:95
#define G_malloc(n)
Definition: defs/gis.h:94
#define Rast_is_f_null_value(fcellVal)
Definition: defs/raster.h:403
void Rast_set_d_null_value(DCELL *, int)
To set a number of DCELL raster values to NULL.
Definition: null_val.c:153
void Rast_set_c_null_value(CELL *, int)
To set a number of CELL raster values to NULL.
Definition: null_val.c:124
#define Rast_is_d_null_value(dcellVal)
Definition: defs/raster.h:405
#define MIN(a, b)
Definition: gis.h:154
float FCELL
Definition: gis.h:627
double DCELL
Definition: gis.h:626
int CELL
Definition: gis.h:625
#define MAX(a, b)
Definition: gis.h:149
#define NO_LEFT_INFINITE_RULE
Definition: quant.c:30
void Rast_quant_free(struct Quant *q)
Resets and frees allocated memory.
Definition: quant.c:55
#define MAX_LOOKUP_TABLE_SIZE
Definition: quant.c:27
#define NO_RIGHT_INFINITE_RULE
Definition: quant.c:31
void Rast_quant_get_ith_rule(const struct Quant *q, int i, DCELL *dLow, DCELL *dHigh, CELL *cLow, CELL *cHigh)
Returns the i'th quantization rule.
Definition: quant.c:327
int Rast_quant_is_truncate(const struct Quant *quant)
Returns whether or not quant rules are set to truncate map.
Definition: quant.c:192
int Rast__quant_organize_fp_lookup(struct Quant *q)
Organized fp_lookup table.
Definition: quant.c:90
#define USE_LOOKUP
Definition: quant.c:26
void Rast_quant_init(struct Quant *quant)
Initialize the structure.
Definition: quant.c:175
void Rast_quant_round(struct Quant *quant)
Sets the quant rules to perform simple rounding on floats.
Definition: quant.c:230
void Rast_quant_perform_d(struct Quant *q, const DCELL *dcell, CELL *cell, int n)
Returns in "cell" the quantized CELL values.
Definition: quant.c:715
#define NO_EXPLICIT_RULE
Definition: quant.c:33
void Rast_quant_add_rule(struct Quant *q, DCELL dLow, DCELL dHigh, CELL cLow, CELL cHigh)
Adds a new rule to the set of quantization rules.
Definition: quant.c:469
int Rast_quant_get_neg_infinite_rule(const struct Quant *q, DCELL *dLeft, CELL *c)
Returns in "dLeft" and "c" the rule values.
Definition: quant.c:390
void Rast_quant_perform_f(struct Quant *q, const FCELL *fcell, CELL *cell, int n)
Same as Rast_quant_perform_d(), except the type.
Definition: quant.c:735
void Rast_quant_set_neg_infinite_rule(struct Quant *q, DCELL dLeft, CELL c)
Defines a rule for values "dLeft" and smaller.
Definition: quant.c:364
void Rast_quant_truncate(struct Quant *quant)
Sets the quant rules to perform simple truncation on floats.
Definition: quant.c:217
#define NO_FINITE_RULE
Definition: quant.c:32
#define NO_DATA
Definition: quant.c:28
int Rast_quant_get_pos_infinite_rule(const struct Quant *q, DCELL *dRight, CELL *c)
Returns in "dRight" and "c" the rule values.
Definition: quant.c:438
struct Quant_table * Rast__quant_get_rule_for_d_raster_val(const struct Quant *q, DCELL val)
Returns quant rule which will be applied.
Definition: quant.c:774
int Rast_quant_get_limits(const struct Quant *q, DCELL *dMin, DCELL *dMax, CELL *cMin, CELL *cMax)
Returns the minimum and maximum cell and dcell values of all the ranges defined.
Definition: quant.c:281
void Rast_quant_clear(struct Quant *q)
Resets the number of defined rules and number of infinite rules to 0.
Definition: quant.c:41
int Rast_quant_nof_rules(const struct Quant *q)
Returns the number of quantization rules defined.
Definition: quant.c:309
void Rast_quant_reverse_rule_order(struct Quant *q)
Rreverses the order in which the qunatization rules are stored.
Definition: quant.c:513
CELL Rast_quant_get_cell_value(struct Quant *q, DCELL dcellVal)
Returns a CELL category for the floating-point value based on the quantization rules in q....
Definition: quant.c:592
void Rast_quant_set_pos_infinite_rule(struct Quant *q, DCELL dRight, CELL c)
Defines a rule for values "dRight" and larger.
Definition: quant.c:412
int Rast_quant_is_round(const struct Quant *quant)
Returns whether or not quant rules are set to round map.
Definition: quant.c:204
DCELL dLow
Definition: raster.h:74
CELL cHigh
Definition: raster.h:77
CELL cLow
Definition: raster.h:76
DCELL dHigh
Definition: raster.h:75
Definition: raster.h:80
CELL inf_min
Definition: raster.h:113
DCELL dMin
Definition: raster.h:98
struct Quant_table ** rules
Definition: raster.h:108
int nalloc
Definition: raster.h:109
DCELL inf_dmin
Definition: raster.h:111
int truncate_only
Definition: raster.h:81
int nofRules
Definition: raster.h:89
struct Quant_table * table
Definition: raster.h:102
DCELL * vals
Definition: raster.h:105
int maxNofRules
Definition: raster.h:88
CELL cMin
Definition: raster.h:100
DCELL inf_dmax
Definition: raster.h:112
CELL cMax
Definition: raster.h:101
CELL inf_max
Definition: raster.h:114
DCELL infiniteDLeft
Definition: raster.h:94
DCELL infiniteDRight
Definition: raster.h:95
int round_only
Definition: raster.h:82
int infiniteRightSet
Definition: raster.h:86
CELL infiniteCLeft
Definition: raster.h:96
CELL infiniteCRight
Definition: raster.h:97
int infiniteLeftSet
Definition: raster.h:85
struct Quant::@5 fp_lookup
DCELL dMax
Definition: raster.h:99
int active
Definition: raster.h:110
#define x