Tatarize

No Memory Footprint Olsen Noise

Feb 19th, 2015
380
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. public class OlsenNoise2D {
  3.  
  4. private static final int[][] blur3x3 = new int[][]{
  5. {1, 1, 1},
  6. {1, 1, 1},
  7. {1, 1, 1}
  8. };
  9. private static final int blurEdge = 2; //extra pixels are needed for the blur (3 - 1).
  10.  
  11.  
  12. private static final int maxiterations = 7;
  13.  
  14. //The hope is to get scale factor working for other scales. Works only for 2 currently.
  15. private static final int SCALE_FACTOR = 2;
  16.  
  17. public void olsennoise(int[] pixels, int stride, int x, int y, int width, int height) {
  18. olsennoise(pixels, stride, x, y, width, height, maxiterations);
  19. applyColor(pixels, stride, width, height);
  20. }
  21.  
  22. public int getRequiredDim(int dim) {
  23. return dim + blurEdge + SCALE_FACTOR;
  24. }
  25.  
  26. private void olsennoise(int[] pixels, int stride, int x_within_field, int y_within_field, int width, int height, int iteration) {
  27. if (iteration == 0) {
  28. applyNoise(pixels, stride, x_within_field, y_within_field, width, height, iteration);
  29. return;
  30. }
  31. int x_remainder = x_within_field & 1;
  32. int y_remainder = y_within_field & 1; //Math.abs(y_within_field % SCALE_FACTOR)
  33. olsennoise(pixels, stride,
  34. ((x_within_field + x_remainder) / SCALE_FACTOR) - x_remainder,
  35. ((y_within_field + y_remainder) / SCALE_FACTOR) - y_remainder,
  36. ((width + x_remainder) / SCALE_FACTOR) + blurEdge,
  37. ((height + y_remainder) / SCALE_FACTOR) + blurEdge, iteration - 1);
  38. applyScale(pixels, stride, width + 2, height + 2, SCALE_FACTOR);
  39. applyShift(pixels, stride, x_remainder, y_remainder, width + 2, height + 2);
  40. applyBlur(pixels, stride, width + 2, height + 2);
  41. applyNoise(pixels, stride, x_within_field, y_within_field, width, height, iteration);
  42. }
  43.  
  44. private void applyNoise(int[] pixels, int stride, int x_within_field, int y_within_field, int width, int height, int iteration) {
  45. int index = 0;
  46. for (int k = 0, n = height - 1; k <= n; k++, index += stride) {
  47. for (int j = 0, m = width - 1; j <= m; j++) {
  48. int current = index + j;
  49. pixels[current] += (hashrandom(j + x_within_field, k + y_within_field, iteration) & (1 << (7 - iteration)));
  50. }
  51. }
  52. }
  53.  
  54. private void applyScale(int[] pixels, int stride, int width, int height, int factor) {
  55. int index = (height - 1) * stride;
  56. for (int k = 0, n = height - 1; k <= n; n--, index -= stride) {
  57. for (int j = 0, m = width - 1; j <= m; m--) {
  58. int current = index + m;
  59. int lower = ((n / factor) * stride) + (m / factor);
  60. pixels[current] = pixels[lower];
  61. }
  62. }
  63. }
  64.  
  65. private void applyShift(int[] pixels, int stride, int shiftX, int shiftY, int width, int height) {
  66. if ((shiftX == 0) && (shiftY == 0)) {
  67. return;
  68. }
  69.  
  70. int index;
  71. int indexoffset = shiftX + (shiftY * stride);
  72. index = 0;
  73. for (int k = 0, n = height - 1; k <= n; k++, index += stride) {
  74. for (int j = 0, m = width - 1; j <= m; j++) {
  75. int current = index + j;
  76. pixels[current] = pixels[current + indexoffset];
  77. }
  78. }
  79. }
  80.  
  81. private void applyColor(int[] pixels, int stride, int width, int height) {
  82. int index;
  83. index = 0;
  84. for (int k = 0, n = height - 1; k <= n; k++, index += stride) {
  85. for (int j = 0, m = width - 1; j <= m; j++) {
  86. int current = index + j;
  87. int pixel = pixels[current];
  88. pixels[current] = 0xFF000000 | pixel << 16 | pixel << 8 | pixel;
  89. }
  90. }
  91. }
  92.  
  93. private void applyBlur(int[] pixels, int stride, int width, int height) {
  94. convolve(pixels, 0, stride, 0, 0, width, height, blur3x3);
  95. }
  96.  
  97. /**
  98. * Memory Free In-Place Convolution.
  99. * Modified to simply add values. (Greyscale as such).
  100. *
  101. * @param pixels pixels to be modified
  102. * @param offset offset within the pixel array to call zero.
  103. * @param stride width of the memory block to next Y.
  104. * @param x the start x value.
  105. * @param y the start y value.
  106. * @param width the width of blocks to be used for the convolution.
  107. * @param height the height of the convolution area.
  108. * @param matrix matrix of the convolution.
  109. */
  110.  
  111. public static void convolve(int[] pixels, int offset, int stride, int x, int y, int width, int height, int[][] matrix) {
  112. int index = offset + x + (y*stride);
  113. for (int j = 0; j < height; j++, index += stride) {
  114. for (int k = 0; k < width; k++) {
  115. int pos = index + k;
  116. pixels[pos] = convolve(pixels,stride,pos, matrix);
  117. }
  118. }
  119. }
  120.  
  121. private static int crimp(int color) {
  122. return (color >= 0xFF) ? 0xFF : (color < 0) ? 0 : color;
  123. }
  124.  
  125. private static int convolve(int[] pixels, int stride, int index, int[][] matrix) {
  126. int parts = 0;
  127. int sum = 0;
  128. int factor;
  129. for (int j = 0, m = matrix.length; j < m; j++, index+=stride) {
  130. for (int k = 0, n = matrix[j].length; k < n; k++) {
  131. factor = matrix[j][k];
  132. parts += factor;
  133. sum += factor * pixels[index + k];
  134. }
  135. }
  136. if (parts == 0) return crimp(sum);
  137. return crimp(sum/parts);
  138. }
  139.  
  140.  
  141. /**
  142. * XOR hash the hashed values of each element, in elements
  143. * @param elements elements to be hashed and xor'ed together.
  144. * @return
  145. */
  146. public static int hashrandom(int... elements) {
  147. long hash = 0;
  148. for (int i = 0; i < elements.length; i++) {
  149. hash ^= elements[i];
  150. hash = hash(hash);
  151. }
  152. return (int) hash;
  153. }
  154.  
  155. private static long hash(long v) {
  156. long hash = v;
  157. long h = hash;
  158.  
  159. switch ((int) hash & 3) {
  160. case 3:
  161. hash += h;
  162. hash ^= hash << 32;
  163. hash ^= h << 36;
  164. hash += hash >> 22;
  165. break;
  166. case 2:
  167. hash += h;
  168. hash ^= hash << 22;
  169. hash += hash >> 34;
  170. break;
  171. case 1:
  172. hash += h;
  173. hash ^= hash << 20;
  174. hash += hash >> 2;
  175. }
  176. hash ^= hash << 6;
  177. hash += hash >> 10;
  178. hash ^= hash << 8;
  179. hash += hash >> 34;
  180. hash ^= hash << 50;
  181. hash += hash >> 12;
  182. return hash;
  183. }
  184.  
  185. /**
  186. * Trim off the edge pixels
  187. *
  188. * @param pixels destination array
  189. * @param width Width of the new image
  190. * @param height height of the new image
  191. * @param workingpixels source array
  192. * @param workingstride stride of source array
  193. */
  194. public static void trim(int[] pixels, int width, int height, int[] workingpixels, int workingstride) {
  195. for (int k = 0; k < height; k++) {
  196. for (int j = 0; j < width; j++) {
  197. int index = j + (k * width);
  198. int workingindex = j + (k * workingstride);
  199. pixels[index] = workingpixels[workingindex];
  200. }
  201. }
  202. }
  203.  
  204. }
RAW Paste Data