farbfeld

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

commit 6ad3875caa041b3ea716c3b24bee14e748b5c7ff
parent d8e77e37dd74d4835977209c3cd57fba3307f6a8
Author: FRIGN <dev@frign.de>
Date:   Mon,  4 Jan 2016 19:17:03 +0100

Add stricter and clearer error-checking in png2ff and ff2png

As known from sbase, we want to manually flush stdout to see if all
data has been passed on.

Diffstat:
Mff2png.c | 60++++++++++++++++++++++++++++++++++++++----------------------
Mpng2ff.c | 23++++++++++++++++++-----
2 files changed, 56 insertions(+), 27 deletions(-)

diff --git a/ff2png.c b/ff2png.c @@ -1,6 +1,7 @@ /* See LICENSE file for copyright and license details. */ #include <arpa/inet.h> +#include <errno.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -8,17 +9,18 @@ #include <png.h> -#define HEADER_FORMAT "farbfeld########" +#define HEADER "farbfeld########" int main(int argc, char *argv[]) { png_structp png_struct_p; png_infop png_info_p; - uint8_t hdr[16]; - uint16_t tmp16, *png_row; - png_uint_32 width, height, i; png_size_t png_row_len, j; + png_uint_32 width, height, i; + int ret = 0; + uint16_t tmp16, *png_row; + uint8_t hdr[16]; if (argc > 1) { fprintf(stderr, "usage: %s\n", argv[0]); @@ -26,42 +28,47 @@ main(int argc, char *argv[]) } /* header */ - if (fread(hdr, 1, strlen(HEADER_FORMAT), stdin) != strlen(HEADER_FORMAT)) { - fprintf(stderr, "failed to read from stdin or input too short\n"); + if (fread(hdr, 1, strlen(HEADER), stdin) != strlen(HEADER)) { + fprintf(stderr, "%s: incomplete header\n", argv[0]); return 1; } if (memcmp("farbfeld", hdr, strlen("farbfeld"))) { - fprintf(stderr, "invalid magic in header\n"); + fprintf(stderr, "%s: invalid magic value\n", argv[0]); return 1; } width = ntohl(*((uint32_t *)(hdr + 8))); height = ntohl(*((uint32_t *)(hdr + 12))); /* load png */ - png_struct_p = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + 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"); + if (!png_struct_p || !png_info_p) { + fprintf(stderr, "%s: failed to initialize libpng\n", argv[0]); return 1; } + if (setjmp(png_jmpbuf(png_struct_p))) + return 1; png_init_io(png_struct_p, stdout); - png_set_IHDR(png_struct_p, png_info_p, width, height, 16, PNG_COLOR_TYPE_RGB_ALPHA, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + png_set_IHDR(png_struct_p, png_info_p, width, height, 16, + 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(uint16_t); - png_row = malloc(png_row_len); - if (!png_row) { - fprintf(stderr, "failed to allocate row-buffer\n"); + if (!(png_row = malloc(png_row_len))) { + fprintf(stderr, "%s: malloc: ", argv[0]); + perror(NULL); return 1; } - for (i = 0; i < height; ++i) { for (j = 0; j < png_row_len / sizeof(uint16_t); ++j) { - if (fread(&tmp16, 1, sizeof(uint16_t), stdin) != sizeof(uint16_t)) { - fprintf(stderr, "unexpected EOF or row-skew\n"); + if (fread(&tmp16, 1, sizeof(uint16_t), stdin) != + sizeof(uint16_t)) { + fprintf(stderr, "%s: unexpected EOF\n", + argv[0]); return 1; } png_row[j] = tmp16; @@ -70,10 +77,19 @@ main(int argc, char *argv[]) } 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; + /* flush output */ + if (fflush(stdout)) { + fprintf(stderr, "%s: fflush stdout: ", argv[0]); + perror(NULL); + ret = 1; + } + if (fclose(stdout) && !ret) { + fprintf(stderr, "%s: fclose stdout: ", argv[0]); + perror(NULL); + ret = 1; + } + + return ret; } diff --git a/png2ff.c b/png2ff.c @@ -1,6 +1,7 @@ /* See LICENSE file for copyright and license details. */ #include <arpa/inet.h> +#include <errno.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -13,7 +14,7 @@ main(int argc, char *argv[]) png_structp png_struct_p; png_infop png_info_p; png_bytepp png_row_p; - int depth, color; + int depth, color, ret = 0; uint32_t width, height, png_row_len, tmp32, r, i; uint16_t tmp16; @@ -28,7 +29,7 @@ main(int argc, char *argv[]) png_info_p = png_create_info_struct(png_struct_p); if (!png_struct_p || !png_info_p) { - fprintf(stderr, "failed to initialize libpng\n"); + fprintf(stderr, "%s: failed to initialize libpng\n", argv[0]); return 1; } if (setjmp(png_jmpbuf(png_struct_p))) @@ -48,7 +49,7 @@ main(int argc, char *argv[]) png_row_p = png_get_rows(png_struct_p, png_info_p); /* write header */ - fprintf(stdout, "farbfeld"); + fputs("farbfeld", stdout); tmp32 = htonl(width); fwrite(&tmp32, sizeof(uint32_t), 1, stdout); tmp32 = htonl(height); @@ -75,11 +76,23 @@ main(int argc, char *argv[]) } break; default: - fprintf(stderr, "format error\n"); + fprintf(stderr, "%s: format error\n", argv[0]); return 1; } png_destroy_read_struct(&png_struct_p, &png_info_p, NULL); - return 0; + /* flush output */ + if (fflush(stdout)) { + fprintf(stderr, "%s: fflush stdout: ", argv[0]); + perror(NULL); + ret = 1; + } + if (fclose(stdout) && !ret) { + fprintf(stderr, "%s: fclose stdout: ", argv[0]); + perror(NULL); + ret = 1; + } + + return ret; }