/* JMS -- 5 juillet 2003 ---------------------------------------------------- 
Compilation : 
gcc mandel02B -o mandel02B -lgd                                              
Appel :                                                                     
./mandel02B TAILLE MAXITER SEUIL palette RES XMIN XMAX YMIN YMAX GAIN     
----------------------------------------------------------------------------- */

#include <unistd.h>
#include <gd.h>
#include <stdlib.h>

long **IMG;

long MAXITER;

int TAILLE,SEUIL,RES;

double XMIN,XMAX,YMIN,YMAX,GAIN;

/* --- polynôme cubique pour « parcourir » l'espace RVB --------------------- */
float PolyCubique (int n, float x) {
    int i;
    for (i = 0; i < n ; i++) {
        x = 16 * x * (x - 0.75) * (x - 0.75);
    }
    return x;
}


/* --- index mandelbrot ----------------------------------------------------- */
long Mandelbrot (double x, double y, int f) {
    int n, m; 
    long iter = 0;
    double t, tx = 0, ty = 0;
    while ( tx * tx + ty * ty < 4  && iter < MAXITER ) {
        t = tx * tx - ty * ty + x;
        ty = 2 * tx * ty + y;
        tx = t;
        if (f && iter > SEUIL) {
            n = (tx - XMIN) / (XMAX - XMIN) * TAILLE ;
            m = (ty - YMIN) / (YMAX - YMIN) * TAILLE;
            if (tx > XMIN && tx < XMAX && ty > YMIN && ty < YMAX)
                IMG[n][m]++;
        }
        iter++;
    }
    return iter;
}

int Max (int a, int b) {
    if ( a < b )
        return b;
    return a;
}


int main (int argc, char *argv[]) {
    gdImagePtr image;
    
    int i,j,rouge,vert,bleu,max;
    
    int palette = 0;
    int densite = 0;

    long h,k,m;    
    
    double t,x,y;

    /* récupération des arguments */
    sscanf(argv[1],"%d",&TAILLE);
    sscanf(argv[2],"%d",&MAXITER);
    sscanf(argv[3],"%d",&SEUIL);
    sscanf(argv[4],"%d",&palette);
    sscanf(argv[5],"%d",&RES);
    
    XMIN = atof(argv[6]);
    XMAX = atof(argv[7]);
    YMIN = atof(argv[8]);
    YMAX = atof(argv[9]);
    
    GAIN = atof(argv[10]);


    /* allocation de la mémoire image */
    IMG = malloc(TAILLE * sizeof(int *));
    for (i=0;i<TAILLE;i++)
        IMG[i] = malloc(TAILLE * sizeof(int));
    for (i=0;i<TAILLE;i++) {
        for (j=0;j<TAILLE;j++) {
            IMG[i][j] = 0;
        }
    }
    
    
    image = gdImageCreate(TAILLE,TAILLE);

    switch (palette) {
        case 0 : for (i = 0; i <= 255 ; i++ ) {
                    t = (double) i / 255;
                    rouge  = i;
                    vert   = 255 * PolyCubique(1,t);
                    bleu   = 255 * PolyCubique(2,t);
                    gdImageColorAllocate(image,rouge,vert,bleu);
                }
                break;
        default : for(i=0;i<=255;i++) 
                    gdImageColorAllocate(image,i,i,i);        
                break;
    }
    
    m = TAILLE * RES ;
    
    for ( k = 0 ; k < m ; k++) {
        for (h = 0 ; h < m ; h++) {
            x = - 2.0 + 3.0 * k / m;
            y = - 1.5 + 3.0 * h / m;
            if (Mandelbrot(x,y,0) < MAXITER) 
                Mandelbrot(x,y,1);
        }
    }

    max = 0;    
    for ( i=0 ; i<TAILLE ; i++)
        for (j=0 ; j<TAILLE ; j++) 
            max = Max(max,IMG[i][j]);
    
    fprintf(stderr,"Le maximum atteint est %d\n",max);
    
    for(i = 0 ; i < TAILLE ; i++) 
        for(j = 0 ; j < TAILLE ; j++) {
            t = IMG[j][i] / ( max / GAIN ) ;
            if (t > 1) 
                t = 1; 
                gdImageSetPixel(image,i,j, t * 255);
        }
    
    gdImageJpeg(image,stdout,100);
    gdImageDestroy(image);
    exit(0);
}