6 struct dive *fixup_dive(struct dive *dive)
11 int start = -1, end = -1;
12 int startpress = 0, endpress = 0;
13 int starttemp = 0, endtemp = 0;
14 int maxdepth = 0, mintemp = 0;
17 for (i = 0; i < dive->samples; i++) {
18 struct sample *sample = dive->sample + i;
19 int time = sample->time.seconds;
20 int depth = sample->depth.mm;
21 int press = sample->tankpressure.mbar;
22 int temp = sample->temperature.mkelvin;
42 if (!mintemp || temp < mintemp)
45 depthtime += (time - lasttime) * (lastdepth + depth) / 2;
51 dive->duration.seconds = end - start;
53 dive->meandepth.mm = depthtime / (end - start);
55 dive->beginning_pressure.mbar = startpress;
57 dive->end_pressure.mbar = endpress;
59 dive->watertemp.mkelvin = mintemp;
61 dive->maxdepth.mm = maxdepth;
66 /* Don't pick a zero for MERGE_MIN() */
67 #define MIN(a,b) ((a)<(b)?(a):(b))
68 #define MAX(a,b) ((a)>(b)?(a):(b))
69 #define MERGE_MAX(res, a, b, n) res->n = MAX(a->n, b->n)
70 #define MERGE_MIN(res, a, b, n) res->n = (a->n)?(b->n)?MIN(a->n, b->n):(a->n):(b->n)
72 static int alloc_samples;
74 static struct dive *add_sample(struct sample *sample, int time, struct dive *dive)
76 int nr = dive->samples;
79 if (nr >= alloc_samples) {
80 alloc_samples = (alloc_samples + 64) * 3 / 2;
81 dive = realloc(dive, dive_size(alloc_samples));
86 d = dive->sample + nr;
89 d->time.seconds = time;
94 * Merge samples. Dive 'a' is "offset" seconds before Dive 'b'
96 static struct dive *merge_samples(struct dive *res, struct dive *a, struct dive *b, int offset)
98 int asamples = a->samples;
99 int bsamples = b->samples;
100 struct sample *as = a->sample;
101 struct sample *bs = b->sample;
105 struct sample sample;
110 at = asamples ? as->time.seconds : -1;
111 bt = bsamples ? bs->time.seconds + offset : -1;
113 /* No samples? All done! */
114 if (at < 0 && bt < 0)
115 return fixup_dive(res);
117 /* Only samples from a? */
120 res = add_sample(as, at, res);
126 /* Only samples from b? */
129 res = add_sample(bs, bt, res);
140 /* same-time sample: add a merged sample. Take the non-zero ones */
143 sample.depth = as->depth;
144 if (as->temperature.mkelvin)
145 sample.temperature = as->temperature;
146 if (as->tankpressure.mbar)
147 sample.tankpressure = as->tankpressure;
149 sample.tankindex = as->tankindex;
151 res = add_sample(&sample, at, res);
160 static char *merge_text(const char *a, const char *b)
170 res = malloc(strlen(a) + strlen(b) + 9);
173 sprintf(res, "(%s) or (%s)", a, b);
178 * This could do a lot more merging. Right now it really only
179 * merges almost exact duplicates - something that happens easily
180 * with overlapping dive downloads.
182 struct dive *try_to_merge(struct dive *a, struct dive *b)
187 if (a->when != b->when)
191 res = malloc(dive_size(alloc_samples));
194 memset(res, 0, dive_size(alloc_samples));
197 res->name = merge_text(a->name, b->name);
198 res->location = merge_text(a->location, b->location);
199 res->notes = merge_text(a->notes, b->notes);
200 MERGE_MAX(res, a, b, maxdepth.mm);
201 res->meandepth.mm = 0;
202 MERGE_MAX(res, a, b, duration.seconds);
203 MERGE_MAX(res, a, b, surfacetime.seconds);
204 MERGE_MAX(res, a, b, airtemp.mkelvin);
205 MERGE_MIN(res, a, b, watertemp.mkelvin);
206 MERGE_MAX(res, a, b, beginning_pressure.mbar);
207 MERGE_MAX(res, a, b, end_pressure.mbar);
208 for (i = 0; i < MAX_MIXES; i++) {
209 if (a->gasmix[i].o2.permille) {
210 res->gasmix[i] = a->gasmix[i];
213 res->gasmix[i] = b->gasmix[i];
215 return merge_samples(res, a, b, 0);