286 #include <grass/gis.h>
289 static int double_comp(
const void *,
const void *);
292 #define MAX_LOOKUP_TABLE_SIZE 2048
293 #define NO_DATA (G_set_c_null_value (&tmp, 1), (CELL) tmp)
297 #define MIN(a,b) ((a) < (b) ? (a) : (b))
298 #define MAX(a,b) ((a) > (b) ? (a) : (b))
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)
311 q->infiniteRightSet = q->infiniteLeftSet = 0;
320 if (q->maxNofRules > 0)
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;
338 struct Quant_table *p;
342 if (q->nofRules == 0)
344 q->fp_lookup.vals = (DCELL *)
345 G_calloc(q->nofRules * 2,
sizeof(DCELL));
347 q->fp_lookup.rules = (
struct Quant_table **)
348 G_calloc(q->nofRules * 2,
sizeof(
struct Quant_table *));
358 for (p = &(q->table[q->nofRules - 1]); p >= q->table; p--) {
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;
364 q->fp_lookup.nalloc = i;
367 qsort((
char *)q->fp_lookup.vals, q->fp_lookup.nalloc,
368 sizeof(DCELL), double_comp);
371 for (i = 0; i < q->fp_lookup.nalloc - 1; i++) {
375 val = (q->fp_lookup.vals[i] + q->fp_lookup.vals[i + 1]) / 2.;
376 q->fp_lookup.rules[i] =
388 q->fp_lookup.inf_dmin = q->infiniteDLeft;
389 q->fp_lookup.inf_min = q->infiniteCLeft;
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;
398 if (q->fp_lookup.nalloc)
399 q->fp_lookup.inf_dmax = q->infiniteDRight;
400 q->fp_lookup.inf_max = q->infiniteCRight;
403 q->fp_lookup.inf_dmax = q->fp_lookup.vals[q->fp_lookup.nalloc - 1];
404 q->fp_lookup.inf_max =
NO_DATA;
406 q->fp_lookup.active = 1;
424 quant->fp_lookup.active = 0;
425 quant->maxNofRules = 0;
426 quant->truncate_only = 0;
427 quant->round_only = 0;
437 return quant->truncate_only;
444 return quant->round_only;
473 quant->truncate_only = 1;
481 quant->round_only = 1;
487 static void quant_set_limits(
struct Quant *
q,
488 DCELL dLow, DCELL dHigh, CELL cLow, CELL cHigh)
498 static void quant_update_limits(
struct Quant *
q,
499 DCELL dLow, DCELL dHigh,
500 CELL cLow, DCELL cHigh)
503 quant_set_limits(q, dLow, dHigh, cLow, cHigh);
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));
535 DCELL * dMin, DCELL * dMax, CELL * cMin, CELL * cMax)
564 DCELL * dLow, DCELL * dHigh,
565 CELL * cLow, CELL * cHigh)
567 *dLow = q->table[i].dLow;
568 *dHigh = q->table[i].dHigh;
569 *cLow = q->table[i].cLow;
570 *cHigh = q->table[i].cHigh;
575 static void quant_table_increase(
struct Quant *q)
577 if (q->nofRules < q->maxNofRules)
580 if (q->maxNofRules == 0) {
582 q->table = (
struct Quant_table *)
583 G_malloc(q->maxNofRules *
sizeof(
struct Quant_table));
586 q->maxNofRules += 50;
587 q->table = (
struct Quant_table *)
588 G_realloc((
char *)q->table,
589 q->maxNofRules *
sizeof(
struct Quant_table));
597 q->infiniteDLeft = dLeft;
598 q->infiniteCLeft = c;
599 quant_update_limits(q, dLeft, dLeft, c, c);
602 if (q->fp_lookup.active) {
603 q->fp_lookup.inf_dmin = q->infiniteDLeft;
604 q->fp_lookup.inf_min = q->infiniteCLeft;
606 q->infiniteLeftSet = 1;
612 DCELL * dLeft, CELL * c)
614 if (q->infiniteLeftSet == 0)
617 *dLeft = q->infiniteDLeft;
618 *c = q->infiniteCLeft;
627 q->infiniteDRight = dRight;
628 q->infiniteCRight = c;
629 quant_update_limits(q, dRight, dRight, c, c);
632 if (q->fp_lookup.active) {
633 q->fp_lookup.inf_dmax = q->infiniteDRight;
634 q->fp_lookup.inf_max = q->infiniteCRight;
636 q->infiniteRightSet = 1;
642 DCELL * dRight, CELL * c)
644 if (q->infiniteRightSet == 0)
647 *dRight = q->infiniteDRight;
648 *c = q->infiniteCRight;
656 DCELL dLow, DCELL dHigh, CELL cLow, CELL cHigh)
659 struct Quant_table *p;
661 quant_table_increase(q);
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;
687 quant_update_limits(q, dLow, dHigh, cLow, cHigh);
696 struct Quant_table tmp;
697 struct Quant_table *pLeft, *pRight;
700 pRight = &(q->table[q->nofRules - 1]);
702 while (pLeft < pRight) {
703 tmp.dLow = pLeft->dLow;
704 tmp.dHigh = pLeft->dHigh;
705 tmp.cLow = pLeft->cLow;
706 tmp.cHigh = pLeft->cHigh;
708 pLeft->dLow = pRight->dLow;
709 pLeft->dHigh = pRight->dHigh;
710 pLeft->cLow = pRight->cLow;
711 pLeft->cHigh = pRight->cHigh;
713 pRight->dLow = tmp.dLow;
714 pRight->dHigh = tmp.dHigh;
715 pRight->cLow = tmp.cLow;
716 pRight->cHigh = tmp.cHigh;
725 static CELL quant_interpolate(DCELL dLow, DCELL dHigh,
726 CELL cLow, CELL cHigh, DCELL dValue)
733 return (CELL) ((dValue - dLow) / (dHigh - dLow) * (DCELL) (cHigh - cLow) +
738 static int less_or_equal(
double x,
double y)
746 static int less(
double x,
double y)
779 int try, min_ind, max_ind;
780 struct Quant_table *p;
789 if (q->truncate_only)
794 return (CELL) (dcellVal + .5);
795 return (CELL) (dcellVal - .5);
807 if (dcellVal < q->fp_lookup.vals[0]) {
808 if (dcellVal <= q->fp_lookup.inf_dmin)
809 return q->fp_lookup.inf_min;
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;
822 try = (q->fp_lookup.nalloc - 1) / 2;
824 max_ind = q->fp_lookup.nalloc - 2;
831 if (q->fp_lookup.rules[
try])
834 lower = less_or_equal;
836 if (lower(q->fp_lookup.vals[
try + 1], dcellVal)) {
839 try = (max_ind + min_ind) / 2;
842 if (lower(dcellVal, q->fp_lookup.vals[
try])) {
845 try = (max_ind + min_ind) / 2;
849 p = q->fp_lookup.rules[
try];
851 return quant_interpolate(p->dLow, p->dHigh, p->cLow, p->cHigh,
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;
869 return quant_interpolate(p->dLow, p->dHigh, p->cLow, p->cHigh,
874 return q->infiniteCLeft;
879 return q->infiniteCRight;
885 const DCELL * dcell, CELL * cell,
int n)
889 for (i = 0; i <
n; i++, dcell++)
899 const FCELL * fcell, CELL * cell,
int n)
903 for (i = 0; i <
n; i++, fcell++)
912 static int double_comp(
const void *xx,
const void *yy)
932 const struct Quant_table *p;
934 for (p = &(q->table[q->nofRules - 1]); p >= q->table; p--)
935 if ((val >= p->dLow) && (val <= p->dHigh))
938 return (
struct Quant_table *)p;
940 return (
struct Quant_table *)
NULL;
void G_free(void *buf)
Free allocated memory.
void G_quant_free(struct Quant *q)
void G_quant_set_neg_infinite_rule(struct Quant *q, DCELL dLeft, CELL c)
#define NO_RIGHT_INFINITE_RULE
int G_quant_get_neg_infinite_rule(const struct Quant *q, DCELL *dLeft, CELL *c)
void G_set_d_null_value(DCELL *dcellVals, int numVals)
void G_quant_perform_f(struct Quant *q, const FCELL *fcell, CELL *cell, int n)
int G_quant_is_truncate(const struct Quant *quant)
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...
#define NO_LEFT_INFINITE_RULE
void G_quant_get_ith_rule(const struct Quant *q, int i, DCELL *dLow, DCELL *dHigh, CELL *cLow, CELL *cHigh)
struct Quant_table * G__quant_get_rule_for_d_raster_val(const struct Quant *q, DCELL val)
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().
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'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.
#define MAX_LOOKUP_TABLE_SIZE
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 "in...
int G__quant_organize_fp_lookup(struct Quant *q)
int G_quant_is_round(const struct Quant *quant)
void G_quant_reverse_rule_order(struct Quant *q)
int G_quant_nof_rules(const struct Quant *q)
void G_quant_add_rule(struct Quant *q, DCELL dLow, DCELL dHigh, CELL cLow, CELL cHigh)
void G_quant_clear(struct Quant *q)
int G_quant_init(struct Quant *quant)
Initializes the q struct.
void G_set_c_null_value(CELL *cellVals, int numVals)
void G_quant_perform_d(struct Quant *q, const DCELL *dcell, CELL *cell, int n)
void G_quant_set_pos_infinite_rule(struct Quant *q, DCELL dRight, CELL c)
int G_quant_round(struct Quant *quant)
int G_quant_get_pos_infinite_rule(const struct Quant *q, DCELL *dRight, CELL *c)
int G_quant_truncate(struct Quant *quant)
sets the quant for q rules to perform simple truncation on floats.