Source of ilace.c
typedef struct _interval
void construct_slots(int n)
void destruct_slots(void)
int dist(int p, int q)
int mark_closest_to(int p)
int midpoint(interval* I)
void construct_largest_interval(int n)
void destruct_largest_interval(void)
void remove_largest_interval(interval* I)
void insert_interval(interval* I)
void construct_ilace(int n)
void destruct_ilace(void)
int* ilace(int n)
/* ilace.c -- generate interlace sequences for rasters with n scan lines. */
/* rj@elilabs.com Tue Nov 5 08:43:21 CST 2002 */
#include <stdlib.h>
#include <stdio.h>
#define FALSE (0)
#define TRUE (!(FALSE))
#define min(a, b) ((a) < (b) ? (a) : (b))
typedef struct _interval { /* a semi-open interval |left, rite> */
int left;
int rite;
} interval;
int* slot;
int nslots;
void construct_slots(int n) { /* create the array of markers */
int i;
nslots = n; /* we need to know its size externally */
slot = malloc(n*sizeof(int)); /* allocate space for it */
for (i = 0; i < n; i++) { /* all slots are initially unmarked */
slot[i] = FALSE;
}
}
void destruct_slots(void) { /* destroy the array of slots */
free(slot); /* give back the space we allocated for it */
}
int dist(int p, int q) { /* return the distance between 2 points */
if (p > q) { /* swap them if out of order */
int r = p;
p = q;
q = r;
}
return min(q - p, p + nslots - q); /* choose the shortest path */
}
int mark_closest_to(int p) { /* mark slot closest to p, return numer of slot marked */
int i;
int q;
for (i = 0; i < nslots/2 + 1; i++) { /* search for closest unmarked slot */
q = (p + i) % nslots; /* look forwards */
if (!slot[q]) {
slot[q] = TRUE;
return q;
}
q = (p - i + nslots) % nslots; /* look backwards */
if (!slot[q]) {
slot[q] = TRUE;
return q;
}
}
printf("%s:%d All slots marked!\n", __FILE__, __LINE__);
exit(1);
return 0; /* NOT REACHED */
}
int midpoint(interval* I) {
return (I->left + I->rite)/2;
}
static interval* largest_interval_array;
void construct_largest_interval(int n) {
int i;
largest_interval_array = (interval*)malloc(2*n*sizeof(interval));
for (i = 0; i < n; i++) {
largest_interval_array[i].left = 0;
largest_interval_array[i].rite = 0;
}
}
void destruct_largest_interval(void) {
free(largest_interval_array);
}
void remove_largest_interval(interval* I) {
int i;
I->left = largest_interval_array[0].left;
I->rite = largest_interval_array[0].rite;
for (i = 1; i < nslots; i++) {
largest_interval_array[i - 1].left = largest_interval_array[i].left;
largest_interval_array[i - 1].rite = largest_interval_array[i].rite;
}
}
void insert_interval(interval* I) {
int i;
int j;
int size0 = I->rite - I->left;
int size;
if (size0 <= 1) { /* don't do degenerate intervals */
return;
}
for (j = 0; j < nslots; j++) { /* search for place to insert */
size = largest_interval_array[j].rite - largest_interval_array[j].left;
if (size0 >= size) { /* found right place? */
for (i = nslots - 1; i >= j; i--) { /* yes, slide over to make some room */
largest_interval_array[i + 1].left = largest_interval_array[i].left;
largest_interval_array[i + 1].rite = largest_interval_array[i].rite;
}
largest_interval_array[j].left = I->left; /* insert this interval */
largest_interval_array[j].rite = I->rite;
return;
}
}
printf("%s:%d Fell off end of sorted list!\n", __FILE__, __LINE__);
exit(1);
}
void construct_ilace(int n) {
construct_slots(n);
construct_largest_interval(n);
}
void destruct_ilace(void) {
destruct_largest_interval();
destruct_slots();
}
int* ilace(int n) { /* generate a "good" interlace sequence for n scan lines */
int line = 0;
interval I;
interval J;
int i;
int* seq = malloc(n*sizeof(int)); /* make room for the resule */
construct_ilace(n); /* initialize */
J.left = 0;
J.rite = n - 1;
insert_interval(&J);
for(i = 0; i < n; i++) { /* for each scan line */
remove_largest_interval(&I); /* get largest remaining interval */
line = (I.left + I.rite)/2; /* midpoint of interval */
line = mark_closest_to(line); /* mark the closest available scan line */
seq[i] = line; /* put its number in the sequence */
J.left = I.left; /* left half */
J.rite = line;
insert_interval(&J);
J.left = line + 1; /* rite half */
J.rite = I.rite;
insert_interval(&J);
}
destruct_ilace(); /* get rid of temporary objects */
return seq; /* return the pointer to the interlace sequence array */
}