diff options
author | FRIGN <dev@frign.de> | 2016-01-06 15:15:06 +0100 |
---|---|---|
committer | FRIGN <dev@frign.de> | 2016-01-06 15:15:06 +0100 |
commit | 295094bbbfecd64b4e6841e5e8093cc1748a2917 (patch) | |
tree | 6313997dee1478c3097877b65dcefa392c96c5e5 /png2ff.c | |
parent | d17e95f980060bd61439f8658bd0719c26595a2b (diff) |
Improve error-handling in the tools
We don't need the jumps, but rather pass a nice function pointer to
libpng. The jump in libjpg was also useless.
We check each fwrite-call so there's an early bailout in case the output
file is full.
Flushing at the end worked as well, but it took too long for complex
images. We don't want to "block" a pipe here and the approach in jpg2ff
was better.
The iHDR-read was useless. Rather use the get*-functions in libpng,
saves us 2 local variables as well.
Diffstat (limited to 'png2ff.c')
-rw-r--r-- | png2ff.c | 66 |
1 files changed, 36 insertions, 30 deletions
@@ -2,39 +2,46 @@ #include <arpa/inet.h> #include <errno.h> -#include <setjmp.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <png.h> +static char *argv0; + +void +pngerr(png_structp png_struct_p, png_const_charp msg) +{ + fprintf(stderr, "%s: libpng: %s\n", argv0, msg); + exit(1); +} + int main(int argc, char *argv[]) { png_structp png_struct_p; png_infop png_info_p; png_bytepp png_row_p; - int depth, color, ret = 0; uint32_t width, height, png_row_len, tmp32, r, i; uint16_t tmp16; - if (argc > 1) { - fprintf(stderr, "usage: %s\n", argv[0]); + argv0 = argv[0], argc--, argv++; + + if (argc) { + fprintf(stderr, "usage: %s\n", argv0); return 1; } /* load png */ png_struct_p = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, - NULL, NULL); + pngerr, NULL); png_info_p = png_create_info_struct(png_struct_p); if (!png_struct_p || !png_info_p) { - fprintf(stderr, "%s: failed to initialize libpng\n", argv[0]); + fprintf(stderr, "%s: failed to initialize libpng\n", argv0); return 1; } - if (setjmp(png_jmpbuf(png_struct_p))) - return 1; png_init_io(png_struct_p, stdin); if (png_get_valid(png_struct_p, png_info_p, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_struct_p); @@ -44,56 +51,55 @@ main(int argc, char *argv[]) png_set_packing(png_struct_p); png_read_png(png_struct_p, png_info_p, PNG_TRANSFORM_PACKING | PNG_TRANSFORM_EXPAND, NULL); - png_get_IHDR(png_struct_p, png_info_p, &width, &height, &depth, - &color, NULL, NULL, NULL); + width = png_get_image_width(png_struct_p, png_info_p); + height = png_get_image_height(png_struct_p, png_info_p); png_row_len = png_get_rowbytes(png_struct_p, png_info_p); png_row_p = png_get_rows(png_struct_p, png_info_p); /* write header */ fputs("farbfeld", stdout); tmp32 = htonl(width); - fwrite(&tmp32, sizeof(uint32_t), 1, stdout); + if (fwrite(&tmp32, sizeof(uint32_t), 1, stdout) != 1) + goto writerr; tmp32 = htonl(height); - fwrite(&tmp32, sizeof(uint32_t), 1, stdout); + if (fwrite(&tmp32, sizeof(uint32_t), 1, stdout) != 1) + goto writerr; /* write data */ - switch(depth) { + switch(png_get_bit_depth(png_struct_p, png_info_p)) { case 8: for (r = 0; r < height; ++r) { for (i = 0; i < png_row_len; i++) { /* ((2^16-1) / 255) == 257 */ tmp16 = htons(257 * png_row_p[r][i]); - fwrite(&tmp16, sizeof(uint16_t), 1, stdout); + if (fwrite(&tmp16, sizeof(uint16_t), 1, + stdout) != 1) + goto writerr; } } break; case 16: for (r = 0; r < height; ++r) { for (i = 0; i < png_row_len / 2; i++) { - tmp16 = *((uint16_t *) - (png_row_p[r] + 2 * i)); - fwrite(&tmp16, sizeof(uint16_t), 1, stdout); + tmp16 = *((uint16_t *)(png_row_p[r] + + 2 * i)); + if (fwrite(&tmp16, sizeof(uint16_t), 1, + stdout) != 1) + goto writerr; } } break; default: - fprintf(stderr, "%s: format error\n", argv[0]); + fprintf(stderr, "%s: invalid bit-depth\n", argv0); return 1; } png_destroy_read_struct(&png_struct_p, &png_info_p, NULL); - /* 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 0; +writerr: + fprintf(stderr, "%s: fwrite: ", argv0); + perror(NULL); - return ret; + return 1; } |