gvsig-raster / libjni-potrace / trunk / libjni-potrace / src / main / native / jpotrace / progress.h @ 1780
History | View | Annotate | Download (2.54 KB)
1 |
/* Copyright (C) 2001-2007 Peter Selinger.
|
---|---|
2 |
This file is part of Potrace. It is free software and it is covered
|
3 |
by the GNU General Public License. See the file COPYING for details. */
|
4 |
|
5 |
/* operations on potrace_progress_t objects, which are defined in
|
6 |
potracelib.h. Note: the code attempts to minimize runtime overhead
|
7 |
when no progress monitoring was requested. It also tries to
|
8 |
minimize excessive progress calculations beneath the "epsilon"
|
9 |
threshold. */
|
10 |
|
11 |
#ifndef PROGRESS_H
|
12 |
#define PROGRESS_H
|
13 |
|
14 |
/* structure to hold progress bar callback data */
|
15 |
struct progress_s {
|
16 |
void (*callback)(double progress, void *privdata); /* callback fn */ |
17 |
void *data; /* callback function's private data */ |
18 |
double min, max; /* desired range of progress, e.g. 0.0 to 1.0 */ |
19 |
double epsilon; /* granularity: can skip smaller increments */ |
20 |
double b; /* upper limit of subrange in superrange units */ |
21 |
double d_prev; /* previous value of d */ |
22 |
}; |
23 |
typedef struct progress_s progress_t; |
24 |
|
25 |
/* notify given progress object of current progress. Note that d is
|
26 |
given in the 0.0-1.0 range, which will be scaled and translated to
|
27 |
the progress object's range. */
|
28 |
static inline void progress_update(double d, progress_t *prog) { |
29 |
double d_scaled;
|
30 |
|
31 |
if (prog->callback != NULL) { |
32 |
d_scaled = prog->min * (1-d) + prog->max * d;
|
33 |
if (d == 1.0 || d_scaled >= prog->d_prev + prog->epsilon) { |
34 |
prog->callback(prog->min * (1-d) + prog->max * d, prog->data);
|
35 |
prog->d_prev = d_scaled; |
36 |
} |
37 |
} |
38 |
} |
39 |
|
40 |
/* start a subrange of the given progress object. The range is
|
41 |
narrowed to [a..b], relative to 0.0-1.0 coordinates. If new range
|
42 |
is below granularity threshold, disable further subdivisions. */
|
43 |
static inline void progress_subrange_start(double a, double b, const progress_t *prog, progress_t *sub) { |
44 |
double min, max;
|
45 |
|
46 |
if (prog->callback == NULL) { |
47 |
sub->callback = NULL;
|
48 |
return;
|
49 |
} |
50 |
|
51 |
min = prog->min * (1-a) + prog->max * a;
|
52 |
max = prog->min * (1-b) + prog->max * b;
|
53 |
|
54 |
if (max - min < prog->epsilon) {
|
55 |
sub->callback = NULL; /* no further progress info in subrange */ |
56 |
sub->b = b; |
57 |
return;
|
58 |
} |
59 |
sub->callback = prog->callback; |
60 |
sub->data = prog->data; |
61 |
sub->epsilon = prog->epsilon; |
62 |
sub->min = min; |
63 |
sub->max = max; |
64 |
sub->d_prev = prog->d_prev; |
65 |
return;
|
66 |
} |
67 |
|
68 |
static inline void progress_subrange_end(progress_t *prog, progress_t *sub) { |
69 |
if (prog->callback != NULL) { |
70 |
if (sub->callback == NULL) { |
71 |
progress_update(sub->b, prog); |
72 |
} else {
|
73 |
prog->d_prev = sub->d_prev; |
74 |
} |
75 |
} |
76 |
} |
77 |
|
78 |
#endif /* PROGRESS_H */ |
79 |
|