0
votes

I made a program in C++ which calculates the mandelbrot-set. Now I want to visualize it (save it in a picture). But when I try to save a 64k picture some problems come up. So what is the best way to save a picture of the pixels or at least to visual it?

Edit:

When I want to create a for Example 64K (61440 * 34560) image there will be the error "Access violation while writing at the position 0x0..." (originally on German and translated) and the program stops. This error appears with very high resolution. On lower resolutions the program works as it is supposed to.

#include <SFML\Graphics.hpp>
#include <stdlib.h>
#include <complex>
#include <cmath>
#include <thread>

//4K :   3840 *  2160
//8K :   7680 *  4320
//16K:  15360 *  8640
//32K:  30720 * 17280
//64K:  61440 * 34560
//128K:122880 * 69120


const unsigned long width  = 61440; //should be dividable by ratioX & numberOfThreads!
const unsigned long height = 34560; //should be dividable by ratioY & numberOfThreads!

const unsigned int maxIterations = 500;

const unsigned int numberOfThreads = 6;

const int maxWidth = width / 3;
const int maxHeight = height / 2;
const int minWidth = -maxWidth * 2;
const int minHeight = -maxHeight;

const double ratioX = 3.0 / width;
const double ratioY = 2.0 / height;

sf::Image img = sf::Image();


int getsGreaterThan2(std::complex<double> z, int noIterations) {
    double result;
    std::complex<double> zTmp = z;
    std::complex<double> c = z;
    for (int i = 1; i != noIterations; i++) {
        zTmp = std::pow(z, 2) + c;
        if (zTmp == z) {
            return 0;
        }
        z = std::pow(z, 2) + c;
        result = std::sqrt(std::pow(z.real(), 2) + std::pow(z.imag(), 2));
        if (result > 2) {
            return i;
        }
    }
    return 0;
}


void fillPixelArrayThreadFunc(int noThreads, int threadNr) { //threadNr ... starts from 0

    double imgNumber;
    double realNumber;

    double tmp;

    long startWidth = ((double)width) / noThreads * threadNr + minWidth;
    long endWidth = startWidth + width / noThreads;

    for (long x = startWidth; x < endWidth; x++) {
        imgNumber = x * ratioX;
        for (long y = minHeight; y < maxHeight; y++) {
            realNumber = y * ratioY;
            long xArray = x - minWidth;
            long yArray = y - minHeight;
            tmp = getsGreaterThan2(std::complex<double>(imgNumber, realNumber), maxIterations);
            if (tmp == 0) {
                img.setPixel(xArray, yArray, sf::Color(0, 0, 0, 255));
            }
            else {
                img.setPixel(xArray, yArray, sf::Color(tmp / maxIterations * 128, tmp / maxIterations * 128, tmp / maxIterations * 255, 255));
            }
        }
    }
}

int main() {
    img.create(width, height, sf::Color::Black);

    std::thread *threads = new std::thread[numberOfThreads];
    for (int i = 0; i < numberOfThreads; i++) {
        threads[i] = std::thread(std::bind(fillPixelArrayThreadFunc, numberOfThreads, i));
    }
    for (int i = 0; i < numberOfThreads; i++) {
        threads[i].join();
    }

    img.saveToFile("filename.png");
    return 1;
}
1
Welcome to stackoverflow.com. Please take some time to read the help pages, especially the sections named "What topics can I ask about here?" and "What types of questions should I avoid asking?". Also please take the tour and read about how to ask good questions. Lastly please learn how to create a Minimal, Complete, and Verifiable Example. - Some programmer dude
when I try to save a 64k picture some problems come up... And what exactly are these problems? You cannot expect anyone to give a valid answer with such a vague description. - Jabberwocky
What picture format are you saving as: JPEG? TIFF? PNG? GIF? BMP? WMF? Are there any size limitations for the format you are using? - Thomas Matthews
I am sorry for the bad explaination. It was rather meant as a general question of how to save it properly (which file-format/methods). But I will upload my code shortly. - SgtDomo
Did you run it with a debugger ? - Jabberwocky

1 Answers

0
votes

Your program fails during the call img.create(width, height, sf::Color::Black);.

When you step into the sf::Image::create function you end up here where the newPixels vector is created, this simply fails when width * height is too big as in your case:

////////////////////////////////////////////////////////////
void Image::create(unsigned int width, unsigned int height, const Color& color)
{
    if (width && height)
    {
        // Create a new pixel buffer first for exception safety's sake
        std::vector<Uint8> newPixels(width * height * 4);
                                     ^61440* ^34560 = 8'493'465'600 bytes !!

Conclusion: SFML cannot handle huge images.