common.c (3226B)
1 #include <rcx/all.h> 2 #include <stdio.h> 3 #include <string.h> 4 5 #include "common.h" 6 7 static u8 8 hex_value[] = { 9 ['0'] = 0x0, ['1'] = 0x1, ['2'] = 0x2, ['3'] = 0x3, ['4'] = 0x4, 10 ['5'] = 0x5, ['6'] = 0x6, ['7'] = 0x7, ['8'] = 0x8, ['9'] = 0x9, 11 ['A'] = 0xA, ['B'] = 0xB, ['C'] = 0xC, ['D'] = 0xD, ['E'] = 0xE, ['F'] = 0xF, 12 ['a'] = 0xA, ['b'] = 0xB, ['c'] = 0xC, ['d'] = 0xD, ['e'] = 0xE, ['f'] = 0xF, 13 }; 14 15 static bool 16 is_hex_numeral(char c) { 17 return ('0' <= c && c <= '9') 18 || ('A' <= c && c <= 'F') 19 || ('a' <= c && c <= 'f'); 20 } 21 22 u16 23 parse_rgba_channel(char *s, bool sixteen) { 24 u16 v = 0; 25 for (usize i = 0; i < (sixteen ? 4 : 2); i++) { 26 if (!is_hex_numeral(s[i])) 27 r_fatalf("expected hexadecimal numeral"); 28 v = 16u * v + hex_value[(usize)s[i]]; 29 } 30 return sixteen ? v : (v << 8) | v; 31 } 32 33 void 34 ff_fwrite(FILE *f, Image img) { 35 usize w = img.w; 36 usize h = img.h; 37 38 char header[16]; 39 memcpy(header, "farbfeld", 8); 40 r_writeb32(header + 8, w); 41 r_writeb32(header + 12, h); 42 if (!fwrite(header, sizeof header, 1, f)) 43 r_fatalf("ff_fwrite: failed to write header"); 44 45 for (usize y = 0; y < h; y++) { 46 for (usize x = 0; x < w; x++) { 47 Rgba p = img.pixels[y * w + x]; 48 u16 buf[4] = { 49 r_htob16(p.r), 50 r_htob16(p.g), 51 r_htob16(p.b), 52 r_htob16(p.a), 53 }; 54 if (!fwrite(buf, sizeof buf, 1, f)) 55 r_fatalf("ff_fwrite: failed to write pixel data"); 56 } 57 } 58 } 59 60 Image 61 ff_fread(FILE *f) { 62 char header[16]; 63 if (!fread(header, sizeof header, 1, f)) 64 r_fatalf("ff_fread: failed to read header"); 65 if (memcmp(header, "farbfeld", 8) != 0) 66 r_fatalf("ff_fread: invalid magic"); 67 usize w = r_readb32(header + 8); 68 usize h = r_readb32(header + 12); 69 70 Rgba *pixels = r_ealloc(w * h * sizeof *pixels); 71 for (usize y = 0; y < h; y++) { 72 for (usize x = 0; x < w; x++) { 73 char buf[8]; 74 if (!fread(buf, sizeof buf, 1, f)) 75 r_fatalf("ff_fread: failed to read pixel data"); 76 pixels[y * w + x] = (Rgba){ 77 .r = r_readb16(buf + 0), 78 .g = r_readb16(buf + 2), 79 .b = r_readb16(buf + 4), 80 .a = r_readb16(buf + 6), 81 }; 82 } 83 } 84 85 return (Image){.w = w, .h = h, .pixels = pixels}; 86 } 87 88 void 89 sp_fwrite(FILE *f, Sandpile sp) { 90 usize w = sp.w; 91 usize h = sp.h; 92 93 char header[16]; 94 memcpy(header, "sandpile", 8); 95 r_writeb32(header + 8, w); 96 r_writeb32(header + 12, h); 97 if (!fwrite(header, sizeof header, 1, f)) 98 r_fatalf("sp_fwrite: failed to write header"); 99 100 for (usize y = 1; y <= h; y++) { 101 for (usize x = 1; x <= w; x++) { 102 char buf[4]; 103 r_writeb32(buf, sp.sand[y * (w + 2) + x]); 104 if (!fwrite(buf, sizeof buf, 1, f)) 105 r_fatalf("sp_fwrite: failed to write sand data"); 106 } 107 } 108 } 109 110 Sandpile 111 sp_fread(FILE *f) { 112 char header[16]; 113 if (!fread(header, sizeof header, 1, f)) 114 r_fatalf("sp_fread: failed to read header"); 115 if (memcmp(header, "sandpile", 8) != 0) 116 r_fatalf("sp_fread: invalid magic"); 117 usize w = r_readb32(header + 8); 118 usize h = r_readb32(header + 12); 119 120 u32 *sand = r_eallocz((w + 2) * (h + 2) * sizeof(u32)); 121 for (usize y = 1; y <= h; y++) { 122 for (usize x = 1; x <= w; x++) { 123 char buf[4]; 124 if (!fread(buf, sizeof buf, 1, f)) 125 r_fatalf("sp_fread: failed to read sand data"); 126 sand[y * (w + 2) + x] = r_readb32(buf); 127 } 128 } 129 130 return (Sandpile){.w = w, .h = h, .sand = sand}; 131 }