summaryrefslogtreecommitdiff
path: root/jpg2ff.c
diff options
context:
space:
mode:
authorFRIGN <dev@frign.de>2016-01-06 12:30:17 +0100
committerFRIGN <dev@frign.de>2016-01-06 12:32:48 +0100
commitff5bbfae5214d8291c8eb93670233909ded5b722 (patch)
tree8cc657ec7a07de3e86519afa1beb9aaf4da34e62 /jpg2ff.c
parent98dbe21bcb83fead026c295329ad2a55d8eff1b5 (diff)
Refactor jpg2ff
Remove some kitchen sink comments (the jpg boilerplate is already horrible enough) and flush the output buffer manually to detect write errors. Also improve error reporting.
Diffstat (limited to 'jpg2ff.c')
-rw-r--r--jpg2ff.c74
1 files changed, 36 insertions, 38 deletions
diff --git a/jpg2ff.c b/jpg2ff.c
index 52b4928..acf66b3 100644
--- a/jpg2ff.c
+++ b/jpg2ff.c
@@ -1,34 +1,22 @@
/* See LICENSE file for copyright and license details. */
#include <arpa/inet.h>
+
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-
#include <setjmp.h>
-#include <jpeglib.h>
-char *argv0;
-
-static jmp_buf setjmp_buffer;
+#include <jpeglib.h>
-static void
-usage(void)
-{
- fprintf(stderr, "usage: %s\n", argv0);
- exit(1);
-}
+static jmp_buf error_jump;
METHODDEF(void)
-if_jpeg_error(j_common_ptr cinfo)
+jpeg_error(j_common_ptr cinfo)
{
- /* Always display the message. */
- /* We could postpone this until after returning, if we chose. */
- (*cinfo->err->output_message) (cinfo);
-
- /* Return control to the setjmp point */
- longjmp(setjmp_buffer, 1);
+ (*cinfo->err->output_message)(cinfo);
+ longjmp(error_jump, 1);
}
int
@@ -42,18 +30,16 @@ main(int argc, char *argv[])
int ret = 1;
JSAMPARRAY buffer; /* output row buffer */
- argv0 = argv[0];
- if (argc > 1)
- usage();
+ if (argc > 1) {
+ fprintf(stderr, "usage: %s\n", argv[0]);
+ return 1;
+ }
- /* load jpeg */
+ /* load jpg */
cinfo.err = jpeg_std_error(&jerr);
- jerr.error_exit = if_jpeg_error;
- /* Establish the setjmp return context for my_error_exit to use. */
- if (setjmp(setjmp_buffer)) {
- /* If we get here, the JPEG code has signaled an error.
- * We need to clean up the JPEG object, close the input file, and return. */
+ jerr.error_exit = jpeg_error;
+ if (setjmp(error_jump)) {
goto cleanup;
}
@@ -64,23 +50,23 @@ main(int argc, char *argv[])
width = cinfo.image_width;
height = cinfo.image_height;
- /* change output for farbfeld */
- cinfo.output_components = 3; /* # of color components per pixel */
- cinfo.out_color_space = JCS_RGB; /* colorspace of input image */
+ /* set output format */
+ cinfo.output_components = 3; /* color components per pixel */
+ cinfo.out_color_space = JCS_RGB; /* input color space */
jpeg_start_decompress(&cinfo);
jpeg_row_len = width * cinfo.output_components;
- /* Make a one-row-high sample array that will go away when done with image */
- buffer = (*cinfo.mem->alloc_sarray)
- ((j_common_ptr) &cinfo, JPOOL_IMAGE, jpeg_row_len, 1);
- ff_row_len = strlen("RRGGBBAA") * width;
+ /* create output buffers */
+ buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo,
+ JPOOL_IMAGE, jpeg_row_len, 1);
+ ff_row_len = strlen("RGBA") * sizeof(uint16_t) * width;
if(!(ff_row = malloc(ff_row_len))) {
- fprintf(stderr, "Can't malloc\n");
+ fprintf(stderr, "%s: malloc: out of memory\n", argv[0]);
return 1;
}
- /* write header with big endian width and height-values */
+ /* write header */
fprintf(stdout, "farbfeld");
val_be = htonl(width);
fwrite(&val_be, sizeof(uint32_t), 1, stdout);
@@ -91,7 +77,7 @@ main(int argc, char *argv[])
/* jpeg_read_scanlines expects an array of pointers to scanlines.
* Here the array is only one element long, but you could ask for
* more than one scanline at a time if that's more convenient. */
- (void)jpeg_read_scanlines(&cinfo, buffer, 1);
+ jpeg_read_scanlines(&cinfo, buffer, 1);
for(i = 0, dx = 0, sx = 0; i < width; i++, sx += 3, dx += 4) {
ff_row[dx] = htons(buffer[0][sx] * 257);
@@ -102,13 +88,25 @@ main(int argc, char *argv[])
/* write data */
if (fwrite(ff_row, 1, ff_row_len, stdout) != ff_row_len) {
- fprintf(stderr, "fwrite() failed\n");
+ fprintf(stderr, "%s: fwrite: ");
+ perror(NULL);
goto cleanup;
}
}
jpeg_finish_decompress(&cinfo);
ret = 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;
+ }
cleanup:
free(ff_row);
jpeg_destroy_decompress(&cinfo);