Advertisement
vivienneanthony

Olsen 2D version 2.00 Conversion Not-working

Feb 19th, 2015
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.02 KB | None | 0 0
  1. /*
  2.  * Original Author @author Tat
  3.  * Mod code Vivienne Anthony
  4.  * c++ rewrite vivienne (WIP)
  5.  * verion 1.0 Functional Rewrite
  6.  *
  7.  * Changes
  8.  *  Java to C++ conversion
  9.  *  Memory pointer usage
  10.  */
  11.  
  12. #include <iostream>
  13. #include <vector>
  14.  
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <png++/png.hpp>
  18.  
  19. using namespace std;
  20.  
  21. void SaveTerrFile(const int * image, int size, char * filename);
  22.  
  23. class OlsenNoise2D
  24. {
  25.  
  26. public:
  27.     OlsenNoise2D();
  28.     void convolve(int * pixels, int offset, int stride, int x, int y, int width, int height, int * matrix, int matrixwidth, int matrixheight, int parts);
  29.     int getRequiredDim(int dim);
  30.     void olsennoise(int * pixels, int stride, int x, int y, int width, int height);
  31.     void olsennoise(int * pixels, int stride, int x_within_field, int y_within_field, int width, int height, int iteration);
  32.  
  33. private:
  34.     int crimp(int color);
  35.     int convolve(int * pixels, int stride, int index, int * matrix, int matrixwidth, int matrixheight, int parts);
  36.     void applyNoise(int * pixels, int stride, int x_within_field, int y_within_field, int width, int height, int iteration);
  37.     void applyBlur(int * pixels, int stride, int width, int height);
  38.     void applyScale(int * pixels, int stride, int width, int height);
  39.     void trim(int * pixels, int width, int height, int * workingpixels, int workingstride);
  40.  
  41.     int hashrandom(std::vector<long long int> elements);
  42.     long long hash(long long v);
  43.  
  44.     int maxiterations;
  45.     int  * blur2x2;
  46. };
  47.  
  48. OlsenNoise2D::OlsenNoise2D()
  49. {
  50.     maxiterations = 7;
  51.     blur2x2= new int(4);
  52.  
  53.     /// fill memory
  54.     blur2x2[0]=1;
  55.     blur2x2[1]=1;
  56.     blur2x2[2]=1;
  57.     blur2x2[3]=1;
  58.  
  59.  
  60. }
  61.  
  62. void OlsenNoise2D::convolve(int * pixels, int offset, int stride, int x, int y, int width, int height, int * matrix, int matrixwidth, int matrixheight, int parts)
  63. {
  64.     int startIndex = x + (y * stride);
  65.     int lastIndex = (x + width - 1) + ((y + height - 1) * stride);
  66.     int x_pos = x;
  67.     int y_pos = y;
  68.     int indexInc = 1;
  69.     int yinc = 0;
  70.     int xinc = 1;
  71.  
  72.     for (int i = 0, s = width + (height*width); i < s; i++)
  73.     {
  74.         if (i == width)
  75.         {
  76.             indexInc = stride;
  77.             yinc = 1;
  78.             xinc = 0;
  79.         }
  80.         int x_counter = x_pos;
  81.         int index = startIndex;
  82.         while (x_counter >= x && index <= lastIndex)
  83.         {
  84.             pixels[offset + index] = convolve(pixels, stride, offset + index, matrix, matrixwidth, matrixheight,parts);
  85.             x_counter--;
  86.             index += stride - 1;
  87.         }
  88.         startIndex += indexInc;
  89.         x_pos += xinc;
  90.         y_pos += yinc;
  91.     }
  92. }
  93.  
  94.  
  95. int OlsenNoise2D::crimp(int color)
  96. {
  97.     return (color >= 0xFF) ? 0xFF : (color < 0) ? 0 : color;
  98. }
  99.  
  100. int OlsenNoise2D::convolve(int * pixels, int stride, int index, int * matrix, int matrixwidth, int matrixheight, int parts)
  101. {
  102.     int redSum = 0;
  103.     int greenSum = 0;
  104.     int blueSum = 0;
  105.     int pixel, factor;
  106.     for (int j = 0, m = matrixheight; j < m; j++, index++)
  107.     {
  108.         for (int k = 0, n = matrixwidth, q = index; k < n; k++, q += stride)
  109.         {
  110.             pixel = pixels[q];
  111.             factor = matrix[j*(k*matrixwidth)];
  112.             redSum += factor * ((pixel >> 16) & 0xFF);
  113.             greenSum += factor * ((pixel >> 8) & 0xFF);
  114.             blueSum += factor * ((pixel) & 0xFF);
  115.         }
  116.     }
  117.     return 0xFF000000 | ((crimp(redSum / parts) << 16) | (crimp(greenSum / parts) << 8) | (crimp(blueSum / parts)));
  118. }
  119.  
  120. //occupies same footprint
  121. void OlsenNoise2D::applyNoise(int * pixels, int stride, int x_within_field, int y_within_field, int width, int height, int iteration)
  122. {
  123.     int index = 0;
  124.     for (int k = 0, n =  height - 1; k <= n; k++, index += stride)
  125.     {
  126.         for (int j = 0, m = width - 1; j <= m; j++)
  127.         {
  128.             int current = index + j;
  129.             pixels[current] += (hashrandom( {x_within_field + j, y_within_field + k, iteration}) & (1 << (7 - iteration)));
  130.         }
  131.     }
  132. }
  133.  
  134. //requires half the height and width be good.
  135. void OlsenNoise2D::applyScale(int * pixels, int stride, int width, int height)
  136. {
  137.     int index = (height - 1) * stride;
  138.     for (int k = 0, n = 0 + height - 1; k <= n; n--, index -= stride)
  139.     {
  140.         for (int j = 0, m = width - 1; j <= m; m--)
  141.         {
  142.             int current = index + m;
  143.             int lower = ((n / 2) * stride) + (m / 2);
  144.             pixels[current] = pixels[lower];
  145.         }
  146.     }
  147. }
  148.  
  149.  
  150. void OlsenNoise2D::applyBlur(int * pixels, int stride, int width, int height)
  151. {
  152.     convolve(pixels, 0, stride,0,0, width, height, blur2x2, 2,2,4);
  153. }
  154.  
  155. //You need to give it an array larger than the current one. This math is just a guess at a number big enough, it's not actually the max dim the array would properly need to be.
  156. int OlsenNoise2D::getRequiredDim(int dim)
  157. {
  158.     return (dim + 5) * 2;
  159. }
  160.  
  161. void OlsenNoise2D::trim(int * pixels, int width, int height, int * workingpixels, int workingstride)
  162. {
  163.     for (int k = 0; k < height; k++)
  164.     {
  165.         for (int j = 0; j < width; j++)
  166.         {
  167.             int index = j + (k * width);
  168.             int workingindex = j + (k * workingstride);
  169.             pixels[index] = workingpixels[workingindex];
  170.         }
  171.     }
  172. }
  173.  
  174.  
  175. void OlsenNoise2D::olsennoise(int * pixels, int stride, int x, int y, int width, int height)
  176. {
  177.     for(int i=0;i<width*height;i++)
  178.     {
  179.         pixels[i]=0xFF000000;
  180.     }
  181.  
  182.     olsennoise(pixels, stride, x, y, width, height, maxiterations);
  183. }
  184.  
  185. void OlsenNoise2D::olsennoise(int * pixels, int stride, int x_within_field, int y_within_field, int width, int height, int iteration)
  186. {
  187.     if (iteration == 0)
  188.     {
  189.         applyNoise(pixels, stride, x_within_field, y_within_field, width, height, iteration);
  190.         return;
  191.     }
  192.  
  193.     olsennoise(pixels, stride, (x_within_field/2)-2, (y_within_field/2)-2, (width/2)+2, (height/2) + 2, iteration - 1);
  194.  
  195.     //scale only requires (width/2+1) and (height/2+1) valid pixels.
  196.     applyScale(pixels, stride, width+1, height+1);
  197.  
  198.     //blur only requires width+1 and height+1 valid pixels.
  199.     applyBlur(pixels, stride, width, height);
  200.  
  201.     //noise requires width, and height valid pixels
  202.     applyNoise(pixels, stride, x_within_field, y_within_field, width, height, iteration);
  203. }
  204.  
  205.  
  206.  
  207. int OlsenNoise2D::hashrandom(std::vector<long long int> elements)
  208. {
  209.     long long hashcalc = 0;
  210.  
  211.  
  212.     for (int i = 0; i < elements.size(); i++)
  213.     {
  214.         hashcalc ^= elements[i];
  215.         hashcalc = hash(hashcalc);
  216.     }
  217.     return (int) hashcalc;
  218. };
  219.  
  220. long long OlsenNoise2D::hash(long long v)
  221. {
  222.     long long hash = v;
  223.     long long h = hash;
  224.  
  225.     switch ((int) hash & 3)
  226.     {
  227.     case 3:
  228.         hash += h;
  229.         hash ^= hash << 32;
  230.         hash ^= h << 36;
  231.         hash += hash >> 22;
  232.         break;
  233.     case 2:
  234.         hash += h;
  235.         hash ^= hash << 22;
  236.         hash += hash >> 34;
  237.         break;
  238.     case 1:
  239.         hash += h;
  240.         hash ^= hash << 20;
  241.         hash += hash >> 2;
  242.     }
  243.     hash ^= hash << 6;
  244.     hash += hash >> 10;
  245.     hash ^= hash << 8;
  246.     hash += hash >> 34;
  247.     hash ^= hash << 50;
  248.     hash += hash >> 12;
  249.     return hash;
  250. };
  251.  
  252.  
  253.  
  254. int main()
  255. {
  256.  
  257.    /// Test
  258.     int ImageSize=2049;
  259.     int * imageInput = new int[ImageSize*ImageSize];
  260.  
  261.     /// Image
  262.     OlsenNoise2D testingolsen;
  263.     testingolsen.olsennoise(imageInput, 2, 0,0,ImageSize,ImageSize);
  264.  
  265.     SaveTerrFile(imageInput, ImageSize, "output.png");
  266.  
  267.     delete imageInput;http://pastebin.com/1i0vwJgv
  268.  
  269.  
  270.     return 1;
  271. }
  272.  
  273.  
  274. void SaveTerrFile(const int * image, int size, char * filename)
  275. {
  276.     png::image< png::rgb_pixel > newimage(size, size);
  277.  
  278.     for (unsigned int y = 0; y < newimage.get_width(); ++y)
  279.     {
  280.         for (unsigned int x = 0; x < newimage.get_height(); ++x)
  281.         {
  282.             int col = int(image[x+(y*newimage.get_width())]);
  283.             newimage[y][x] = png::rgb_pixel(col,col,col);
  284.             // non-checking equivalent of image.set_pixel(x, y, ...);
  285.         }
  286.     }
  287.  
  288.     newimage.write(filename);
  289. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement