#include <stdio.h>
#include <stdlib.h>
#define COLOR 256
#define MASK 0x00FF
#define XMAX 512
#define YMAX 512
/* BMP-file headders */
unsigned short bfType; /* 'B', 'M' */
struct {
unsigned long bfSize; /* file size */
unsigned long reserved0; /* reserved */
unsigned long hsize; /* headder size */
unsigned long biSize; /* size of BITMAPINFOHEADER; I don't use it */
unsigned long bmpX; /* X size */
unsigned long bmpY; /* Y size */
} headder0;
unsigned short biPlanes; /* 0x0001 */
unsigned short biBitCount; /* colors = 2^biBitCount */
struct {
unsigned long biCompression; /* compression type */
unsigned long biSizeImage; /* image size */
long biXPixPerMeter; /* holizontal resolution */
long biYPixPerMeter; /* vertical resolution */
unsigned long biClrUsed; /* recommended to be 0 */
unsigned long biClrImporant; /* recommended to be 0 */
} headder1;
unsigned long irgb[COLOR]; /* color palette */
double centR, centL, width;
unsigned short initial(char *av1)
{
unsigned short maxRp;
unsigned char input[36];
printf("\tCenter of the image; REAL PART ==> ");
fgets(input, 32, stdin);
centR = atof(input);
printf("\tCenter of the image; IMAGINARY PART ==> ");
fgets(input, 32, stdin);
centL = atof(input);
printf("\tScreenwidth ==> ");
fgets(input, 32, stdin);
if(0.0 >= (width = atof(input)))
{
printf("\n\terror: screenwidth must be above zero");
return 1;
}
printf("\tMaximum repeat(256 to 65535)==> ");
fgets(input, 32, stdin);
if(256 > (maxRp = atoi(input))) maxRp = 256;
if(centL < 0.0)
{
printf("\n\tcenter = %20.17f %20.17fi\n\tscreenwidth = %20.17f, max repeat = %d\n\n", centR, centL, width, maxRp);
}
else
{
printf("\n\tcenter = %20.17f +%20.17fi\n\tscreenwidth = %20.17f, max repeat = %d\n", centR, centL, width, maxRp);
}
return maxRp;
}
int putHeadder(FILE *fp)
{
int i, j;
biBitCount = 8;
bfType = 0x4d42; /* 'B', 'M' */
if(-1 == fwrite(&bfType, sizeof(bfType), 1, fp)) return -1;
headder0.hsize = sizeof(bfType) + sizeof(headder0) + sizeof(biPlanes) +
sizeof(biBitCount) + sizeof(headder1) + sizeof(irgb);
headder0.bfSize = headder0.hsize + XMAX*YMAX*biBitCount/8;
headder0.biSize = sizeof(headder0.biSize) + sizeof(headder0.bmpX) +
sizeof(headder0.bmpY) + sizeof(biPlanes) + sizeof(biBitCount) +
sizeof(headder1);
headder0.bmpX = XMAX;
headder0.bmpY = YMAX;
if(-1 == fwrite(&headder0, sizeof(headder0), 1, fp)) return -1;
biPlanes = 0x0001;
if(-1 == fwrite(&biPlanes, sizeof(biPlanes), 1, fp)) return -1;
if(-1 == fwrite(&biBitCount, sizeof(biBitCount), 1, fp)) return -1;
if(-1 == fwrite(&headder1, sizeof(headder1), 1, fp)) return -1;
j = 0x00000000;
for(i = 0; i < (2 << biBitCount); i++)
{
irgb[i] = j;
j += 0x00010101;
}
return(fwrite(irgb, sizeof(irgb), 1, fp));
}
int main(int argc, char *argv[])
{
unsigned short maxRp, calc, xx, yy;
unsigned char *buff; /* pointer for the buffer[] */
unsigned char buffer[XMAX];
double scale, rx, rx0, iy, real, real2, imag, imag2;
FILE *fp;
if(2 != argc)
{
printf("Usage: %s filename.bmp\n", argv[0]);
return -1;
}
if((maxRp = initial(argv[1])) < 256) return -2;
if(NULL == (fp = fopen(argv[1], "w")))
{
printf("cannot create this file: %s\n", argv[1]);
return -2;
}
if(-1 == putHeadder(fp))
{
printf("BitMap headder write error: %s\n", argv[1]);
return -3;
}
scale = width / YMAX; /* size between each pixel */
rx0 = centR - (XMAX/2)*(width/YMAX); /* left under corner's real part */
iy = centL - width/2.0 - scale; /* left under corner's imaginary part */
for(yy = 0; yy < YMAX; yy++)
{
rx = rx0; iy += scale;
buff = buffer;
for(xx = 0; xx < XMAX; xx++)
{
real = rx; imag = iy;
for(calc = 0; calc < maxRp; calc++)
{
real2 = real*real; imag2 = imag*imag;
if(4.0 <= (real2 + imag2))
{
*buff = (char)(calc & MASK);
goto jump;
}
imag *= (real+real);
imag += iy;
real = real2 - imag2 + rx;
}
*buff = 0; /* if 'n' reached 'repeat max', set a black dot */
jump:
rx += scale;
buff++;
}
fwrite(buffer, XMAX, 1, fp);
}
fclose(fp);
return 0;
}