/**
 * Creates an image with the perlin noise. If the depth value is to big the biggest working value is used.
 * For possible scaling flags see (Image::)scale(), (Image::)smooth() and (Image::)createWhiteNoise().
 * (default flags = WHITE_NOISE_GREY | SMOOTH_NORMAL | SCALE_NEAREST_NEIGHBOR)
 * @param width of the image
 * @param height of the image
 * @param range for the random values
 * @param seed for the random number generator
 * @param number of interation
 * @param weight of the new noise (towards 0 makes the image smoother)
 * @param flags
 * @return the created image
 * @throw bad_alloc exception if something went wrong while allocating memory
 */
Image Image::createPerlinNoise(size_t width, size_t height, unsigned int seed, unsigned char range, unsigned int depth, float weight, unsigned char flags)
{
    float currentWidth = width;
    float currentHeight = height;
    unsigned int actualDepth = 0;
    //reduce the resolution to the requested depth
    for(unsigned int i = 0; i <= depth && currentWidth >= 2 && currentHeight >= 2; ++i)
    {
        currentWidth /= 2;
        currentHeight /= 2;
        actualDepth = i;
    }
    //prevent too high depth
    depth = actualDepth;
    //fill the new image with white noise
    Image img = createWhiteNoise((size_t)ceil(currentWidth), (size_t)ceil(currentHeight), seed, flags, range);
    img.smooth(flags);
    //merge with bigger smoothed noise images until the given depth is reached
    for(unsigned int i = 0; i < depth; ++i)
    {
        currentWidth *= 2;
        currentHeight *= 2;
        Image newImg = createWhiteNoise((size_t)ceil(currentWidth), (size_t)ceil(currentHeight), seed, flags, range);
        newImg.smooth(flags);
        img.scale(2.0f, 2.0f, flags);
        img.smooth(flags);
        img.maximizeContrast();
        img = mergeImages(img, newImg, weight, flags);
    }
    return img;
}
Example #2
0
void merge (FILE *pbmImage1, FILE *pbmImage2) {

	int fSize1 = size(pbmImage1);
	int fSize2 = size(pbmImage2);
	int fSize;
	int pbmHeight1, pbmWidth1;
	int pbmHeight2, pbmWidth2;
	int pbmHeight, pbmWidth;

	// Error checking file sizes
	if (fSize1 != fSize2) {
		fprintf(stderr, "PBM image sizes do not match. Image1: %i, Image2: %i\n", fSize1, fSize2);
		exit(-1);
	}
	
	// Assign global file size for both images
	fSize = fSize1;

	// Set up image chars
	unsigned char *inputBuffer1 = malloc(fSize);
	unsigned char *inputBuffer2 = malloc(fSize);
	memset(inputBuffer1, 0, fSize);
	memset(inputBuffer2, 0, fSize);


	// Process Height and Width of image 1
	if (!fgets((char *)inputBuffer1, sizeof(inputBuffer1), pbmImage1)) {
		fprintf(stderr, "Unable to read image format.\n");
		exit(-1);
	}

	if (inputBuffer1[0] != 'P' || inputBuffer1[1] != '4') {
		fprintf(stderr, "Invalid image format. Must be P4.\n");
		exit(-1);
	}

	if (fscanf(pbmImage1, "%d %d", &pbmWidth1, &pbmHeight1) != 2) {
		fprintf(stderr, "Invalid image size.\n");
		exit(-1);
	}

	// Process Height and Width of image 2
	if (!fgets((char *)inputBuffer2, sizeof(inputBuffer2), pbmImage2)) {
		fprintf(stderr, "Unable to read image format.\n");
		exit(-1);
	}

	if (inputBuffer2[0] != 'P' || inputBuffer2[1] != '4') {
		fprintf(stderr, "Invalid image format. Must be P4.\n");
		exit(-1);
	}

	if (fscanf(pbmImage2, "%d %d", &pbmWidth2, &pbmHeight2) != 2) {
		fprintf(stderr, "Invalid image size.\n");
		exit(-1);
	}

	// Error checking to make sure image 1 is the same dimensions as image 2
	if (pbmWidth1 != pbmWidth2 && pbmHeight1 != pbmHeight2) {
		fprintf(stderr, "PBM Image dimensions do not match. Image 1\tWidth: %i\tHeight: %i\nImage 2\t Width: %i\tHeight: %i\n", pbmWidth1, pbmHeight1, pbmWidth2, pbmHeight2);
		exit(-1);
	}
	else {
		pbmWidth = pbmWidth1;
		pbmHeight = pbmHeight1;
	}


	// Read the image into respective buffers
	fread(inputBuffer1, fSize - 4, 1, pbmImage1);	
	fread(inputBuffer2, fSize - 4, 1, pbmImage2);

	// Finally merge images to output to stdout
	mergeImages(inputBuffer1, inputBuffer2, pbmHeight, pbmWidth, fSize);

}