farbfeld

suckless image format with conversion tools
git clone git://git.suckless.org/farbfeld
Log | Files | Refs | README | LICENSE

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 }