commit ff5bbfae5214d8291c8eb93670233909ded5b722
parent 98dbe21bcb83fead026c295329ad2a55d8eff1b5
Author: FRIGN <dev@frign.de>
Date:   Wed,  6 Jan 2016 12:30:17 +0100
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:
| M | jpg2ff.c |  |  | 74 | ++++++++++++++++++++++++++++++++++++-------------------------------------- | 
1 file changed, 36 insertions(+), 38 deletions(-)
diff --git 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);