GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
quant.c
Go to the documentation of this file.
1 
2 /**********************************************************************
3  *
4  * G_quant_init (quant)
5  * struct Quant *quant;
6  *
7  * initializes new quantization structure. calls
8  * G_quant_clear() before it returns.
9  *
10  * note: dies if G_malloc dies.
11  *
12  **********************************************************************
13  *
14  * G_quant_is_truncate (quant)
15  * struct Quant *quant;
16  *
17  * Returns wether or not quant rules are set to truncate map
18  *
19  **********************************************************************
20  *
21  * G_quant_is_round (quant)
22  * struct Quant *quant;
23  *
24  * Returns wether or not quant rules are set to round map
25  *
26  **********************************************************************
27  *
28  * G_quant_truncate (quant)
29  * struct Quant *quant;
30  *
31  * sets the quant rules to perform simple truncation on floats.
32  *
33  **********************************************************************
34  *
35  * G_quant_round (quant)
36  * struct Quant *quant;
37  *
38  * sets the quant rules to perform simple rounding on floats.
39  *
40  **********************************************************************
41  *
42  * G_quant_organize_fp_lookup (quant)
43  * struct Quant *quant;
44  *
45  * Organizes fp_lookup table for faster (logarithmic) lookup time
46  * G_quant_organize_fp_lookup() creates a list of min and max for
47  * each quant rule, sorts this list, and stores the pointer to quant
48  * rule that should be used inbetween any 2 numbers in this list.
49  * Also it stores extreme points for 2 infinite rules, if exist.
50  * After the call to G_quant_organize_fp_lookup()
51  * instead of linearly searching through list of rules to find
52  * a rule to apply, quant lookup will perform a binary search
53  * to find an interval containing floating point value, and then use
54  * the rule associated with this interval.
55  * when the value doesn't fall within any interval, check for the
56  * infinite rules.
57  *
58  **********************************************************************
59  *
60  * void
61  * G_quant_free (q)
62  *
63  * struct Quant *q;
64  *
65  * resets the number of defined rules to 0 and free's space allocated
66  * for rules. calls G_quant_clear ().
67  *
68  **********************************************************************
69  *
70  * void
71  * G_quant_clear (q)
72  *
73  * struct Quant *q;
74  *
75  * resets the number of defined rules and number of infinite rules to 0.
76  *
77  **********************************************************************
78  *
79  * int
80  * G_quant_get_limits (q, dMin, dMax, cMin, cMax)
81  *
82  * struct Quant *q;
83  * DCELL *dMin, *dMax;
84  * CELL *cMin, *cMax;
85  *
86  * returns the minimum and maximum cell and dcell values of all
87  * the ranges defined.
88  *
89  * returns: -1 if q->truncate or q->round are true or
90  after G_quant_init (), or any call to
91  * G_quant_clear () or G_quant_free ()
92  * no explicit rules have been added
93  * In this case the returned minimum and maximum
94  * CELL and DCELL values are null.
95  * 1 otherwise. in this case the values returned correspond
96  * to the extreme values of the defined rules
97  *
98  **********************************************************************
99  *
100  * int
101  * G_quant_nof_rules (q)
102  *
103  * struct Quant *q;
104  *
105  * returns the number of quantization rules defined. This number does
106  * not include the 2 infinite intervals.
107  *
108  **********************************************************************
109  *
110  * void
111  * G_quant_get_ith_rule (q, i, dLow, dHigh, cLow, cHigh)
112  *
113  * struct Quant *q;
114  * int i;
115  * DCELL *dLow, *dHigh;
116  * CELL *cLow, *cHigh;
117  *
118  * returns the i'th quantization rule, for 0 <= i < G_quant_nof_rules().
119  * a larger value for i means that the rule has been added later.
120  *
121  **********************************************************************
122  * void
123  * G_quant_set_neg_infinite_rule (q, dLeft, c)
124  *
125  * struct Quant *q;
126  * DCELL dLeft;
127  * CELL c;
128  *
129  * defines a rule for values "dLeft" and smaller. values in this range
130  * are mapped to "c" if none of the "finite" quantization rules applies.
131  *
132  * **********************************************************************
133  *
134  * int
135  * G_quant_get_neg_infinite_rule (q, dLeft, c)
136  *
137  * struct Quant *q;
138  * DCELL *dLeft;
139  * CELL *c;
140  *
141  * returns in "dLeft" and "c" the rule values for the negative infinite
142  * interval (see G_quant_set_neg_infinite_rule ()).
143  *
144  * returns: 0 if this rule is not defined
145  * 1 otherwise.
146  *
147  * **********************************************************************
148  *
149  * struct Quant_table *
150  * G__quant_get_rule_for_d_raster_val (q, val)
151  *
152  * struct Quant *q;
153  * DCELL val;
154  *
155  * returns quant rule which will be applied when looking up the
156  * integer quant value for val. (used when organizing fp_lookup.
157  *
158  * returns: pointer to the Quant_table (color rule)
159  * NULL otherwise.
160  *
161  **********************************************************************
162  * void
163  * G_quant_set_pos_infinite_rule (q, dRight, c)
164  *
165  * struct Quant *q;
166  * DCELL dRight;
167  * CELL c;
168  *
169  * defines a rule for values "dRight" and larger. values in this range
170  * are mapped to "c" if none of the "finite" quantization rules or the
171  * negative infinite rule applies.
172  *
173  * **********************************************************************
174  *
175  * int
176  * G_quant_get_pos_infinite_rule (q, dRight, c)
177  *
178  * struct Quant *q;
179  * DCELL *dRight;
180  * CELL *c;
181  *
182  * returns in "dRight" and "c" the rule values for the positive infinite
183  * interval (see G_quant_set_pos_infinite_rule ()).
184  *
185  * returns: 0 if this rule is not defined
186  * 1 otherwise.
187  *
188  **********************************************************************
189  *
190  * void
191  * G_quant_reverse_rule_order (q)
192  *
193  * struct Quant *q;
194  *
195  * reverses the order in which the qunatization rules are stored. (see
196  * also G_quant_get_ith_rule () and G_quant_perform_d ()).
197  *
198  **********************************************************************
199  *
200  * void
201  * G_quant_add_rule (q, dLow, dHigh, cLow, cHigh)
202  *
203  * struct Quant *q;
204  * DCELL dLow, dHigh;
205  * CELL cLow, cHigh;
206  *
207  * adds a new rule to the set of quantization rules. if dLow < dHigh
208  * the rule will be stored with the low and high values interchanged.
209  *
210  * Note: currently no cleanup of rules is performed, i.e. redundant
211  * rules are not removed. This can't be changed because Categories
212  * structure HEAVILY depends of quant rules stored in exactly the
213  * same order they are entered. So if the cleanup or rearrangement
214  * is done in the future make a flag for add_rule wether or not
215  * to do it, then quant will not set this flag.
216  *
217  **********************************************************************
218  *
219  * CELL
220  * G_quant_get_cell_value (q, cellValue)
221  *
222  * struct Quant *q;
223  * DCELL *cellValue;
224  *
225  * returns in "cell" the quantized CELL values corresponding to the
226  * DCELL value "cellValue".
227  *
228  * if several quantization rules apply for cellValue, the one which has
229  * been inserted latest (i.e. the one of them which is returned by
230  * G_quant_get_ith_rule() for the largest i) is used. if no such rule
231  * applies the cellValue is first tested against the negative infinite
232  * rule, and finally against the positive infinite rule. if none of
233  * these rules apply, NO_DATA is returned. the actual value of NO_DATA
234  * is found by calling G_c_set_null_value().
235  *
236  * NOTE: see G_quant_organize_fp_lookup() for details on how
237  * the values are looked up from fp_lookup table when it is active.
238  *
239  * if after G_quant_init (), or any call to G_quant_clear () or
240  * G_quant_free () neither G_quant_add_rule (),
241  * G_quant_set_neg_infinite_rule (), G_quant_set_pos_infinite_rule ()
242  * are used NO_DATA is returned independently
243  * of cellValue.
244  *
245  **********************************************************************
246  *
247  * void
248  * G_quant_perform_d (q, dcell, cell, n)
249  *
250  * struct Quant *q;
251  * DCELL *dcell;
252  * CELL *cell;
253  * int n;
254  *
255  * returns in "cell" the quantized CELL values corresponding to the
256  * DCELL values stored in "dcell". the number of elements quantized
257  * is n. quantization is performed by repeated application of
258  * G_quant_get_cell_value ().
259  *
260  **********************************************************************
261  *
262  * void
263  * G_quant_perform_f (q, fcell, cell, n)
264  *
265  * struct Quant *q;
266  * FCELL *fcell;
267  * CELL *cell;
268  * int n;
269  *
270  * same as G_quant_perform_d (), except the type.
271  *
272  **********************************************************************/
273 
274 /*--------------------------------------------------------------------------*/
275 
276 /*
277  the quantization table is stored as a linear array. rules are added starting
278  from index 0. redundant rules are not eliminated. rules are tested from the
279  highest index downto 0. there are two "infinite" rules. support is provided
280  to reverse the order of the rules.
281  */
282 
283 /*--------------------------------------------------------------------------*/
284 
285 #include <stdlib.h>
286 #include <grass/gis.h>
287 
288 /*--------------------------------------------------------------------------*/
289 static int double_comp(const void *, const void *);
290 
291 #define USE_LOOKUP 1
292 #define MAX_LOOKUP_TABLE_SIZE 2048
293 #define NO_DATA (G_set_c_null_value (&tmp, 1), (CELL) tmp)
294 
295 #undef MIN
296 #undef MAX
297 #define MIN(a,b) ((a) < (b) ? (a) : (b))
298 #define MAX(a,b) ((a) > (b) ? (a) : (b))
299 
300 #define NO_LEFT_INFINITE_RULE (! q->infiniteLeftSet)
301 #define NO_RIGHT_INFINITE_RULE (! q->infiniteRightSet)
302 #define NO_FINITE_RULE (q->nofRules <= 0)
303 #define NO_EXPLICIT_RULE (NO_FINITE_RULE && \
304  NO_LEFT_INFINITE_RULE && NO_RIGHT_INFINITE_RULE)
305 
306 /*--------------------------------------------------------------------------*/
307 
308 void G_quant_clear(struct Quant *q)
309 {
310  q->nofRules = 0;
311  q->infiniteRightSet = q->infiniteLeftSet = 0;
312 }
313 
314 /*--------------------------------------------------------------------------*/
315 
316 void G_quant_free(struct Quant *q)
317 {
318  G_quant_clear(q);
319 
320  if (q->maxNofRules > 0)
321  G_free(q->table);
322  if (q->fp_lookup.active) {
323  G_free(q->fp_lookup.vals);
324  G_free(q->fp_lookup.rules);
325  q->fp_lookup.nalloc = 0;
326  q->fp_lookup.active = 0;
327  }
328  q->maxNofRules = 0;
329 }
330 
331 /*--------------------------------------------------------------------------*/
332 
333 int G__quant_organize_fp_lookup(struct Quant *q)
334 {
335  int i;
336  DCELL val;
337  CELL tmp;
338  struct Quant_table *p;
339 
340  if (q->nofRules * 2 > MAX_LOOKUP_TABLE_SIZE)
341  return -1;
342  if (q->nofRules == 0)
343  return -1;
344  q->fp_lookup.vals = (DCELL *)
345  G_calloc(q->nofRules * 2, sizeof(DCELL));
346  /* 2 endpoints for each rule */
347  q->fp_lookup.rules = (struct Quant_table **)
348  G_calloc(q->nofRules * 2, sizeof(struct Quant_table *));
349 
350  /* first we organize finite rules into a table */
351  if (!NO_FINITE_RULE) {
352  i = 0;
353  /* get the list of DCELL values from set of all dLows and dHighs
354  of all rules */
355  /* NOTE: if dLow==DHigh in a rule, the value appears twice in a list
356  but if dLow==DHigh of the previous, rule the value appears only once */
357 
358  for (p = &(q->table[q->nofRules - 1]); p >= q->table; p--) {
359  /* check if the min is the same as previous maximum */
360  if (i == 0 || p->dLow != q->fp_lookup.vals[i - 1])
361  q->fp_lookup.vals[i++] = p->dLow;
362  q->fp_lookup.vals[i++] = p->dHigh;
363  }
364  q->fp_lookup.nalloc = i;
365 
366  /* now sort the values */
367  qsort((char *)q->fp_lookup.vals, q->fp_lookup.nalloc,
368  sizeof(DCELL), double_comp);
369 
370  /* now find the rule to apply inbetween each 2 values in a list */
371  for (i = 0; i < q->fp_lookup.nalloc - 1; i++) {
372  /*debug
373  fprintf (stderr, "%lf %lf ", q->fp_lookup.vals[i], q->fp_lookup.vals[i+1]);
374  */
375  val = (q->fp_lookup.vals[i] + q->fp_lookup.vals[i + 1]) / 2.;
376  q->fp_lookup.rules[i] =
378  /* debug
379  if(q->fp_lookup.rules[i])
380  fprintf (stderr, "%lf %lf %d %d\n", q->fp_lookup.rules[i]->dLow, q->fp_lookup.rules[i]->dHigh, q->fp_lookup.rules[i]->cLow, q->fp_lookup.rules[i]->cHigh);
381  else fprintf (stderr, "null\n");
382  */
383 
384  }
385  } /* organizing finite rules */
386 
387  if (!NO_LEFT_INFINITE_RULE) {
388  q->fp_lookup.inf_dmin = q->infiniteDLeft;
389  q->fp_lookup.inf_min = q->infiniteCLeft;
390  }
391  else {
392  if (q->fp_lookup.nalloc)
393  q->fp_lookup.inf_dmin = q->fp_lookup.vals[0];
394  q->fp_lookup.inf_min = NO_DATA;
395  }
396 
397  if (!NO_RIGHT_INFINITE_RULE) {
398  if (q->fp_lookup.nalloc)
399  q->fp_lookup.inf_dmax = q->infiniteDRight;
400  q->fp_lookup.inf_max = q->infiniteCRight;
401  }
402  else {
403  q->fp_lookup.inf_dmax = q->fp_lookup.vals[q->fp_lookup.nalloc - 1];
404  q->fp_lookup.inf_max = NO_DATA;
405  }
406  q->fp_lookup.active = 1;
407  return 1;
408 }
409 
410 /*--------------------------------------------------------------------------*/
411 
412 
422 int G_quant_init(struct Quant *quant)
423 {
424  quant->fp_lookup.active = 0;
425  quant->maxNofRules = 0;
426  quant->truncate_only = 0;
427  quant->round_only = 0;
428  G_quant_clear(quant);
429 
430  return 1;
431 }
432 
433 /*--------------------------------------------------------------------------*/
434 
435 int G_quant_is_truncate(const struct Quant *quant)
436 {
437  return quant->truncate_only;
438 }
439 
440 /*--------------------------------------------------------------------------*/
441 
442 int G_quant_is_round(const struct Quant *quant)
443 {
444  return quant->round_only;
445 }
446 
447 /*--------------------------------------------------------------------------*/
448 
449 
471 int G_quant_truncate(struct Quant *quant)
472 {
473  quant->truncate_only = 1;
474  return 1;
475 }
476 
477 /*--------------------------------------------------------------------------*/
478 
479 int G_quant_round(struct Quant *quant)
480 {
481  quant->round_only = 1;
482  return 1;
483 }
484 
485 /*--------------------------------------------------------------------------*/
486 
487 static void quant_set_limits(struct Quant *q,
488  DCELL dLow, DCELL dHigh, CELL cLow, CELL cHigh)
489 {
490  q->dMin = dLow;
491  q->dMax = dHigh;
492  q->cMin = cLow;
493  q->cMax = cHigh;
494 }
495 
496 /*--------------------------------------------------------------------------*/
497 
498 static void quant_update_limits(struct Quant *q,
499  DCELL dLow, DCELL dHigh,
500  CELL cLow, DCELL cHigh)
501 {
502  if (NO_EXPLICIT_RULE) {
503  quant_set_limits(q, dLow, dHigh, cLow, cHigh);
504  return;
505  }
506 
507  q->dMin = MIN(q->dMin, MIN(dLow, dHigh));
508  q->dMax = MAX(q->dMax, MAX(dLow, dHigh));
509  q->cMin = MIN(q->cMin, MIN(cLow, cHigh));
510  q->cMax = MAX(q->cMax, MAX(cLow, cHigh));
511 }
512 
513 /*--------------------------------------------------------------------------*/
514 
515 
534 int G_quant_get_limits(const struct Quant *q,
535  DCELL * dMin, DCELL * dMax, CELL * cMin, CELL * cMax)
536 {
537  if (NO_EXPLICIT_RULE) {
538  G_set_c_null_value(cMin, 1);
539  G_set_c_null_value(cMax, 1);
540  G_set_d_null_value(dMin, 1);
541  G_set_d_null_value(dMax, 1);
542  return -1;
543  }
544 
545  *dMin = q->dMin;
546  *dMax = q->dMax;
547  *cMin = q->cMin;
548  *cMax = q->cMax;
549 
550  return 1;
551 }
552 
553 /*--------------------------------------------------------------------------*/
554 
555 int G_quant_nof_rules(const struct Quant *q)
556 {
557  return q->nofRules;
558 }
559 
560 /*--------------------------------------------------------------------------*/
561 
562 void G_quant_get_ith_rule(const struct Quant *q,
563  int i,
564  DCELL * dLow, DCELL * dHigh,
565  CELL * cLow, CELL * cHigh)
566 {
567  *dLow = q->table[i].dLow;
568  *dHigh = q->table[i].dHigh;
569  *cLow = q->table[i].cLow;
570  *cHigh = q->table[i].cHigh;
571 }
572 
573 /*--------------------------------------------------------------------------*/
574 
575 static void quant_table_increase(struct Quant *q)
576 {
577  if (q->nofRules < q->maxNofRules)
578  return;
579 
580  if (q->maxNofRules == 0) {
581  q->maxNofRules = 50;
582  q->table = (struct Quant_table *)
583  G_malloc(q->maxNofRules * sizeof(struct Quant_table));
584  }
585  else {
586  q->maxNofRules += 50;
587  q->table = (struct Quant_table *)
588  G_realloc((char *)q->table,
589  q->maxNofRules * sizeof(struct Quant_table));
590  }
591 }
592 
593 /*--------------------------------------------------------------------------*/
594 
595 void G_quant_set_neg_infinite_rule(struct Quant *q, DCELL dLeft, CELL c)
596 {
597  q->infiniteDLeft = dLeft;
598  q->infiniteCLeft = c;
599  quant_update_limits(q, dLeft, dLeft, c, c);
600 
601  /* update lookup table */
602  if (q->fp_lookup.active) {
603  q->fp_lookup.inf_dmin = q->infiniteDLeft;
604  q->fp_lookup.inf_min = q->infiniteCLeft;
605  }
606  q->infiniteLeftSet = 1;
607 }
608 
609 /*--------------------------------------------------------------------------*/
610 
611 int G_quant_get_neg_infinite_rule(const struct Quant *q,
612  DCELL * dLeft, CELL * c)
613 {
614  if (q->infiniteLeftSet == 0)
615  return 0;
616 
617  *dLeft = q->infiniteDLeft;
618  *c = q->infiniteCLeft;
619 
620  return 1;
621 }
622 
623 /*--------------------------------------------------------------------------*/
624 
625 void G_quant_set_pos_infinite_rule(struct Quant *q, DCELL dRight, CELL c)
626 {
627  q->infiniteDRight = dRight;
628  q->infiniteCRight = c;
629  quant_update_limits(q, dRight, dRight, c, c);
630 
631  /* update lookup table */
632  if (q->fp_lookup.active) {
633  q->fp_lookup.inf_dmax = q->infiniteDRight;
634  q->fp_lookup.inf_max = q->infiniteCRight;
635  }
636  q->infiniteRightSet = 1;
637 }
638 
639 /*--------------------------------------------------------------------------*/
640 
641 int G_quant_get_pos_infinite_rule(const struct Quant *q,
642  DCELL * dRight, CELL * c)
643 {
644  if (q->infiniteRightSet == 0)
645  return 0;
646 
647  *dRight = q->infiniteDRight;
648  *c = q->infiniteCRight;
649 
650  return 1;
651 }
652 
653 /*--------------------------------------------------------------------------*/
654 
655 void G_quant_add_rule(struct Quant *q,
656  DCELL dLow, DCELL dHigh, CELL cLow, CELL cHigh)
657 {
658  int i;
659  struct Quant_table *p;
660 
661  quant_table_increase(q);
662 
663  i = q->nofRules;
664 
665  p = &(q->table[i]);
666  if (dHigh >= dLow) {
667  p->dLow = dLow;
668  p->dHigh = dHigh;
669  p->cLow = cLow;
670  p->cHigh = cHigh;
671  }
672  else {
673  p->dLow = dHigh;
674  p->dHigh = dLow;
675  p->cLow = cHigh;
676  p->cHigh = cLow;
677  }
678 
679  /* destroy lookup table, it has to be rebuilt */
680  if (q->fp_lookup.active) {
681  G_free(q->fp_lookup.vals);
682  G_free(q->fp_lookup.rules);
683  q->fp_lookup.active = 0;
684  q->fp_lookup.nalloc = 0;
685  }
686 
687  quant_update_limits(q, dLow, dHigh, cLow, cHigh);
688 
689  q->nofRules++;
690 }
691 
692 /*--------------------------------------------------------------------------*/
693 
694 void G_quant_reverse_rule_order(struct Quant *q)
695 {
696  struct Quant_table tmp;
697  struct Quant_table *pLeft, *pRight;
698 
699  pLeft = q->table;
700  pRight = &(q->table[q->nofRules - 1]);
701 
702  while (pLeft < pRight) {
703  tmp.dLow = pLeft->dLow;
704  tmp.dHigh = pLeft->dHigh;
705  tmp.cLow = pLeft->cLow;
706  tmp.cHigh = pLeft->cHigh;
707 
708  pLeft->dLow = pRight->dLow;
709  pLeft->dHigh = pRight->dHigh;
710  pLeft->cLow = pRight->cLow;
711  pLeft->cHigh = pRight->cHigh;
712 
713  pRight->dLow = tmp.dLow;
714  pRight->dHigh = tmp.dHigh;
715  pRight->cLow = tmp.cLow;
716  pRight->cHigh = tmp.cHigh;
717 
718  pLeft++;
719  pRight--;
720  }
721 }
722 
723 /*--------------------------------------------------------------------------*/
724 
725 static CELL quant_interpolate(DCELL dLow, DCELL dHigh,
726  CELL cLow, CELL cHigh, DCELL dValue)
727 {
728  if (cLow == cHigh)
729  return cLow;
730  if (dLow == dHigh)
731  return cLow;
732 
733  return (CELL) ((dValue - dLow) / (dHigh - dLow) * (DCELL) (cHigh - cLow) +
734  (DCELL) cLow);
735 }
736 
737 /*--------------------------------------------------------------------------*/
738 static int less_or_equal(double x, double y)
739 {
740  if (x <= y)
741  return 1;
742  else
743  return 0;
744 }
745 
746 static int less(double x, double y)
747 {
748  if (x < y)
749  return 1;
750  else
751  return 0;
752 }
753 
754 
775 CELL G_quant_get_cell_value(struct Quant * q, DCELL dcellVal)
776 {
777  CELL tmp;
778  DCELL dtmp;
779  int try, min_ind, max_ind;
780  struct Quant_table *p;
781  int (*lower) ();
782 
783  dtmp = dcellVal;
784  /* I know the functions which call me already check for null values,
785  but I am a public function, and can be called from outside */
786  if (G_is_d_null_value(&dtmp))
787  return NO_DATA;
788 
789  if (q->truncate_only)
790  return (CELL) dtmp;
791 
792  if (q->round_only) {
793  if (dcellVal > 0)
794  return (CELL) (dcellVal + .5);
795  return (CELL) (dcellVal - .5);
796  }
797 
798  if (NO_EXPLICIT_RULE)
799  return NO_DATA;
800  if (NO_EXPLICIT_RULE)
801  return NO_DATA;
802 
803  if (USE_LOOKUP &&
804  (q->fp_lookup.active || G__quant_organize_fp_lookup(q) > 0)) {
805  /* first check if values fall within range */
806  /* if value is below the range */
807  if (dcellVal < q->fp_lookup.vals[0]) {
808  if (dcellVal <= q->fp_lookup.inf_dmin)
809  return q->fp_lookup.inf_min;
810  else
811  return NO_DATA;
812  }
813  /* if value is below above range */
814  if (dcellVal > q->fp_lookup.vals[q->fp_lookup.nalloc - 1]) {
815  if (dcellVal >= q->fp_lookup.inf_dmax)
816  return q->fp_lookup.inf_max;
817  else
818  return NO_DATA;
819  }
820  /* make binary search to find which interval our value belongs to
821  and apply the rule for this interval */
822  try = (q->fp_lookup.nalloc - 1) / 2;
823  min_ind = 0;
824  max_ind = q->fp_lookup.nalloc - 2;
825  while (1) {
826  /* DEBUG
827  fprintf (stderr, "%d %d %d\n", min_ind, max_ind, try);
828  */
829  /* when the ruke for the interval is NULL, we exclude the end points.
830  when it exists, we include the end-points */
831  if (q->fp_lookup.rules[try])
832  lower = less;
833  else
834  lower = less_or_equal;
835 
836  if (lower(q->fp_lookup.vals[try + 1], dcellVal)) { /* recurse to the second half */
837  min_ind = try + 1;
838  /* must be still < nalloc-1, since number is within the range */
839  try = (max_ind + min_ind) / 2;
840  continue;
841  }
842  if (lower(dcellVal, q->fp_lookup.vals[try])) { /* recurse to the second half */
843  max_ind = try - 1;
844  /* must be still >= 0, since number is within the range */
845  try = (max_ind + min_ind) / 2;
846  continue;
847  }
848  /* the value fits into the interval! */
849  p = q->fp_lookup.rules[try];
850  if (p)
851  return quant_interpolate(p->dLow, p->dHigh, p->cLow, p->cHigh,
852  dcellVal);
853  /* otherwise when finite rule for this interval doesn't exist */
854  else { /* first check if maybe infinite rule applies */
855  if (dcellVal <= q->fp_lookup.inf_dmin)
856  return q->fp_lookup.inf_min;
857  if (dcellVal >= q->fp_lookup.inf_dmax)
858  return q->fp_lookup.inf_max;
859  else
860  return NO_DATA;
861  }
862  } /* while */
863  } /* looking up in fp_lookup */
864 
865  if (!NO_FINITE_RULE) {
866  p = G__quant_get_rule_for_d_raster_val(q, dcellVal);
867  if (!p)
868  return NO_DATA;
869  return quant_interpolate(p->dLow, p->dHigh, p->cLow, p->cHigh,
870  dcellVal);
871  }
872 
873  if ((!NO_LEFT_INFINITE_RULE) && (dcellVal <= q->infiniteDLeft))
874  return q->infiniteCLeft;
875 
876  if ((NO_RIGHT_INFINITE_RULE) || (dcellVal < q->infiniteDRight))
877  return NO_DATA;
878 
879  return q->infiniteCRight;
880 }
881 
882 /*--------------------------------------------------------------------------*/
883 
884 void G_quant_perform_d(struct Quant *q,
885  const DCELL * dcell, CELL * cell, int n)
886 {
887  int i;
888 
889  for (i = 0; i < n; i++, dcell++)
890  if (!G_is_d_null_value(dcell))
891  *cell++ = G_quant_get_cell_value(q, *dcell);
892  else
893  G_set_c_null_value(cell++, 1);
894 }
895 
896 /*--------------------------------------------------------------------------*/
897 
898 void G_quant_perform_f(struct Quant *q,
899  const FCELL * fcell, CELL * cell, int n)
900 {
901  int i;
902 
903  for (i = 0; i < n; i++, fcell++)
904  if (!G_is_f_null_value(fcell))
905  *cell++ = G_quant_get_cell_value(q, (DCELL) * fcell);
906  else
907  G_set_c_null_value(cell++, 1);
908 }
909 
910 /*--------------------------------------------------------------------------*/
911 
912 static int double_comp(const void *xx, const void *yy)
913 {
914  const DCELL *x = xx;
915  const DCELL *y = yy;
916 
917  if (G_is_d_null_value(x))
918  return 0;
919  if (*x < *y)
920  return -1;
921  else if (*x == *y)
922  return 0;
923  else
924  return 1;
925 }
926 
927 /*--------------------------------------------------------------------------*/
928 
929 struct Quant_table *G__quant_get_rule_for_d_raster_val(const struct Quant *q,
930  DCELL val)
931 {
932  const struct Quant_table *p;
933 
934  for (p = &(q->table[q->nofRules - 1]); p >= q->table; p--)
935  if ((val >= p->dLow) && (val <= p->dHigh))
936  break;
937  if (p >= q->table)
938  return (struct Quant_table *)p;
939  else
940  return (struct Quant_table *)NULL;
941 }
942 
943 /*--------------------------------------------------------------------------*/
944 
945 /*--------------------------------------------------------------------------*/
946 
947 /*--------------------------------------------------------------------------*/
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:142
#define USE_LOOKUP
Definition: quant.c:291
void G_quant_free(struct Quant *q)
Definition: quant.c:316
void G_quant_set_neg_infinite_rule(struct Quant *q, DCELL dLeft, CELL c)
Definition: quant.c:595
#define NO_RIGHT_INFINITE_RULE
Definition: quant.c:301
tuple q
Definition: forms.py:2019
int G_quant_get_neg_infinite_rule(const struct Quant *q, DCELL *dLeft, CELL *c)
Definition: quant.c:611
void G_set_d_null_value(DCELL *dcellVals, int numVals)
Definition: null_val.c:176
void G_quant_perform_f(struct Quant *q, const FCELL *fcell, CELL *cell, int n)
Definition: quant.c:898
int G_quant_is_truncate(const struct Quant *quant)
Definition: quant.c:435
CELL G_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:775
#define NO_LEFT_INFINITE_RULE
Definition: quant.c:300
int y
Definition: plot.c:34
void G_quant_get_ith_rule(const struct Quant *q, int i, DCELL *dLow, DCELL *dHigh, CELL *cLow, CELL *cHigh)
Definition: quant.c:562
#define NO_FINITE_RULE
Definition: quant.c:302
#define NO_EXPLICIT_RULE
Definition: quant.c:303
struct Quant_table * G__quant_get_rule_for_d_raster_val(const struct Quant *q, DCELL val)
Definition: quant.c:929
int G_is_d_null_value(const DCELL *dcellVal)
Returns 1 if dcell is NULL, 0 otherwise. This will test if the value dcell is a NaN. Same test as in G_is_f_null_value().
Definition: null_val.c:306
int G_is_f_null_value(const FCELL *fcellVal)
Returns 1 if fcell is NULL, 0 otherwise. This will test if the value fcell is a NaN. It isn&#39;t good enough to test for a particular NaN bit pattern since the machine code may change this bit pattern to a different NaN. The test will be.
Definition: null_val.c:281
#define MAX_LOOKUP_TABLE_SIZE
Definition: quant.c:292
int G_quant_get_limits(const struct Quant *q, DCELL *dMin, DCELL *dMax, CELL *cMin, CELL *cMax)
Extracts the minimum and maximum floating-point and integer values from all the rules (except the &quot;in...
Definition: quant.c:534
#define NO_DATA
Definition: quant.c:293
int G__quant_organize_fp_lookup(struct Quant *q)
Definition: quant.c:333
int
Definition: g3dcolor.c:48
int G_quant_is_round(const struct Quant *quant)
Definition: quant.c:442
void G_quant_reverse_rule_order(struct Quant *q)
Definition: quant.c:694
int G_quant_nof_rules(const struct Quant *q)
Definition: quant.c:555
void G_quant_add_rule(struct Quant *q, DCELL dLow, DCELL dHigh, CELL cLow, CELL cHigh)
Definition: quant.c:655
return NULL
Definition: dbfopen.c:1394
#define MIN(a, b)
Definition: quant.c:297
void G_quant_clear(struct Quant *q)
Definition: quant.c:308
int G_quant_init(struct Quant *quant)
Initializes the q struct.
Definition: quant.c:422
#define MAX(a, b)
Definition: quant.c:298
void G_set_c_null_value(CELL *cellVals, int numVals)
Definition: null_val.c:142
void G_quant_perform_d(struct Quant *q, const DCELL *dcell, CELL *cell, int n)
Definition: quant.c:884
void G_quant_set_pos_infinite_rule(struct Quant *q, DCELL dRight, CELL c)
Definition: quant.c:625
int n
Definition: dataquad.c:291
int G_quant_round(struct Quant *quant)
Definition: quant.c:479
int G_quant_get_pos_infinite_rule(const struct Quant *q, DCELL *dRight, CELL *c)
Definition: quant.c:641
int G_quant_truncate(struct Quant *quant)
sets the quant for q rules to perform simple truncation on floats.
Definition: quant.c:471