sandpiles

sandpile art
git clone git://git.rr3.xyz/sandpiles
Log | Files | Refs | README | LICENSE

sp2ff.c (2422B)


      1 #include <rcx/all.h>
      2 #include <stdio.h>
      3 #include <string.h>
      4 
      5 #include "common.h"
      6 
      7 #define USAGE \
      8 	"usage: %s [COLOR0 COLOR1 COLOR2 COLOR3 [COLOR4 COLOR5 COLOR6 COLOR7]]\n" \
      9 	"where COLORi is a 24 or 48 (32 or 64) bit RGB (RGBA) hex value\n"
     10 
     11 Rgba
     12 parse_rgba(char *s) {
     13 	switch (strlen(s)) {
     14 	case 6: // 8-bit RGB
     15 		return (Rgba){
     16 			parse_rgba_channel(s + 0, false),
     17 			parse_rgba_channel(s + 2, false),
     18 			parse_rgba_channel(s + 4, false),
     19 			0xffff,
     20 		};
     21 	case 8: // 8-bit RGBA
     22 		return (Rgba){
     23 			parse_rgba_channel(s + 0, false),
     24 			parse_rgba_channel(s + 2, false),
     25 			parse_rgba_channel(s + 4, false),
     26 			parse_rgba_channel(s + 6, false),
     27 		};
     28 	case 12: // 16-bit RGB
     29 		return (Rgba){
     30 			parse_rgba_channel(s + 0, true),
     31 			parse_rgba_channel(s + 2, true),
     32 			parse_rgba_channel(s + 4, true),
     33 			0xffff,
     34 		};
     35 	case 16: // 16-bit RGBA
     36 		return (Rgba){
     37 			parse_rgba_channel(s + 0, true),
     38 			parse_rgba_channel(s + 2, true),
     39 			parse_rgba_channel(s + 4, true),
     40 			parse_rgba_channel(s + 6, true),
     41 		};
     42 	default:
     43 		r_fatalf("expected 6, 8, 12, or 16 hexadecimal numerals");
     44 	}
     45 	unreachable;
     46 }
     47 
     48 Image
     49 draw(Sandpile sp, Rgba (*palette)[8]) {
     50 	usize w = sp.w;
     51 	usize h = sp.h;
     52 
     53 	Rgba *pixels = r_ealloc(w * h * sizeof *pixels);
     54 	for (usize y = 0; y < h; y++) {
     55 		for (usize x = 0; x < w; x++) {
     56 			u32 s = sp.sand[(y + 1) * (w + 2) + (x + 1)];
     57 			pixels[y * w + x] = (*palette)[MIN(s, 7)];
     58 		}
     59 	}
     60 
     61 	return (Image){.w = w, .h = h, .pixels = pixels};
     62 }
     63 
     64 int
     65 main(int argc, char **argv) {
     66 	CHECK_FOR_HELP_OPTION(USAGE, argc, argv);
     67 
     68 	Rgba palette[8];
     69 	if (argc == 1) { // Default palette
     70 	#define RGB(r, g, b) (Rgba){ 0x##r##r, 0x##g##g, 0x##b##b, 0xffff }
     71 		palette[0] = RGB(D4, F1, F4);
     72 		palette[1] = RGB(75, E6, DA);
     73 		palette[2] = RGB(18, 9A, B4);
     74 		palette[3] = RGB(05, 44, 5E);
     75 		// TODO: The rest of these are scuffed
     76 		palette[4] = RGB(38, A2, 18);
     77 		palette[5] = RGB(1D, 73, BE);
     78 		palette[6] = RGB(40, 6A, 33);
     79 		palette[7] = RGB(79, 69, 4F);
     80 	#undef RGB
     81 	} else if (argc == 5) { // Custom 4 color palette
     82 		for (usize i = 0; i < 4; i++)
     83 			palette[i] = parse_rgba(argv[i+1]);
     84 		for (usize i = 4; i < 8; i++)
     85 			palette[i] = palette[3];
     86 	} else if (argc == 9) { // Custom 8 color palette
     87 		for (usize i = 0; i < 8; i++)
     88 			palette[i] = parse_rgba(argv[i+1]);
     89 	} else {
     90 		fprintf(stderr, USAGE, argv[0]);
     91 		return 1;
     92 	}
     93 
     94 	Sandpile sp = sp_fread(stdin);
     95 	Image img = draw(sp, &palette);
     96 	ff_fwrite(stdout, img);
     97 }