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