static bool isleaf(scm *s, long long i) { if (scm_get_offset(s, i)) { long long x = scm_get_index(s, i); long long j; for (int c = 0; c < 4; c++) { // If child c exists and has data, then x is not a leaf. if ((j = scm_search(s, scm_page_child(x, c))) != -1) if (scm_get_offset(s, j) > 0) return false; } return true; } return false; }
static void process(scm *s, scm **V, int C, int O) { const size_t S = (size_t) (scm_get_n(s) + 2) * (size_t) (scm_get_n(s) + 2) * (size_t) (scm_get_c(s)); float *p; float *q; // Allocate temporary and accumulator buffers. if ((p = scm_alloc_buffer(s)) && (q = scm_alloc_buffer(s))) { long long b = 0; long long m = 0; long long i = 0; long long o[256]; // Determine the highest page index in the input. for (int f = 0; f < C; ++f) { if (m < scm_get_index(V[f], scm_get_length(V[f]) - 1)) m = scm_get_index(V[f], scm_get_length(V[f]) - 1); o[f] = 0; } // Process each page of an SCM with the desired depth. for (int x = 0; x <= m; ++x) { int c = scm_get_c(s); int g = 0; int k = 0; // Count the SCMs contributing to page x. for (int f = 0; f < C; ++f) if ((i = scm_search(V[f], x)) < 0) o[f] = 0; else { o[f] = scm_get_offset(V[f], i); g = f; k++; } // If there is exactly one contributor, repeat its page. if (k == 1) b = scm_repeat(s, b, V[g], o[g]); // If there is more than one, append their summed pages. else if (k > 1) { memset(p, 0, S * sizeof (float)); for (int f = 0; f < C; ++f) if (o[f] && scm_read_page(V[f], o[f], q)) switch (O) { case 0: for (size_t j = 0; j < S; ++j) p[j] = sum(p[j], q[j]); break; case 1: for (size_t j = 0; j < S; ++j) p[j] = max(p[j], q[j]); break; case 2: for (size_t j = 0; j < S; ++j) p[j] = avg(p[j], q[j]); break; case 3: for (size_t j = 0; j < S; j += c) blend(p + j, q + j, c); break; } b = scm_append(s, b, x, p); } } free(q); free(p); } }