ff2png.c (1526B)
1 /* See LICENSE file for copyright and license details. */ 2 #include <arpa/inet.h> 3 4 #include <errno.h> 5 #include <stdint.h> 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 10 #include <png.h> 11 12 #include "util.h" 13 14 static void 15 png_err(png_struct *pngs, const char *msg) 16 { 17 (void)pngs; 18 die("libpng: %s", msg); 19 } 20 21 static void 22 png_setup_writer(png_struct **s, png_info **i, uint32_t w, uint32_t h) 23 { 24 *s = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, png_err, NULL); 25 *i = png_create_info_struct(*s); 26 27 if (!*s || !*i) { 28 die("Failed to initialize libpng"); 29 } 30 31 png_init_io(*s, stdout); 32 png_set_IHDR(*s, *i, w, h, 16, PNG_COLOR_TYPE_RGB_ALPHA, 33 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, 34 PNG_FILTER_TYPE_BASE); 35 png_write_info(*s, *i); 36 } 37 38 static void 39 usage(void) 40 { 41 die("usage: %s", argv0); 42 } 43 44 int 45 main(int argc, char *argv[]) 46 { 47 png_struct *pngs; 48 png_info *pngi; 49 size_t rowlen; 50 uint32_t width, height, i; 51 uint16_t *row; 52 53 /* arguments */ 54 argv0 = argv[0], argc--, argv++; 55 56 if (argc) { 57 usage(); 58 } 59 60 /* prepare */ 61 ff_read_header(&width, &height); 62 png_setup_writer(&pngs, &pngi, width, height); 63 row = ereallocarray(NULL, width, (sizeof("RGBA") - 1) * sizeof(uint16_t)); 64 rowlen = width * (sizeof("RGBA") - 1); 65 66 /* write data */ 67 for (i = 0; i < height; ++i) { 68 efread(row, sizeof(uint16_t), rowlen, stdin); 69 png_write_row(pngs, (uint8_t *)row); 70 } 71 72 /* clean up */ 73 png_write_end(pngs, NULL); 74 png_destroy_write_struct(&pngs, NULL); 75 76 return fshut(stdout, "<stdout>"); 77 }