diff options
author | FRIGN <dev@frign.de> | 2015-11-09 23:39:29 +0100 |
---|---|---|
committer | FRIGN <dev@frign.de> | 2015-11-09 23:40:46 +0100 |
commit | d5f6f70d351239ee37b3d864c9a94dc49d66c052 (patch) | |
tree | 47993f137fd273df86a4f24fe7fe22098c435e0a /ff2png.c | |
parent | 0b0fcaa7136d7de2e1bc5dc05a576f5fe5608995 (diff) |
imagefile -> farbfeld
- Rename the format
- Change the format specification
- Drop old tools waiting to be fixed on a later date, just keep
fixed png for now
- Simplify other stuff
This is a direct consequence of my slcon2-talk on this topic.
At first I planned to have 64 bits per channel, but this is
overkill.
Diffstat (limited to 'ff2png.c')
-rw-r--r-- | ff2png.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/ff2png.c b/ff2png.c new file mode 100644 index 0000000..4cbbf22 --- /dev/null +++ b/ff2png.c @@ -0,0 +1,90 @@ +/* See LICENSE file for copyright and license details. */ +#include <endian.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <png.h> + +#include "arg.h" + +char *argv0; + +#define HEADER_FORMAT "farbfeld########" + +static void +usage(void) +{ + fprintf(stderr, "usage: %s\n", argv0); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + png_structp png_struct_p; + png_infop png_info_p; + uint8_t hdr[17], *png_row; + uint16_t tmp16; + png_uint_32 width, height, i; + png_size_t png_row_len, j; + + ARGBEGIN { + default: + usage(); + } ARGEND; + + if (argc) + usage(); + + /* header */ + if (fread(hdr, 1, strlen(HEADER_FORMAT), stdin) != strlen(HEADER_FORMAT)) { + fprintf(stderr, "failed to read from stdin or input too short\n"); + return 1; + } + if (memcmp("farbfeld", hdr, strlen("farbfeld"))) { + fprintf(stderr, "invalid magic in header\n"); + return 1; + } + width = be32toh((hdr[9] << 0) | (hdr[10] << 8) | (hdr[11] << 16) | (hdr[12] << 24)); + height = be32toh((hdr[13] << 0) | (hdr[14] << 8) | (hdr[15] << 16) | (hdr[16] << 24)); + + /* load png */ + png_struct_p = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + png_info_p = png_create_info_struct(png_struct_p); + + if (!png_struct_p || !png_info_p || setjmp(png_jmpbuf(png_struct_p))) { + fprintf(stderr, "failed to initialize libpng\n"); + return 1; + } + png_init_io(png_struct_p, stdout); + png_set_IHDR(png_struct_p, png_info_p, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + png_write_info(png_struct_p, png_info_p); + + /* write rows */ + png_row_len = strlen("RGBA") * width * sizeof(uint8_t); + png_row = malloc(png_row_len); + if (!png_row) { + fprintf(stderr, "failed to allocate row-buffer\n"); + return 1; + } + + for (i = 0; i < height; ++i) { + for (j = 0; j < png_row_len; ++j) { + if (fread(&tmp16, 1, sizeof(uint16_t), stdin) != sizeof(uint16_t)) { + fprintf(stderr, "unexpected EOF or row-skew\n"); + return 1; + } + png_row[j] = be16toh(tmp16) / (1 << 8); + } + png_write_row(png_struct_p, png_row); + } + png_write_end(png_struct_p, NULL); + + /* clean up */ + png_free_data(png_struct_p, png_info_p, PNG_FREE_ALL, -1); + png_destroy_write_struct(&png_struct_p, NULL); + free(png_row); + return 0; +} |