// Copyright 2007 Ilan Pillemer // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #define WIDTH 1024 #define HEIGHT 768 unsigned short bfType; /* Magic number for file */ typedef struct /**** BMP file header structure ****/ { unsigned int bfSize; /* Size of file */ unsigned short bfReserved1; /* Reserved */ unsigned short bfReserved2; /* ... */ unsigned int bfOffBits; } BITMAPFILEHEADER; typedef struct /**** BMP file info structure ****/ { unsigned int biSize; /* Size of info header */ int biWidth; /* Width of image */ int biHeight; /* Height of image */ unsigned short biPlanes; /* Number of color planes */ unsigned short biBitCount; /* Number of bits per pixel */ unsigned int biCompression; /* Type of compression to use */ unsigned int biSizeImage; /* Size of image data */ int biXPelsPerMeter; /* X pixels per meter */ int biYPelsPerMeter; /* Y pixels per meter */ unsigned int biClrUsed; /* Number of colors used */ unsigned int biClrImportant; /* Number of important colors */ } BITMAPINFOHEADER; typedef struct { unsigned char red; unsigned char green; unsigned char blue; } Colour; typedef struct { unsigned char blue; unsigned char green; unsigned char red; } Pixel; typedef struct { Pixel col[WIDTH]; } Column; typedef struct { Column row[HEIGHT]; } Picture; typedef struct { int x; int y; } Point; int rand(); //clears background in white void clear (Picture * picture) { int i,j; for (i = 0; i < HEIGHT; i++) for (j = 0; j < WIDTH; j++) { (picture->row[i]).col[j].red = 255; (picture->row[i]).col[j].green =255; (picture->row[i]).col[j].blue = 255; } } // draws a point in specified colour. void draw_point(Picture * src, Point * point, Colour * colour) { src->row[point->y].col[point->x].red = colour->red; src->row[point->y].col[point->x].green = colour->green; src->row[point->y].col[point->x].blue = colour->blue; } void draw_test(Picture * picture) { } void draw_sierpinksi(Picture * picture, int width, int height) { /* A triangle */ Point vertices[3]; Colour colours[3]; vertices[0].x = 0; vertices[0].y = 0; vertices[1].x = width/2; vertices[1].y= height; vertices[2].x = width; vertices[2].y = 0; colours[0].red = 255; colours[0].green = 0; colours[0].blue = 0; colours[1].red = 0; colours[1].green = 255; colours[1].blue = 0; colours[2].red = 0; colours[2].green = 0; colours[2].blue = 255; /* Choose a boring point somewhere */ Point S; Colour S_Colour; S.x=width/2; S.y=height/2; S_Colour.red = 0; S_Colour.green = 0; S_Colour.blue = 0; int j,k; for (k=0; k<1000000; k++){ j=rand()%3; S.x = (S.x + vertices[j].x) / 2; S.y = (S.y + vertices[j].y) / 2; S_Colour.red = (S_Colour.red + colours[j].red) / 2; S_Colour.green = (S_Colour.green + colours[j].green) / 2; S_Colour.blue = (S_Colour.blue + colours[j].blue) / 2; draw_point(picture,&S,&S_Colour); } } void saveBMP(){ int i, j, rc, arraypos; FILE* bitfile; BITMAPFILEHEADER header; BITMAPINFOHEADER info; bfType = 19778; /* magic, magic, magic */ header.bfReserved1 = 0; header.bfReserved2 = 0; header.bfOffBits = 54; info.biSize = 40; info.biWidth = WIDTH; info.biHeight = HEIGHT; info.biPlanes=1; info.biBitCount=24; info.biCompression=0; info.biSizeImage=0; info.biXPelsPerMeter=0; info.biYPelsPerMeter=0; info.biClrUsed=0; info.biClrImportant=0; unsigned int bytesPerPixel = (unsigned int)(info.biBitCount >> 3); unsigned int extraBytes = ((unsigned int)info.biWidth * bytesPerPixel) % 4; unsigned int adjustedLineSize = bytesPerPixel * ((unsigned int)info.biWidth + extraBytes); unsigned int sizeOfImageData = (unsigned int)(info.biHeight) * adjustedLineSize; header.bfSize = header.bfOffBits + sizeOfImageData; bitfile = fopen("sierpinski.bmp","wb"); printf("size of header:%d\n",sizeof(BITMAPFILEHEADER)); rc = fwrite(&bfType,2,1,bitfile); rc = fwrite(&header,sizeof(BITMAPFILEHEADER),1,bitfile); rc = fwrite(&info,sizeof(BITMAPINFOHEADER),1,bitfile); /* Note to make this code crossplatform simply call malloc(WIDTH * HEIGHT * 3) I have used sbrk() for my own amusement; but this will not work on non-*ix systems. If you remove the sbrk() here; you will also need to comment out the second reference*/ Picture * picture = (Picture *) sbrk(WIDTH * HEIGHT * 3); clear(picture); for (i=555; i>0; i--) { draw_sierpinksi(picture,1024-i,768-i); } //write picture to file for (i = 0; i < HEIGHT; i++) fwrite (&(picture->row[i]),WIDTH*3,1,bitfile); fclose (bitfile); picture=0; sbrk(-(WIDTH * HEIGHT * 3)); /* remove this if you malloc; you could replace it with the relevant free() call if you feel like it. */ } int main() { saveBMP(); printf("Hmmm...\n"); return 0; }