Last active
June 15, 2020 06:09
-
-
Save louisswarren/311f1f55409f7c5cf7940c662a31275b to your computer and use it in GitHub Desktop.
Farbfeld test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <arpa/inet.h> | |
#define S_WIDTH 80 | |
#define S_HEIGHT 80 | |
#define S_IDX(X, Y) ((X) + (S_WIDTH) * (Y)) | |
#define ftoff(X) htons((X) >= 1.0 ? 0xFFFF : (X) * 0x10000) | |
struct colour { | |
float r, g, b; | |
}; | |
int | |
main(void) | |
{ | |
uint32_t ff_width = htonl(S_WIDTH); | |
uint32_t ff_height = htonl(S_HEIGHT); | |
struct { | |
uint16_t r, g, b, a; | |
} ff_pixel = {.a = 0xFFFF}; | |
struct colour *image = calloc(S_WIDTH * S_HEIGHT, sizeof(*image)); | |
/* Draw something abstract */ | |
for (int i = 0; i < S_WIDTH; i++) { | |
for (int j = 0; j < 10; j++) { | |
image[S_IDX(10 + j, i)].r = 0.7; | |
image[S_IDX(i, 10 + j)].g = 0.7; | |
image[S_IDX(i, 60 + j)].b = 0.7; | |
image[S_IDX(60 + j, i)].r = 1.0; | |
image[S_IDX(60 + j, i)].g = 1.0; | |
image[S_IDX(60 + j, i)].b = 1.0; | |
} | |
} | |
/* Write image as farbfeld */ | |
fwrite("farbfeld", 8, 1, stdout); | |
fwrite(&ff_width, sizeof(ff_width), 1, stdout); | |
fwrite(&ff_height, sizeof(ff_width), 1, stdout); | |
for (int i = 0; i < S_WIDTH * S_HEIGHT; ++i) { | |
ff_pixel.r = ftoff(image[i].r); | |
ff_pixel.g = ftoff(image[i].g); | |
ff_pixel.b = ftoff(image[i].b); | |
fwrite(&ff_pixel, sizeof(ff_pixel), 1, stdout); | |
} | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CC = gcc | |
CFLAGS = -fopenmp -lm -std=c99 -pedantic -Wall | |
TARGETS = abstract.ff | |
.PHONY: default | |
default: $(TARGETS) $(TARGETS:.ff=.png) | |
%.png: %.ff | |
ff2png < $< > $@ | |
%.ff: %.c | |
$(CC) $(CFLAGS) -o $(@:.ff=) $^ | |
./$(@:.ff=) > $@ | |
%: %.c | |
.PHONY: clean | |
clean: | |
rm -f *.png *.ff $(TARGETS) $(TARGETS:.ff=.png) $(TARGETS:.ff=) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <arpa/inet.h> | |
#include <omp.h> | |
#include <complex.h> | |
#define REALMIN -0.80 | |
#define REALMAX -0.70 | |
#define IMAGMIN 0.1 | |
#define IMAGMAX 0.2 | |
#define REALMID -0.75 | |
#define IMAGMID 0.15 | |
#define S_SCALE 6000 | |
#define S_WIDTH 600 | |
#define S_HEIGHT 600 | |
#define S_IDX(X, Y) ((X) + S_WIDTH * (Y)) | |
#define MAXITER 1000 | |
#define ftoff(X) htons((X) >= 1.0 ? 0xFFFF : (X) * 0x10000) | |
#define ftoffspecr(X) ftoff(1.0 - (X)) | |
#define ftoffspecg(X) ftoff((X) * (1.0 - (X))) | |
#define ftoffspecb(X) ftoff(X) | |
struct rgba { | |
uint16_t r, g, b, a; | |
}; | |
int | |
escape_time(double complex c) | |
{ | |
double complex z = c; | |
int t = 0; | |
for (; cabs(z) < 2 && t < MAXITER; ++t) { | |
z = z * z + c; | |
} | |
if (t == MAXITER) | |
t = -1; | |
return t; | |
} | |
/* | |
void | |
log_mb(double complex c) | |
{ | |
int cv; | |
if ((cv = escape_time(c)) > 0) | |
fprintf(stderr, "%f + %fi escapes in %d iterations\n", | |
creal(c), cimag(c), cv); | |
else | |
fprintf(stderr, "%f + %fi is in the mandlebrot set\n", | |
creal(c), cimag(c)); | |
} | |
*/ | |
int | |
main(void) | |
{ | |
uint32_t ff_width = htonl(S_WIDTH); | |
uint32_t ff_height = htonl(S_HEIGHT); | |
struct rgba *ff_image = calloc(S_WIDTH * S_HEIGHT, sizeof(*ff_image)); | |
for (int i = 0; i < S_WIDTH * S_HEIGHT; ++i) | |
ff_image[i].a = 0xFFFF; | |
/* Projection values */ | |
double xscale = ((double) REALMAX - REALMIN) / S_WIDTH; | |
double yscale = ((double) IMAGMAX - IMAGMIN) / S_HEIGHT; | |
double xshift = REALMIN + xscale / 2; | |
double yshift = IMAGMIN + yscale / 2; | |
#pragma omp parallel for | |
for (int j = 0; j < S_HEIGHT; j++) { | |
struct rgba *pixel; | |
double complex c; | |
int cv; | |
for (int i = 0; i < S_WIDTH; i++) { | |
c = (xscale * i + xshift) + I * (yscale * j + yshift); | |
if ((cv = escape_time(c)) > 0) { | |
pixel = &ff_image[S_IDX(i, S_HEIGHT - j)]; | |
pixel->r = ftoffspecr((double) MAXITER / cv); | |
pixel->g = ftoffspecg((double) MAXITER / cv); | |
pixel->b = ftoffspecb((double) MAXITER / cv); | |
} | |
} | |
} | |
/* Write image as farbfeld */ | |
fwrite("farbfeld", 8, 1, stdout); | |
fwrite(&ff_width, sizeof(ff_width), 1, stdout); | |
fwrite(&ff_height, sizeof(ff_width), 1, stdout); | |
fwrite(ff_image, sizeof(struct rgba), S_WIDTH * S_HEIGHT, stdout); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment