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 }