001/*******************************************************************************
002 * This software is provided as a supplement to the authors' textbooks on digital
003 *  image processing published by Springer-Verlag in various languages and editions.
004 * Permission to use and distribute this software is granted under the BSD 2-Clause 
005 * "Simplified" License (see http://opensource.org/licenses/BSD-2-Clause). 
006 * Copyright (c) 2006-2016 Wilhelm Burger, Mark J. Burge. All rights reserved. 
007 * Visit http://imagingbook.com for additional details.
008 *******************************************************************************/
009
010package imagingbook.pub.noise.hashing;
011
012public class HashPermute extends HashFun {
013        
014        public HashPermute() {
015                super();
016        }
017        
018    // seed is ignored by HashPermute
019        public HashPermute(int seed) {
020                super(seed);
021        }
022        
023        @Override
024        public double hash(int u) {
025                int h = h8(u);
026                return (double) (h & 0xFF) / 0xFF; // use bits 0..7 for d
027        }
028        
029        // 6 bits per channel (overlapping blocks)
030        @Override
031        public double[] hash(int u, int v) {
032                final int M = 0x3F; // 63;
033                int h = h8(u, v);
034                double hx = h & M;                      // use bits 0..5 for dx
035                double hy = (h >> 2) & M;       // use bits 2..7 for dy
036                return new double[] {hx/M, hy/M};
037        }
038        
039        @Override
040        public double[] hash(int u, int v, int w) {
041                final int M = 0x0F;
042                int h = h8(u, v, w);
043                double hx =  h & M;                     // use bits 0..3 for x
044                double hy = ((h >> 2) & M);     // use bits 2..5 for y
045                double hz = ((h >> 4) & M);     // use bits 4..7 for z
046                return new double[] {hx/M, hy/M, hz/M};
047        }
048
049        // 2 dimensions
050        private int h8 (int u) {
051                u = (u + seed) & 0xFF;
052                return P[u];
053        }
054        
055        // 2 dimensions
056        private int h8 (int u, int v) {
057                u = (u + seed) & 0xFF;
058                v = v & 0xFF;
059                return P[P[v] + u];
060        }
061        
062        // 3 dimensions
063        private int h8 (int u, int v, int w) {
064                u = (u + seed) & 0xFF;
065                v = v & 0xFF;
066                w = w & 0xFF;
067                return P[P[P[w] + v] + u];
068        }
069        
070        @Override
071        /*
072         * N-dimensional permutation hash; this version does not use
073         * any bit splitting. Instead, the hash8() function is
074         * applied repeatedly for every gradient dimension by 
075         * using the dimension number (k) as a local seed (sd) - 
076         * in addition to the global seed (seed).
077         */
078        public double[] hash(int[] p) {
079                int N = p.length;
080                double[] g = new double[N];
081                for (int k=0; k<N; k++) {               // dimension k
082                        int h = h8(p, k+seed);
083                        g[k] = (double) (h & 0xFF) / 0xFF;
084                }
085                return g;
086        }
087        
088        /*
089         * N-dimensional permutation hash function
090         */
091        private int h8 (int[] p, int sd) {
092                int h = sd & 0xFF;
093                for (int k=0; k<p.length; k++) {
094                        h = P[h + p[k] & 0xFF];
095                }
096                return h;
097        }
098
099        /*
100         * Permutation table P[i], for i = 0..255. To avoid index wrapping, 
101         * table's length is doubled to 512.
102         */
103        static final int P[] = new int[512];
104        static {
105                int[] perm = {
106                                151, 160, 137, 91, 90, 15, 131, 13, 
107                                201, 95, 96, 53, 194, 233, 7, 225, 
108                                140, 36, 103, 30, 69, 142, 8, 99, 
109                                37, 240, 21, 10, 23, 190, 6, 148, 
110                                247, 120, 234, 75, 0, 26, 197, 62,
111                                94,     252, 219, 203, 117, 35, 11, 32, 
112                                57, 177, 33, 88, 237, 149, 56, 87, 
113                                174, 20, 125, 136, 171, 168, 68, 175, 
114                                74, 165, 71, 134, 139, 48, 27, 166, 
115                                77, 146, 158, 231, 83, 111, 229, 122, 
116                                60, 211, 133, 230, 220, 105, 92, 41, 
117                                55, 46, 245, 40, 244, 102, 143, 54, 
118                                65, 25, 63, 161, 1, 216, 80, 73, 
119                                209, 76, 132, 187, 208, 89, 18, 169, 
120                                200, 196, 135, 130, 116, 188, 159, 86, 
121                                164, 100, 109, 198, 173, 186, 3, 64,
122                                52, 217, 226, 250, 124, 123, 5, 202, 
123                                38, 147, 118, 126, 255, 82, 85, 212, 
124                                207, 206, 59, 227, 47, 16, 58, 17, 
125                                182, 189, 28, 42, 223, 183, 170, 213, 
126                                119, 248, 152, 2, 44, 154, 163, 70, 
127                                221, 153, 101, 155, 167, 43, 172, 9,
128                                129, 22, 39, 253, 19, 98, 108, 110, 
129                                79, 113, 224, 232, 178, 185, 112, 104,
130                                218, 246, 97, 228, 251, 34, 242, 193, 
131                                238, 210, 144, 12, 191, 179, 162, 241, 
132                                81, 51, 145, 235, 249, 14, 239, 107, 
133                                49, 192, 214, 31, 181, 199, 106, 157, 
134                                184, 84, 204, 176, 115, 121, 50, 45, 
135                                127, 4, 150, 254, 138, 236, 205, 93, 
136                                222, 114, 67, 29, 24, 72, 243, 141, 
137                                128, 195, 78, 66, 215, 61, 156, 180 };
138                for (int i = 0; i < 256; i++)
139                        P[256 + i] = P[i] = perm[i];
140        }
141        
142        public static void main(String[] args) {
143                HashPermute hf = new HashPermute();
144                for (int k=0; k<256; k++) {
145                        System.out.format("%d : %10f\n", k, hf.hash(k));
146                        
147                }
148                
149                System.out.println(-1 % 256);
150        }
151}