ff2ppm.c (1526B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <arpa/inet.h> 3 4 #include <errno.h> 5 #include <inttypes.h> 6 #include <stdint.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 11 #include "arg.h" 12 #include "util.h" 13 14 static void 15 usage(void) 16 { 17 die("usage: %s [-b colour]", argv0); 18 } 19 20 int 21 main(int argc, char *argv[]) 22 { 23 size_t rowlen, rowoutlen; 24 uint64_t a; 25 uint32_t width, height, i, j, k, l; 26 uint16_t *row, mask[3] = { 0xffff, 0xffff, 0xffff }; 27 uint8_t *rowout; 28 29 /* arguments */ 30 ARGBEGIN { 31 case 'b': 32 if (parse_mask(EARGF(usage()), mask)) { 33 usage(); 34 } 35 break; 36 default: 37 usage(); 38 } ARGEND 39 40 if (argc) { 41 usage(); 42 } 43 44 /* prepare */ 45 ff_read_header(&width, &height); 46 row = ereallocarray(NULL, width, (sizeof("RGBA") - 1) * sizeof(uint16_t)); 47 rowout = ereallocarray(NULL, width, (sizeof("RGB") - 1) * sizeof(uint8_t)); 48 rowlen = width * (sizeof("RGBA") - 1); 49 rowoutlen = width * (sizeof("RGB") - 1); 50 51 /* write data */ 52 printf("P6\n%" PRIu32 " %" PRIu32 "\n255\n", width, height); 53 54 for (i = 0; i < height; ++i) { 55 efread(row, sizeof(uint16_t), rowlen, stdin); 56 57 for (j = 0, k = 0; j < rowlen; j += 4, k += 3) { 58 a = ntohs(row[j + 3]); 59 for (l = 0; l < 3; l++) { 60 /* alpha blending and 8-bit-reduction */ 61 rowout[k + l] = (a * ntohs(row[j + l]) + 62 (UINT16_MAX - a) * mask[l]) / 63 (UINT16_MAX * 64 (UINT16_MAX / UINT8_MAX)); 65 } 66 } 67 68 efwrite(rowout, sizeof(uint8_t), rowoutlen, stdout); 69 } 70 71 return fshut(stdout, "<stdout>"); 72 }