Recently I modified my mandelbrot fractal generation program to be able to integrate gmp and mpfr in order to zoom deeper into the fractal.
But since I did this I have a segmentation error when I try to run the program
I’m pretty new to c language (but not in development) so excuse me if it’s a basic error
Here my code:
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <stdio.h>
#include <math.h>
#include <mpfr.h>
#include <gmp.h>
#include "stb_image.h"
#include "stb_image_write.h"
#define CHANNELS 3
typedef struct{
mpfr_t x, y;
} Point;
typedef struct{
int r, g, b;
} Color;
int width = 1000;
int height = 1000;
int maxIteration = 255;
int nbColors = 100;
char fileName[100] = "mandelbrot.bmp";
Color colors[100] = {
{0, 0, 0},
{255, 255, 255}
};
Color hexToRGB(const char *hex) {
Color rgb;
if (strlen(hex) == 6) {
sscanf(hex, "%2x%2x%2x", &rgb.r, &rgb.g, &rgb.b);
} else {
rgb.r = 0;
rgb.g = 0;
rgb.b = 0;
}
return rgb;
}
Color interpolate(Color colors[], int numColors, long double t) {
if (numColors <= 1) {
return colors[0];
}
long double segmentLength = 1.0 / (numColors - 1);
int segment = t / segmentLength;
long double segmentT = (t - segment * segmentLength) / segmentLength;
Color c1 = colors[segment];
Color c2 = colors[segment + 1];
Color result;
result.r = (unsigned char)(c1.r * (1 - segmentT) + c2.r * segmentT);
result.g = (unsigned char)(c1.g * (1 - segmentT) + c2.g * segmentT);
result.b = (unsigned char)(c1.b * (1 - segmentT) + c2.b * segmentT);
return result;
}
double floatingMod(double x, double y) {
double quotient = x / y;
double wholePart;
modf(quotient, &wholePart); // Récupère la partie entière du quotient
double result = x - wholePart * y;
return result;
}
int mandelbrot(Point point, int maxIteration) {
Point z, c;
mpfr_t temp, threshold, temp1, temp2;
mpfr_inits(z.x, z.y, c.x, c.y, temp, threshold, temp1, temp2);
//if((point.x < sqrt((point.x - 0.25)*(point.x - 0.25) + point.y*point.y) - 2*((point.x - 0.25)*(point.x - 0.25) + point.y*point.y) + 0.25) || ((point.x + 1) * (point.x + 1) + point.y*point.y < 0.0625)) return 0;
mpfr_set(z.x, point.x, MPFR_RNDN);
mpfr_set(z.y, point.y, MPFR_RNDN);
mpfr_set(c.x, point.x, MPFR_RNDN);
mpfr_set(c.y, point.y, MPFR_RNDN);
mpfr_set_str(threshold, "2.0", 10, MPFR_RNDN);
for(int iteration = 0; iteration < maxIteration; iteration++) {
mpfr_mul(temp1, z.x, z.x, MPFR_RNDN);
mpfr_mul(temp2, z.y, z.y, MPFR_RNDN);
mpfr_sub(temp, temp1, temp2, MPFR_RNDN);
mpfr_add(temp, temp, c.x, MPFR_RNDN);
mpfr_mul(z.y, z.x, z.y, MPFR_RNDN);
mpfr_mul_d(z.y, z.y, 2.0, MPFR_RNDN);
mpfr_add(z.y, z.y, c.y, MPFR_RNDN);
mpfr_set(z.x, temp, MPFR_RNDN);
mpfr_add(temp1, temp1, temp2, MPFR_RNDN);
if(mpfr_cmp(temp1, threshold) > 0) {
mpfr_clears(z.x, z.y, c.x, c.y, temp, threshold, temp1, temp2, NULL);
return iteration;
}
}
return 0;
}
int main(int argc, char *argv[]) {
long double zoomFactor;
mpfr_set_default_prec(256);
mpfr_t Xmin, Xmax, Ymin, Ymax;
mpfr_inits(Xmin, Xmax, Ymin, Ymax);
mpfr_set_str(Xmin, "-2.1", 10, MPFR_RNDN);
mpfr_set_str(Xmax, "0.6", 10, MPFR_RNDN);
mpfr_set_str(Ymin, "-1.2", 10, MPFR_RNDN);
mpfr_set_str(Ymax, "1.2", 10, MPFR_RNDN);
Point zoomCenter;
mpfr_inits(zoomCenter.x, zoomCenter.y);
mpfr_set_str(zoomCenter.x, "-0.75", 10, MPFR_RNDN);
mpfr_set_str(zoomCenter.y, "0.0", 10, MPFR_RNDN);
for(int arg = 1; arg < argc; arg+=2 ) {
if(strcmp(argv[arg], "--width") == 0) {
width = strtod(argv[arg + 1], NULL);
} else if(strcmp(argv[arg], "--height") == 0) {
height = strtod(argv[arg + 1], NULL);
} else if(strcmp(argv[arg], "--maxIteration") == 0) {
maxIteration = strtod(argv[arg + 1], NULL);
} else if(strcmp(argv[arg], "--zoomFactor") == 0) {
zoomFactor = strtold(argv[arg + 1], NULL);
} else if(strcmp(argv[arg], "--nbColors") == 0) {
nbColors = strtold(argv[arg + 1], NULL);
} else if(strcmp(argv[arg], "--fileName") == 0) {
sprintf(fileName, "%s", argv[arg + 1]);
} else if(strcmp(argv[arg], "--zoomCenter") == 0) {
mpfr_set_str(zoomCenter.x, strtok(argv[arg + 1], ","), 10, MPFR_RNDN);
mpfr_set_str(zoomCenter.y, strtok(NULL, ","), 10, MPFR_RNDN);
} else if(strcmp(argv[arg], "--palette") == 0) {
char *hexColorTokens[strlen(argv[arg + 1]) / 7 + 1];
char *token = strtok((char *)argv[arg + 1], ",");
int numColors = 0;
while (token != NULL) {
hexColorTokens[numColors++] = token;
token = strtok(NULL, ",");
}
for (int i = 0; i < numColors; i++) {
colors[i] = hexToRGB(hexColorTokens[i]);
}
}
}
unsigned char *imageData = (unsigned char *)malloc(width * height * CHANNELS);
long double colorNumber;
mpfr_t aspectRatio, valueX, valueY, temp1, temp2;
mpfr_inits(aspectRatio, valueX, valueY, temp1, temp2);
Point point;
mpfr_inits(point.x, point.y);
Color iterationColor;
int numColors = sizeof(colors) / sizeof(Color);
int iteration;
//aspect ratio
mpfr_set_d(aspectRatio, width, MPFR_RNDN);
mpfr_div_d(aspectRatio, aspectRatio, height, MPFR_RNDN);
if(width > height) {
mpfr_mul(Xmin, Xmin, aspectRatio, MPFR_RNDN);
mpfr_mul(Xmax, Xmax, aspectRatio, MPFR_RNDN);
} else if(width < height) {
mpfr_mul(Ymin, Ymin, aspectRatio, MPFR_RNDN);
mpfr_mul(Ymax, Ymax, aspectRatio, MPFR_RNDN);
}
/*zoom*/
zoomFactor *= 2;
//valueX
mpfr_sub(temp1, Xmax, Xmin, MPFR_RNDN);
mpfr_div_d(valueX, temp1, zoomFactor, MPFR_RNDN);
//valueY
mpfr_sub(temp1, Ymax, Ymin, MPFR_RNDN);
mpfr_div_d(valueY, temp1, zoomFactor, MPFR_RNDN);
mpfr_sub(Xmin, zoomCenter.x, valueX, MPFR_RNDN);
mpfr_add(Xmax, zoomCenter.x, valueX, MPFR_RNDN);
mpfr_sub(Ymin, zoomCenter.y, valueY, MPFR_RNDN);
mpfr_add(Ymin, zoomCenter.y, valueY, MPFR_RNDN);
for(int px = 0; px < width*height; px++) {
mpfr_sub(point.x, Xmax, Xmin, MPFR_RNDN);
mpfr_div_d(point.x, point.x, (width-1), MPFR_RNDN);
mpfr_mul_d(point.x, point.x, (px % width), MPFR_RNDN);
mpfr_add(point.x, point.x, Xmin, MPFR_RNDN);
mpfr_sub(point.y, Ymax, Ymin, MPFR_RNDN);
mpfr_div_d(point.y, point.y, (height-1), MPFR_RNDN);
mpfr_mul_d(point.y, point.y, floor(px / width), MPFR_RNDN);
mpfr_add(point.y, point.y, Ymin, MPFR_RNDN);
iteration = mandelbrot(point, maxIteration);
colorNumber = (long double)iteration/(long double)nbColors;
iterationColor = interpolate(colors, numColors, floatingMod((double)iteration/(double)nbColors, 1.0));
imageData[px*CHANNELS + 0] = iterationColor.r;
imageData[px*CHANNELS + 1] = iterationColor.g;
imageData[px*CHANNELS + 2] = iterationColor.b;
}
mpfr_clears(aspectRatio, valueX, valueY, temp1, temp2, point.x, point.y, NULL);
stbi_write_bmp(fileName, width, height, CHANNELS, imageData);
free(imageData);
return 0;
}
I did not try much because I do not understand the error well, nevertheless I tried to free the memory with `mpfr_clears’, but it did not change anything