Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Original Author @author Tat
- * Mod code Vivienne Anthony
- * c++ rewrite vivienne (WIP)
- * verion 1.0 Functional Rewrite
- *
- * Changes
- * Java to C++ conversion
- * Memory pointer usage
- */
- #include <iostream>
- #include <vector>
- #include <stdio.h>
- #include <stdlib.h>
- #include <png++/png.hpp>
- using namespace std;
- void SaveTerrFile(const int * image, int size, char * filename);
- class OlsenNoise2D
- {
- public:
- OlsenNoise2D();
- void convolve(int * pixels, int offset, int stride, int x, int y, int width, int height, int * matrix, int matrixwidth, int matrixheight, int parts);
- int getRequiredDim(int dim);
- void olsennoise(int * pixels, int stride, int x, int y, int width, int height);
- void olsennoise(int * pixels, int stride, int x_within_field, int y_within_field, int width, int height, int iteration);
- private:
- int crimp(int color);
- int convolve(int * pixels, int stride, int index, int * matrix, int matrixwidth, int matrixheight, int parts);
- void applyNoise(int * pixels, int stride, int x_within_field, int y_within_field, int width, int height, int iteration);
- void applyBlur(int * pixels, int stride, int width, int height);
- void applyScale(int * pixels, int stride, int width, int height);
- void trim(int * pixels, int width, int height, int * workingpixels, int workingstride);
- int hashrandom(std::vector<long long int> elements);
- long long hash(long long v);
- int maxiterations;
- int * blur2x2;
- };
- OlsenNoise2D::OlsenNoise2D()
- {
- maxiterations = 7;
- blur2x2= new int(4);
- /// fill memory
- blur2x2[0]=1;
- blur2x2[1]=1;
- blur2x2[2]=1;
- blur2x2[3]=1;
- }
- 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)
- {
- int startIndex = x + (y * stride);
- int lastIndex = (x + width - 1) + ((y + height - 1) * stride);
- int x_pos = x;
- int y_pos = y;
- int indexInc = 1;
- int yinc = 0;
- int xinc = 1;
- for (int i = 0, s = width + (height*width); i < s; i++)
- {
- if (i == width)
- {
- indexInc = stride;
- yinc = 1;
- xinc = 0;
- }
- int x_counter = x_pos;
- int index = startIndex;
- while (x_counter >= x && index <= lastIndex)
- {
- pixels[offset + index] = convolve(pixels, stride, offset + index, matrix, matrixwidth, matrixheight,parts);
- x_counter--;
- index += stride - 1;
- }
- startIndex += indexInc;
- x_pos += xinc;
- y_pos += yinc;
- }
- }
- int OlsenNoise2D::crimp(int color)
- {
- return (color >= 0xFF) ? 0xFF : (color < 0) ? 0 : color;
- }
- int OlsenNoise2D::convolve(int * pixels, int stride, int index, int * matrix, int matrixwidth, int matrixheight, int parts)
- {
- int redSum = 0;
- int greenSum = 0;
- int blueSum = 0;
- int pixel, factor;
- for (int j = 0, m = matrixheight; j < m; j++, index++)
- {
- for (int k = 0, n = matrixwidth, q = index; k < n; k++, q += stride)
- {
- pixel = pixels[q];
- factor = matrix[j*(k*matrixwidth)];
- redSum += factor * ((pixel >> 16) & 0xFF);
- greenSum += factor * ((pixel >> 8) & 0xFF);
- blueSum += factor * ((pixel) & 0xFF);
- }
- }
- return 0xFF000000 | ((crimp(redSum / parts) << 16) | (crimp(greenSum / parts) << 8) | (crimp(blueSum / parts)));
- }
- //occupies same footprint
- void OlsenNoise2D::applyNoise(int * pixels, int stride, int x_within_field, int y_within_field, int width, int height, int iteration)
- {
- int index = 0;
- for (int k = 0, n = height - 1; k <= n; k++, index += stride)
- {
- for (int j = 0, m = width - 1; j <= m; j++)
- {
- int current = index + j;
- pixels[current] += (hashrandom( {x_within_field + j, y_within_field + k, iteration}) & (1 << (7 - iteration)));
- }
- }
- }
- //requires half the height and width be good.
- void OlsenNoise2D::applyScale(int * pixels, int stride, int width, int height)
- {
- int index = (height - 1) * stride;
- for (int k = 0, n = 0 + height - 1; k <= n; n--, index -= stride)
- {
- for (int j = 0, m = width - 1; j <= m; m--)
- {
- int current = index + m;
- int lower = ((n / 2) * stride) + (m / 2);
- pixels[current] = pixels[lower];
- }
- }
- }
- void OlsenNoise2D::applyBlur(int * pixels, int stride, int width, int height)
- {
- convolve(pixels, 0, stride,0,0, width, height, blur2x2, 2,2,4);
- }
- //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.
- int OlsenNoise2D::getRequiredDim(int dim)
- {
- return (dim + 5) * 2;
- }
- void OlsenNoise2D::trim(int * pixels, int width, int height, int * workingpixels, int workingstride)
- {
- for (int k = 0; k < height; k++)
- {
- for (int j = 0; j < width; j++)
- {
- int index = j + (k * width);
- int workingindex = j + (k * workingstride);
- pixels[index] = workingpixels[workingindex];
- }
- }
- }
- void OlsenNoise2D::olsennoise(int * pixels, int stride, int x, int y, int width, int height)
- {
- for(int i=0;i<width*height;i++)
- {
- pixels[i]=0xFF000000;
- }
- olsennoise(pixels, stride, x, y, width, height, maxiterations);
- }
- void OlsenNoise2D::olsennoise(int * pixels, int stride, int x_within_field, int y_within_field, int width, int height, int iteration)
- {
- if (iteration == 0)
- {
- applyNoise(pixels, stride, x_within_field, y_within_field, width, height, iteration);
- return;
- }
- olsennoise(pixels, stride, (x_within_field/2)-2, (y_within_field/2)-2, (width/2)+2, (height/2) + 2, iteration - 1);
- //scale only requires (width/2+1) and (height/2+1) valid pixels.
- applyScale(pixels, stride, width+1, height+1);
- //blur only requires width+1 and height+1 valid pixels.
- applyBlur(pixels, stride, width, height);
- //noise requires width, and height valid pixels
- applyNoise(pixels, stride, x_within_field, y_within_field, width, height, iteration);
- }
- int OlsenNoise2D::hashrandom(std::vector<long long int> elements)
- {
- long long hashcalc = 0;
- for (int i = 0; i < elements.size(); i++)
- {
- hashcalc ^= elements[i];
- hashcalc = hash(hashcalc);
- }
- return (int) hashcalc;
- };
- long long OlsenNoise2D::hash(long long v)
- {
- long long hash = v;
- long long h = hash;
- switch ((int) hash & 3)
- {
- case 3:
- hash += h;
- hash ^= hash << 32;
- hash ^= h << 36;
- hash += hash >> 22;
- break;
- case 2:
- hash += h;
- hash ^= hash << 22;
- hash += hash >> 34;
- break;
- case 1:
- hash += h;
- hash ^= hash << 20;
- hash += hash >> 2;
- }
- hash ^= hash << 6;
- hash += hash >> 10;
- hash ^= hash << 8;
- hash += hash >> 34;
- hash ^= hash << 50;
- hash += hash >> 12;
- return hash;
- };
- int main()
- {
- /// Test
- int ImageSize=2049;
- int * imageInput = new int[ImageSize*ImageSize];
- /// Image
- OlsenNoise2D testingolsen;
- testingolsen.olsennoise(imageInput, 2, 0,0,ImageSize,ImageSize);
- SaveTerrFile(imageInput, ImageSize, "output.png");
- delete imageInput;http://pastebin.com/1i0vwJgv
- return 1;
- }
- void SaveTerrFile(const int * image, int size, char * filename)
- {
- png::image< png::rgb_pixel > newimage(size, size);
- for (unsigned int y = 0; y < newimage.get_width(); ++y)
- {
- for (unsigned int x = 0; x < newimage.get_height(); ++x)
- {
- int col = int(image[x+(y*newimage.get_width())]);
- newimage[y][x] = png::rgb_pixel(col,col,col);
- // non-checking equivalent of image.set_pixel(x, y, ...);
- }
- }
- newimage.write(filename);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement