ivtv-from-ff.c - vtv-tools - virtual terminal video tools Err bitreich.org 70 hgit clone git://bitreich.org/vtv-tools git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/vtv-tools URL:git://bitreich.org/vtv-tools git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/vtv-tools bitreich.org 70 1Log /scm/vtv-tools/log.gph bitreich.org 70 1Files /scm/vtv-tools/files.gph bitreich.org 70 1Refs /scm/vtv-tools/refs.gph bitreich.org 70 1Tags /scm/vtv-tools/tag bitreich.org 70 1README /scm/vtv-tools/file/README.md.gph bitreich.org 70 1LICENSE /scm/vtv-tools/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 ivtv-from-ff.c (5417B) Err bitreich.org 70 i--- Err bitreich.org 70 i 1 // Convert farbfeld image to vtv file. Err bitreich.org 70 i 2 // Err bitreich.org 70 i 3 // Can be run either in pipe mode or with file arguments. A file Err bitreich.org 70 i 4 // 'img.ff' is turned into a file 'img.vtv'. Err bitreich.org 70 i 5 // Err bitreich.org 70 i 6 // If you want to produce a vtv file that can be shown with Err bitreich.org 70 i 7 // vtv-player, the image should be 25 lines by 73 columns. Err bitreich.org 70 i 8 // Err bitreich.org 70 i 9 // Copyright 2023 Troels Henriksen Err bitreich.org 70 i 10 // Err bitreich.org 70 i 11 // See LICENSE file for licensing information. Err bitreich.org 70 i 12 Err bitreich.org 70 i 13 #include Err bitreich.org 70 i 14 #include Err bitreich.org 70 i 15 #include Err bitreich.org 70 i 16 #include Err bitreich.org 70 i 17 #include Err bitreich.org 70 i 18 Err bitreich.org 70 i 19 void def(FILE *f) { Err bitreich.org 70 i 20 fprintf(f, "\033[0m"); Err bitreich.org 70 i 21 } Err bitreich.org 70 i 22 Err bitreich.org 70 i 23 void fg_rgb(FILE *f, uint8_t r, uint8_t g, uint8_t b) { Err bitreich.org 70 i 24 fprintf(f, "\033[38;2;%d;%d;%dm", r, g, b); Err bitreich.org 70 i 25 } Err bitreich.org 70 i 26 Err bitreich.org 70 i 27 void bg_rgb(FILE *f, uint8_t r, uint8_t g, uint8_t b) { Err bitreich.org 70 i 28 fprintf(f, "\033[48;2;%d;%d;%dm", r, g, b); Err bitreich.org 70 i 29 } Err bitreich.org 70 i 30 Err bitreich.org 70 i 31 int read_be_uint16(FILE *f, uint16_t *x) { Err bitreich.org 70 i 32 uint8_t word[2]; Err bitreich.org 70 i 33 Err bitreich.org 70 i 34 if (fread(&word, 1, 2, f) != 2) { Err bitreich.org 70 i 35 return 1; Err bitreich.org 70 i 36 } Err bitreich.org 70 i 37 *x = (word[1] << 8) + word[0]; Err bitreich.org 70 i 38 Err bitreich.org 70 i 39 return 0; Err bitreich.org 70 i 40 } Err bitreich.org 70 i 41 Err bitreich.org 70 i 42 int read_be_uint32(FILE *f, uint32_t *x) { Err bitreich.org 70 i 43 uint8_t word[4]; Err bitreich.org 70 i 44 Err bitreich.org 70 i 45 if (fread(&word, 1, 4, f) != 4) { Err bitreich.org 70 i 46 return 1; Err bitreich.org 70 i 47 } Err bitreich.org 70 i 48 *x = (word[0] << 24) + (word[1] << 16) + (word[2] << 8) + word[3]; Err bitreich.org 70 i 49 Err bitreich.org 70 i 50 return 0; Err bitreich.org 70 i 51 } Err bitreich.org 70 i 52 Err bitreich.org 70 i 53 int load_ff(FILE *f, Err bitreich.org 70 i 54 uint16_t* *argbs_out, Err bitreich.org 70 i 55 uint32_t *width_out, Err bitreich.org 70 i 56 uint32_t *height_out) { Err bitreich.org 70 i 57 char magic[8]; Err bitreich.org 70 i 58 uint16_t* argbs = NULL; Err bitreich.org 70 i 59 uint32_t width = 0, height = 0; Err bitreich.org 70 i 60 Err bitreich.org 70 i 61 if (fread(magic, 1, 8, f) != 8) { Err bitreich.org 70 i 62 goto bad; Err bitreich.org 70 i 63 } Err bitreich.org 70 i 64 Err bitreich.org 70 i 65 if (memcmp(magic, "farbfeld", 8) != 0) { Err bitreich.org 70 i 66 goto bad; Err bitreich.org 70 i 67 } Err bitreich.org 70 i 68 Err bitreich.org 70 i 69 if (read_be_uint32(f, &width) != 0) { Err bitreich.org 70 i 70 goto bad; Err bitreich.org 70 i 71 } Err bitreich.org 70 i 72 Err bitreich.org 70 i 73 if (read_be_uint32(f, &height) != 0) { Err bitreich.org 70 i 74 goto bad; Err bitreich.org 70 i 75 } Err bitreich.org 70 i 76 Err bitreich.org 70 i 77 argbs = calloc(width*height*4, sizeof(uint16_t)); Err bitreich.org 70 i 78 Err bitreich.org 70 i 79 for (unsigned int i = 0; i < width; i++) { Err bitreich.org 70 i 80 for (unsigned int j = 0; j < height; j++) { Err bitreich.org 70 i 81 for (unsigned int l = 0; l < 4; l++) { Err bitreich.org 70 i 82 if (read_be_uint16(f, &argbs[i*(height*4)+(j*4)+l]) != 0) { Err bitreich.org 70 i 83 goto bad; Err bitreich.org 70 i 84 } Err bitreich.org 70 i 85 } Err bitreich.org 70 i 86 } Err bitreich.org 70 i 87 } Err bitreich.org 70 i 88 Err bitreich.org 70 i 89 *argbs_out = argbs; Err bitreich.org 70 i 90 *width_out = width; Err bitreich.org 70 i 91 *height_out = height; Err bitreich.org 70 i 92 return 0; Err bitreich.org 70 i 93 Err bitreich.org 70 i 94 bad: Err bitreich.org 70 i 95 free(argbs); Err bitreich.org 70 i 96 return 1; Err bitreich.org 70 i 97 } Err bitreich.org 70 i 98 Err bitreich.org 70 i 99 void render(int nrows, int ncols, const uint16_t *argbs, Err bitreich.org 70 i 100 uint32_t *fgs, uint32_t *bgs, char *chars) { Err bitreich.org 70 i 101 for (int i = 0; i < nrows; i++) { Err bitreich.org 70 i 102 for (int j = 0; j < ncols; j++) { Err bitreich.org 70 i 103 uint32_t r0 = argbs[(i*2)*(ncols*4)+j*4+0]>>8; Err bitreich.org 70 i 104 uint32_t g0 = argbs[(i*2)*(ncols*4)+j*4+1]>>8; Err bitreich.org 70 i 105 uint32_t b0 = argbs[(i*2)*(ncols*4)+j*4+2]>>8; Err bitreich.org 70 i 106 uint32_t r1 = argbs[(i*2+1)*(ncols*4)+j*4+0]>>8; Err bitreich.org 70 i 107 uint32_t g1 = argbs[(i*2+1)*(ncols*4)+j*4+1]>>8; Err bitreich.org 70 i 108 uint32_t b1 = argbs[(i*2+1)*(ncols*4)+j*4+2]>>8; Err bitreich.org 70 i 109 Err bitreich.org 70 i 110 uint32_t w0 = r0 << 16 | g0 << 8 | b0; Err bitreich.org 70 i 111 uint32_t w1 = r1 << 16 | g1 << 8 | b1; Err bitreich.org 70 i 112 fgs[i*ncols+j] = w0; Err bitreich.org 70 i 113 bgs[i*ncols+j] = w1; Err bitreich.org 70 i 114 chars[i*ncols+j] = 127; // Sentinel. Err bitreich.org 70 i 115 } Err bitreich.org 70 i 116 } Err bitreich.org 70 i 117 } Err bitreich.org 70 i 118 Err bitreich.org 70 i 119 void display(FILE *f, int nrows, int ncols, Err bitreich.org 70 i 120 const uint32_t *fgs, const uint32_t *bgs, const char *chars) { Err bitreich.org 70 i 121 for (int i = 0; i < nrows; i++) { Err bitreich.org 70 i 122 uint32_t prev_w0 = 0xdeadbeef; Err bitreich.org 70 i 123 uint32_t prev_w1 = 0xdeadbeef; Err bitreich.org 70 i 124 for (int j = 0; j < ncols; j++) { Err bitreich.org 70 i 125 double r0 = 0, g0 = 0, b0 = 0; Err bitreich.org 70 i 126 double r1 = 0, g1 = 0, b1 = 0; Err bitreich.org 70 i 127 uint32_t w0 = fgs[i*ncols+j]; Err bitreich.org 70 i 128 uint32_t w1 = bgs[i*ncols+j]; Err bitreich.org 70 i 129 if (w0 != prev_w0 || w1 != prev_w1) { Err bitreich.org 70 i 130 r0 = (w0>>16)&0xFF; Err bitreich.org 70 i 131 g0 = (w0>>8)&0xFF; Err bitreich.org 70 i 132 b0 = (w0>>0)&0xFF; Err bitreich.org 70 i 133 r1 = (w1>>16)&0xFF; Err bitreich.org 70 i 134 g1 = (w1>>8)&0xFF; Err bitreich.org 70 i 135 b1 = (w1>>0)&0xFF; Err bitreich.org 70 i 136 fg_rgb(f, r0, g0, b0); Err bitreich.org 70 i 137 bg_rgb(f, r1, g1, b1); Err bitreich.org 70 i 138 prev_w0 = w0; Err bitreich.org 70 i 139 prev_w1 = w1; Err bitreich.org 70 i 140 } Err bitreich.org 70 i 141 char c = chars[i*ncols+j]; Err bitreich.org 70 i 142 if (c == 127) { Err bitreich.org 70 i 143 fputs("▀", f); Err bitreich.org 70 i 144 } else { Err bitreich.org 70 i 145 fputc(c, f); Err bitreich.org 70 i 146 } Err bitreich.org 70 i 147 } Err bitreich.org 70 i 148 def(f); Err bitreich.org 70 i 149 fputc('\n', f); Err bitreich.org 70 i 150 } Err bitreich.org 70 i 151 } Err bitreich.org 70 i 152 Err bitreich.org 70 i 153 int convert(FILE *ff, FILE *vtv) { Err bitreich.org 70 i 154 uint32_t width, height; Err bitreich.org 70 i 155 uint16_t *argbs; Err bitreich.org 70 i 156 if (load_ff(ff, &argbs, &width, &height) != 0) { Err bitreich.org 70 i 157 return 1; Err bitreich.org 70 i 158 } Err bitreich.org 70 i 159 uint32_t *fgs = calloc(width*height, sizeof(uint32_t)); Err bitreich.org 70 i 160 uint32_t *bgs = calloc(width*height, sizeof(uint32_t)); Err bitreich.org 70 i 161 char *chars = calloc(width*height, sizeof(char)); Err bitreich.org 70 i 162 render(height, width, argbs, fgs, bgs, chars); Err bitreich.org 70 i 163 display(vtv, height/2, width, fgs, bgs, chars); Err bitreich.org 70 i 164 free(argbs); Err bitreich.org 70 i 165 free(fgs); Err bitreich.org 70 i 166 free(bgs); Err bitreich.org 70 i 167 free(chars); Err bitreich.org 70 i 168 return 0; Err bitreich.org 70 i 169 } Err bitreich.org 70 i 170 Err bitreich.org 70 i 171 int main (int argc, char** argv) { Err bitreich.org 70 i 172 if (argc == 1) { Err bitreich.org 70 i 173 if (convert(stdin, stdout) != 0) { Err bitreich.org 70 i 174 fprintf(stderr, "%s: invalid farbfeld image on stdin.\n", argv[0]); Err bitreich.org 70 i 175 exit(1); Err bitreich.org 70 i 176 } Err bitreich.org 70 i 177 } else { Err bitreich.org 70 i 178 for (int i = 1; i < argc; i++) { Err bitreich.org 70 i 179 const char *ff_fname = argv[i]; Err bitreich.org 70 i 180 size_t len = strlen(ff_fname); Err bitreich.org 70 i 181 if (len >= 3 && strcmp(&ff_fname[len-3], ".ff") == 0) { Err bitreich.org 70 i 182 char *vtv_fname = malloc(len+2); Err bitreich.org 70 i 183 strncpy(vtv_fname, ff_fname, len-3); Err bitreich.org 70 i 184 strcpy(vtv_fname+len-3, ".vtv"); Err bitreich.org 70 i 185 printf("%s\n%s\n", ff_fname, vtv_fname); Err bitreich.org 70 i 186 FILE *ff = fopen(ff_fname, "r"); Err bitreich.org 70 i 187 if (ff == NULL) { Err bitreich.org 70 i 188 fprintf(stderr, "%s: could not open %s: %s\n", Err bitreich.org 70 i 189 argv[0], ff_fname, strerror(errno)); Err bitreich.org 70 i 190 } Err bitreich.org 70 i 191 FILE *vtv = fopen(vtv_fname, "w+"); Err bitreich.org 70 i 192 if (vtv == NULL) { Err bitreich.org 70 i 193 fprintf(stderr, "%s: could not open %s: %s\n", Err bitreich.org 70 i 194 argv[0], vtv_fname, strerror(errno)); Err bitreich.org 70 i 195 } Err bitreich.org 70 i 196 if (convert(ff, vtv) != 0) { Err bitreich.org 70 i 197 fprintf(stderr, "%s: invalid farbfeld image in %s.\n", Err bitreich.org 70 i 198 argv[0], ff_fname); Err bitreich.org 70 i 199 exit(1); Err bitreich.org 70 i 200 } Err bitreich.org 70 i 201 fclose(ff); Err bitreich.org 70 i 202 fclose(vtv); Err bitreich.org 70 i 203 free(vtv_fname); Err bitreich.org 70 i 204 } else { Err bitreich.org 70 i 205 fprintf(stderr, Err bitreich.org 70 i 206 "%s: argument %s does not have .ff extension.\n", Err bitreich.org 70 i 207 argv[0], ff_fname); Err bitreich.org 70 i 208 exit(1); Err bitreich.org 70 i 209 } Err bitreich.org 70 i 210 } Err bitreich.org 70 i 211 } Err bitreich.org 70 i 212 } Err bitreich.org 70 .