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}