1 #ifndef IMDI_IMP_H 2 #define IMDI_IMP_H 3 4 /* Integer Multi-Dimensional Interpolation */ 5 /* 6 * Copyright 2000 - 2002 Graeme W. Gill 7 * All rights reserved. 8 * 9 * This material is licenced under the GNU GENERAL PUBLIC LICENCE :- 10 * see the Licence.txt file for licencing details. 11 */ 12 13 /* Common implementation definitions */ 14 15 #define IXDI 8 /* maximum input channels/dimensions allowed */ 16 #define IXDO 8 /* maximum output channels/dimensions allowed */ 17 18 #if IXDI > IXDO /* Maximum of either DI or DO */ 19 # define IXDIDO IXDI 20 #else 21 # define IXDIDO IXDO 22 #endif 23 24 #define ALLOW64 /* Allow declarations but not use of 64 bit types */ 25 /* Enabling must be done in architecture setup */ 26 27 #undef USE64 /* Use 64 bit, even on architectures where it's */ 28 /* not a native size. ALLOW64 must be defined */ 29 30 /* Private run time implementation definitions */ 31 typedef struct { 32 /* Table data */ 33 void *in_tables[IXDI]; /* Input dimension input lookup tables */ 34 void *sw_table; /* Simplex weighting lookup table */ 35 void *im_table; /* Interpolation Multi-dimensional lookup table */ 36 void *out_tables[IXDO]; /* Output dimension output lookup tables */ 37 int nintabs; /* Number of input tables */ 38 int nouttabs; /* Number of output tables */ 39 } imdi_imp; 40 41 42 /* ------------------------------------------------------- */ 43 /* Macros combination counter */ 44 /* Declare the counter name nn, combinations out of total */ 45 /* Maximum combinations is DI+2 */ 46 47 #define COMBO(nn, comb, total) \ 48 int nn[IXDI+2]; /* counter value */ \ 49 int nn##_cmb = (comb); /* number of combinations*/ \ 50 int nn##_tot = (total); /* out of total possible */ \ 51 int nn##_e /* dimension index */ 52 53 /* Set total to new setting */ 54 #define CB_SETT(nn, total) \ 55 nn##_tot = (total) /* total possible */ 56 57 /* Set combinations to new setting */ 58 #define CB_SETC(nn, comb) \ 59 nn##_cmb = (comb) /* number of combinations*/ 60 61 /* Set the counter to its initial value */ 62 #define CB_INIT(nn) \ 63 { \ 64 for (nn##_e = 0; nn##_e < nn##_cmb; nn##_e++) \ 65 nn[nn##_e] = nn##_cmb-nn##_e-1; \ 66 nn##_e = 0; \ 67 } 68 69 /* Increment the counter value */ 70 #define CB_INC(nn) \ 71 { \ 72 for (nn##_e = 0; nn##_e < nn##_cmb; nn##_e++) { \ 73 nn[nn##_e]++; \ 74 if (nn[nn##_e] < (nn##_tot-nn##_e)) { \ 75 int nn##_ee; /* No carry */ \ 76 for (nn##_ee = nn##_e-1; nn##_ee >= 0; nn##_ee--) \ 77 nn[nn##_ee] = nn[nn##_ee+1] + 1; \ 78 break; \ 79 } \ 80 } \ 81 } 82 83 /* After increment, expression is TRUE if counter is done */ 84 #define CB_DONE(nn) \ 85 (nn##_e >= nn##_cmb) 86 87 88 /* ------------------------------------------------------- */ 89 /* Macros simplex combination counter. */ 90 /* Based on COMBO, but skips invalid simplex combinations */ 91 92 #define XCOMBO(nn, comb, total) \ 93 COMBO(nn, comb, total) 94 95 /* Set total to new setting */ 96 #define XCB_SETT(nn, total) \ 97 CB_SETT(nn, total) 98 99 /* Set combinations to new setting */ 100 #define XCB_SETC(nn, comb) \ 101 CB_SETC(nn, comb) 102 103 104 /* Set the counter to its initial value */ 105 #define XCB_INIT(nn) \ 106 { \ 107 int nn##_ii; \ 108 \ 109 for (nn##_e = 0; nn##_e < nn##_cmb; nn##_e++) \ 110 nn[nn##_e] = nn##_cmb-nn##_e-1; \ 111 for (nn##_ii = 1; nn##_ii < nn##_cmb; nn##_ii++) { \ 112 if ((nn[nn##_ii-1] ^ nn[nn##_ii]) & nn[nn##_ii])\ 113 break; /* Went from 0 to 1 */ \ 114 } \ 115 if (nn##_ii < nn##_cmb) { /* Fix invalid combination */ \ 116 XCB_INC(nn); \ 117 } \ 118 nn##_e = 0; \ 119 } 120 121 /* Increment the counter value */ 122 #define XCB_INC(nn) \ 123 { \ 124 int nn##_ii = 0; \ 125 \ 126 while (nn##_ii < nn##_cmb) { \ 127 for (nn##_e = 0; nn##_e < nn##_cmb; nn##_e++) { \ 128 nn[nn##_e]++; \ 129 if (nn[nn##_e] < (nn##_tot-nn##_e)) { \ 130 int nn##_ee; /* No carry */ \ 131 for (nn##_ee = nn##_e-1; nn##_ee >= 0; nn##_ee--) \ 132 nn[nn##_ee] = nn[nn##_ee+1] + 1; \ 133 break; \ 134 } \ 135 } \ 136 if (nn##_e >= nn##_cmb) \ 137 break; /* Done */ \ 138 \ 139 /* Reject invalid combinations */ \ 140 for (nn##_ii = 1; nn##_ii < nn##_cmb; nn##_ii++) { \ 141 if ((nn[nn##_ii-1] ^ nn[nn##_ii]) & nn[nn##_ii]) \ 142 break; /* Went from 0 to 1 */ \ 143 } \ 144 } \ 145 } 146 147 /* After increment, expression is TRUE if counter is done */ 148 #define XCB_DONE(nn) \ 149 CB_DONE(nn) 150 151 /* ------------------------------------------------------- */ 152 /* Macro pseudo-hilbert counter */ 153 /* This multi-dimensional count sequence is a distributed */ 154 /* Gray code sequence, with direction reversal on every */ 155 /* alternate power of 2 scale. */ 156 /* It is intended to aid cache coherence in multi-dimensional */ 157 /* regular sampling. It approximates the Hilbert curve sequence. */ 158 159 #define PHILBERT(nn) \ 160 int nn[IXDIDO];/* counter value */ \ 161 int nn##di; /* Dimensionality */ \ 162 unsigned nn##res; /* Resolution per coordinate */ \ 163 unsigned nn##bits; /* Bits per coordinate */ \ 164 unsigned nn##ix; /* Current binary index */ \ 165 unsigned nn##tmask; /* Total 2^n count mask */ \ 166 unsigned nn##count; /* Usable count */ 167 168 /* Init counter for dimenion di, resolution res */ 169 #define PH_INIT(nn, pdi, pres) \ 170 { \ 171 int nn##e; \ 172 \ 173 nn##di = pdi; \ 174 nn##res = (unsigned)pres; \ 175 \ 176 /* Compute bits */ \ 177 for (nn##bits = 0; (1 << nn##bits) < nn##res; nn##bits++) \ 178 ; \ 179 \ 180 /* Compute the total count mask */ \ 181 nn##tmask = ((((unsigned)1) << (nn##bits * nn##di))-1); \ 182 \ 183 /* Compute usable count */ \ 184 nn##count = 1; \ 185 for (nn##e = 0; nn##e < nn##di; nn##e++) \ 186 nn##count *= nn##res; \ 187 \ 188 nn##ix = 0; \ 189 for (nn##e = 0; nn##e < nn##di; nn##e++) \ 190 nn[nn##e] = 0; \ 191 } 192 193 /* Increment the counter value */ 194 #define PH_INC(nn) \ 195 { \ 196 int nn##e; \ 197 do { \ 198 int nn##b; \ 199 int nn##gix; /* Gray code index */ \ 200 \ 201 nn##ix = (nn##ix + 1) & nn##tmask; \ 202 \ 203 /* Convert to gray code index */ \ 204 nn##gix = nn##ix ^ (nn##ix >> 1); \ 205 \ 206 for (nn##e = 0; nn##e < nn##di; nn##e++) \ 207 nn[nn##e] = 0; \ 208 \ 209 /* Distribute bits */ \ 210 for (nn##b = 0; nn##b < nn##bits; nn##b++) { \ 211 if (nn##b & 1) { /* In reverse order */ \ 212 for (nn##e = nn##di-1; nn##e >= 0; nn##e--) { \ 213 nn[nn##e] |= (nn##gix & 1) << nn##b; \ 214 nn##gix >>= 1; \ 215 } \ 216 } else { /* In normal order */ \ 217 for (nn##e = 0; nn##e < nn##di; nn##e++) { \ 218 nn[nn##e] |= (nn##gix & 1) << nn##b; \ 219 nn##gix >>= 1; \ 220 } \ 221 } \ 222 } \ 223 \ 224 /* Convert from Gray to binary coordinates */ \ 225 for (nn##e = 0; nn##e < nn##di; nn##e++) { \ 226 unsigned nn##sh, nn##tv; \ 227 \ 228 for(nn##sh = 1, nn##tv = nn[nn##e];; nn##sh <<= 1) { \ 229 unsigned nn##ptv = nn##tv; \ 230 nn##tv ^= (nn##tv >> nn##sh); \ 231 if (nn##ptv <= 1 || nn##sh == 16) \ 232 break; \ 233 } \ 234 /* Filter - increment again if outside cube range */ \ 235 if (nn##tv >= nn##res) \ 236 break; \ 237 nn[nn##e] = nn##tv; \ 238 } \ 239 \ 240 } while (nn##e < nn##di); \ 241 \ 242 } 243 244 /* After increment, expression is TRUE if counter has looped back to start. */ 245 #define PH_LOOPED(nn) \ 246 (nn##ix == 0) \ 247 248 /* ------------------------------------------------------- */ 249 250 #endif /* IMDI_IMP_H */ 251 252 253 254 255 256 257 258 259 260 261 262