diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2014-09-01 13:56:46 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2014-09-01 13:56:46 +0200 |
commit | 22f703cab05b7cd368f4de9e03991b7664dc5022 (patch) | |
tree | 6f4d50beaa42328e24b1c6b56b6ec059e4ef21a5 /imdi/imdi_utl.h |
Initial import of argyll version 1.5.1-8debian/1.5.1-8
Diffstat (limited to 'imdi/imdi_utl.h')
-rw-r--r-- | imdi/imdi_utl.h | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/imdi/imdi_utl.h b/imdi/imdi_utl.h new file mode 100644 index 0000000..f1a3ff5 --- /dev/null +++ b/imdi/imdi_utl.h @@ -0,0 +1,262 @@ +#ifndef IMDI_UTL_H +#define IMDI_UTL_H + +/* Integer Multi-Dimensional Interpolation */ + +/* + * Copyright 2000 - 2007 Graeme W. Gill + * All rights reserved. + * + * This material is licenced under the GNU AFFERO GENERAL PUBLIC LICENSE Version 3 :- + * see the License.txt file for licencing details. + */ + +#include <limits.h> + +/* Common utility definitions used at both generation and runtime. */ + +#define IXDI 10 /* maximum input channels/dimensions allowed */ +#define IXDO 10 /* maximum output channels/dimensions allowed */ + +#if IXDI > IXDO /* Maximum of either DI or DO */ +# define IXDIDO IXDI +#else +# define IXDIDO IXDO +#endif + +#define ALLOW64 /* Allow declarations but not use of 64 bit types */ + +#ifndef FORCE64 +# undef FORCE64 /* Use 64 bit, even on architectures where it's */ + /* not a native size. ALLOW64 must be defined */ +#endif + +/* ------------------------------------------------------ */ + +#if defined(ALLOW64) && (ULONG_MAX == 0xffffffffffffffffUL || defined(FORCE64)) +#ifndef USE64 +#pragma message("Using 64 bit integer color kernel") +#endif /* USE64 */ +#define USE64 /* Use 64 bits if it's natural or forced */ +#endif + +/* ------------------------------------------------------- */ +/* Macros combination counter */ +/* Declare the counter name nn, combinations out of total */ +/* Maximum combinations is DI+2 */ + +#define COMBO(nn, comb, total) \ + int nn[IXDI+2]; /* counter value */ \ + int nn##_cmb = (comb); /* number of combinations*/ \ + int nn##_tot = (total); /* out of total possible */ \ + int nn##_e /* dimension index */ + +/* Set total to new setting */ +#define CB_SETT(nn, total) \ + nn##_tot = (total) /* total possible */ + +/* Set combinations to new setting */ +#define CB_SETC(nn, comb) \ + nn##_cmb = (comb) /* number of combinations*/ + +/* Set the counter to its initial value */ +#define CB_INIT(nn) \ +{ \ + for (nn##_e = 0; nn##_e < nn##_cmb; nn##_e++) \ + nn[nn##_e] = nn##_cmb-nn##_e-1; \ + nn##_e = 0; \ +} + +/* Increment the counter value */ +#define CB_INC(nn) \ +{ \ + for (nn##_e = 0; nn##_e < nn##_cmb; nn##_e++) { \ + nn[nn##_e]++; \ + if (nn[nn##_e] < (nn##_tot-nn##_e)) { \ + int nn##_ee; /* No carry */ \ + for (nn##_ee = nn##_e-1; nn##_ee >= 0; nn##_ee--) \ + nn[nn##_ee] = nn[nn##_ee+1] + 1; \ + break; \ + } \ + } \ +} + +/* After increment, expression is TRUE if counter is done */ +#define CB_DONE(nn) \ + (nn##_e >= nn##_cmb) + + +/* ------------------------------------------------------- */ +/* Macros simplex combination counter. */ +/* Based on COMBO, but skips invalid simplex combinations */ + +#define XCOMBO(nn, comb, total) \ + COMBO(nn, comb, total) + +/* Set total to new setting */ +#define XCB_SETT(nn, total) \ + CB_SETT(nn, total) + +/* Set combinations to new setting */ +#define XCB_SETC(nn, comb) \ + CB_SETC(nn, comb) + + +/* Set the counter to its initial value */ +#define XCB_INIT(nn) \ +{ \ + int nn##_ii; \ + \ + for (nn##_e = 0; nn##_e < nn##_cmb; nn##_e++) \ + nn[nn##_e] = nn##_cmb-nn##_e-1; \ + for (nn##_ii = 1; nn##_ii < nn##_cmb; nn##_ii++) { \ + if ((nn[nn##_ii-1] ^ nn[nn##_ii]) & nn[nn##_ii])\ + break; /* Went from 0 to 1 */ \ + } \ + if (nn##_ii < nn##_cmb) { /* Fix invalid combination */ \ + XCB_INC(nn); \ + } \ + nn##_e = 0; \ +} + +/* Increment the counter value */ +#define XCB_INC(nn) \ +{ \ + int nn##_ii = 0; \ + \ + while (nn##_ii < nn##_cmb) { \ + for (nn##_e = 0; nn##_e < nn##_cmb; nn##_e++) { \ + nn[nn##_e]++; \ + if (nn[nn##_e] < (nn##_tot-nn##_e)) { \ + int nn##_ee; /* No carry */ \ + for (nn##_ee = nn##_e-1; nn##_ee >= 0; nn##_ee--) \ + nn[nn##_ee] = nn[nn##_ee+1] + 1; \ + break; \ + } \ + } \ + if (nn##_e >= nn##_cmb) \ + break; /* Done */ \ + \ + /* Reject invalid combinations */ \ + for (nn##_ii = 1; nn##_ii < nn##_cmb; nn##_ii++) { \ + if ((nn[nn##_ii-1] ^ nn[nn##_ii]) & nn[nn##_ii]) \ + break; /* Went from 0 to 1 */ \ + } \ + } \ +} + +/* After increment, expression is TRUE if counter is done */ +#define XCB_DONE(nn) \ + CB_DONE(nn) + +/* ------------------------------------------------------- */ +/* Macro pseudo-hilbert counter */ +/* This multi-dimensional count sequence is a distributed */ +/* Gray code sequence, with direction reversal on every */ +/* alternate power of 2 scale. */ +/* It is intended to aid cache coherence in multi-dimensional */ +/* regular sampling. It approximates the Hilbert curve sequence. */ + +#define PHILBERT(nn) \ + int nn[IXDIDO];/* counter value */ \ + int nn##di; /* Dimensionality */ \ + unsigned nn##res; /* Resolution per coordinate */ \ + unsigned nn##bits; /* Bits per coordinate */ \ + unsigned nn##ix; /* Current binary index */ \ + unsigned nn##tmask; /* Total 2^n count mask */ \ + unsigned nn##count; /* Usable count */ + +/* Init counter for dimenion di, resolution res */ +#define PH_INIT(nn, pdi, pres) \ +{ \ + int nn##e; \ + \ + nn##di = pdi; \ + nn##res = (unsigned)pres; \ + \ + /* Compute bits */ \ + for (nn##bits = 0; (1u << nn##bits) < nn##res; nn##bits++) \ + ; \ + \ + /* Compute the total count mask */ \ + nn##tmask = ((1u << (nn##bits * nn##di))-1); \ + \ + /* Compute usable count */ \ + nn##count = 1; \ + for (nn##e = 0; nn##e < nn##di; nn##e++) \ + nn##count *= nn##res; \ + \ + nn##ix = 0; \ + for (nn##e = 0; nn##e < nn##di; nn##e++) \ + nn[nn##e] = 0; \ +} + +/* Increment the counter value */ +#define PH_INC(nn) \ +{ \ + int nn##e; \ + do { \ + unsigned int nn##b; \ + int nn##gix; /* Gray code index */ \ + \ + nn##ix = (nn##ix + 1) & nn##tmask; \ + \ + /* Convert to gray code index */ \ + nn##gix = nn##ix ^ (nn##ix >> 1); \ + \ + for (nn##e = 0; nn##e < nn##di; nn##e++) \ + nn[nn##e] = 0; \ + \ + /* Distribute bits */ \ + for (nn##b = 0; nn##b < nn##bits; nn##b++) { \ + if (nn##b & 1) { /* In reverse order */ \ + for (nn##e = nn##di-1; nn##e >= 0; nn##e--) { \ + nn[nn##e] |= (nn##gix & 1) << nn##b; \ + nn##gix >>= 1; \ + } \ + } else { /* In normal order */ \ + for (nn##e = 0; nn##e < nn##di; nn##e++) { \ + nn[nn##e] |= (nn##gix & 1) << nn##b; \ + nn##gix >>= 1; \ + } \ + } \ + } \ + \ + /* Convert from Gray to binary coordinates */ \ + for (nn##e = 0; nn##e < nn##di; nn##e++) { \ + unsigned nn##sh, nn##tv; \ + \ + for(nn##sh = 1, nn##tv = nn[nn##e];; nn##sh <<= 1) { \ + unsigned nn##ptv = nn##tv; \ + nn##tv ^= (nn##tv >> nn##sh); \ + if (nn##ptv <= 1 || nn##sh == 16) \ + break; \ + } \ + /* Filter - increment again if outside cube range */ \ + if (nn##tv >= nn##res) \ + break; \ + nn[nn##e] = nn##tv; \ + } \ + \ + } while (nn##e < nn##di); \ + \ +} + +/* After increment, expression is TRUE if counter has looped back to start. */ +#define PH_LOOPED(nn) \ + (nn##ix == 0) \ + +/* ------------------------------------------------------- */ + +#endif /* IMDI_UTL_H */ + + + + + + + + + + + |