#include #include #include #include #include /* this program only works on little-endian CPUs */ /* www.ece.ualberta.ca/~elliott/ee552/studentAppNotes/2003_w/misc/bmp_file_format/bmp_file_format.htm BMP: header 14 bytes signature 2 bytes BM filesize 4 bytes in bytes reserved 4 bytes unused, set to zero dataoffset 4 bytes offset to beginning of pixel data, set to 0x36 infohdr 40 bytes size 4 bytes size of infoheader, set to 40 width 4 bytes width of image, number of columns height 4 bytes height in pixels as well, number of lines planes 2 bytes number of planes, idrk, set to 1 bits per pixel 2 bytes set to 24 compression 4 bytes set to 0, no compression imagesize 4 bytes set to 0, since we use no compression xpixelSPERM 4 bytes pixels per meter. thanks microsoft. set to 1 ypixelSPERM 4 bytes pixels per meter. thanks microsoft. set to 1 colorsused 4 bytes number of actually used colours. set to 16777216 (2**24) importantcolors 4 bytes idrk, thanks microsoft. set to 0, that way all colors are imp colortable 4 * numcolors ( = zero ) bytes pixeldata width * height * 3 bytes triplets of bytes: first byte blue, second byte green, third byte red over and over. lines must be padded to the nearest 4-byte boundary, so make your life easier (: lines are sent from bottom to top. thanks microsoft. */ struct piksel { uint8_t r; uint8_t g; uint8_t b; }; struct bmpheader { char signature[2] /* packed ignored for char */; uint32_t filesize __attribute__((packed)); uint32_t reserved __attribute__((packed)); uint32_t dataoffset __attribute__((packed)); uint32_t size __attribute__((packed)); uint32_t width __attribute__((packed)); uint32_t height __attribute__((packed)); uint16_t planes __attribute__((packed)); uint16_t bitsperpixel __attribute__((packed)); uint32_t compression __attribute__((packed)); uint32_t imagesize __attribute__((packed)); uint32_t xpixelsperm __attribute__((packed)); uint32_t ypixelsperm __attribute__((packed)); uint32_t colorsused __attribute__((packed)); uint32_t importantcolors __attribute__((packed)); } __attribute__((packed)); void bmpheader_init (struct bmpheader * in) { in->signature[0] = 'B'; in->signature[1] = 'M'; in->reserved = 0; in->dataoffset = 14+40; in->size = 40; in->planes = 1; in->bitsperpixel = 24; in->compression = 0; in->imagesize = 0; in->xpixelsperm = 1; in->ypixelsperm = 1; in->colorsused = 16777216; /* 2^24 */ in->importantcolors = 0; } int shraniBMP (struct piksel ** in, unsigned int cols, unsigned int lines, FILE * out) { #define LINELEN (cols*3+((4-cols*3%4) == 4 ? 0 : 4-cols*3%4)) /* returns negative on fail or 1 on success */ struct bmpheader bh = { .filesize = 14+40+LINELEN*lines, .width = cols, .height = lines }; bmpheader_init(&bh); if (!fwrite(&bh, sizeof(bh), 1, out)) { fprintf(stderr, "NAPAČA pri pisanju v FILE\n"); return -1; } for (unsigned int i = lines-1; 1; i--) { for (unsigned int j = 0; j < cols; j++) { #define PISIBARVO(x) if (!fwrite(&in[i][j].x, 1, 1, out)) { \ fprintf(stderr, "NAPAČA pri pisanju barve\n"); \ return -2; \ } PISIBARVO(b) PISIBARVO(g) PISIBARVO(r) } if (4 - cols*3%4 != 4) { /* fprintf(stderr, "pišem %d bajtov paddinga\n", cols*3%4); */ char krneki[4] = "\0\0\0"; if (fwrite(krneki, 1, 4 - cols*3%4, out) != 4 - cols*3%4) { fprintf(stderr, "NAPAČA pri pisanju paddinga\n"); return -3; } } if (i == 0) break; } return 1; } long double complex preberi (char * in) { long double r = 0; long double i = 0; preberi: ; long double nasl = strtold(in, &in); if (in[0] == 'i') { /* pravkar je bil povedan imaginarni del */ fprintf(stderr, "je bil povedan imaginarni del\n"); i = nasl; in++; } else { fprintf(stderr, "je bil povedan realni del\n"); r = nasl; } if (in[0] == '+' || in[0] == '-') /* imamo še eno */ goto preberi; long double complex out = r + i * I; return out; } #define P(z) (cpowl(z, 2)+c) int main (int argc, char ** argv) { if (argc != 1+2+3) { fprintf(stderr, "uporaba: %s 512 -13.32344-3.0123i 0 0 1\n", argv[0] ? argv[0] : "hekr"); return 1; } int offset1 = atoi(argv[3]); int offset2 = atoi(argv[4]); long double scale = strtold(argv[5], NULL); int dim = atoi(argv[1]); long double dimf = dim; long double complex c = preberi(argv[2]); struct piksel ** piksli = calloc(1, dim*sizeof(*piksli)); for (int i = 0; i < dim; i++) piksli[i] = calloc(1, dim*sizeof(*piksli[i])); for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { int counter; #define COUNTER (counter) COUNTER = 0; #define PRETVORI(n) (((n)-((dimf)/2))/((dimf)/3.8)) long double complex z = PRETVORI(i+offset1)*scale + PRETVORI(j+offset2)*scale * I; while (creall(z) < 2 && cimagl(z) < 2 && creall(z) > -2 && cimagl(z) > -2 && ++COUNTER < 255) z = P(z); piksli[i][j].r = COUNTER; } fprintf(stderr, "\rGeneriranje vrstice %d od %d.", i, dim); } shraniBMP(piksli, dim, dim, stdout); /* OH NO, ne gledamo return valuea (rodilnik) */ fprintf(stderr, "\rGeneriranje slike končano. Izpisano na standardni izhod.\n"); for (int i = 0; i < dim; i++) free(piksli[i]); free(piksli); return 0; }