gvsig-raster / libjni-potrace / trunk / libjni-potrace / src / main / native / jpotrace / progress.h @ 1780
History | View | Annotate | Download (2.54 KB)
1 | 1780 | nbrodin | /* 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 */ |