summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaslo Hunhold <dev@frign.de>2017-04-12 23:36:47 +0200
committerLaslo Hunhold <dev@frign.de>2017-04-12 23:36:47 +0200
commit9a992f810d2a11751026ac352f435be1717e0979 (patch)
treee4967690d5c078c25566b3a6f51e536ee5c6f07c
parentf22282e99a963f5935ea68a583cc7d928a787ce1 (diff)
Refactor jpg-conversion-utilities
First of all, there was lots of libjpeg-specific cruft that just didn't have any right to exist (METHODDEF(), strange typedefs, use of the internal memory pool for no reason). This is gone now. Additionally, we make use of the save and proven utility functions and in general the code should be more well-separated now. What is left to do is clear up the part where we mix the colors with the mask.
-rw-r--r--ff2jpg.c112
-rw-r--r--jpg2ff.c94
2 files changed, 92 insertions, 114 deletions
diff --git a/ff2jpg.c b/ff2jpg.c
index 51f1fe6..78cb122 100644
--- a/ff2jpg.c
+++ b/ff2jpg.c
@@ -13,7 +13,7 @@
#include "arg.h"
#include "util.h"
-METHODDEF(void)
+static void
jpeg_error(j_common_ptr js)
{
fprintf(stderr, "%s: libjpeg: ", argv0);
@@ -22,6 +22,29 @@ jpeg_error(j_common_ptr js)
}
static void
+jpeg_setup_writer(struct jpeg_compress_struct *s, struct jpeg_error_mgr *e,
+ uint32_t w, uint32_t h, int quality, int opt)
+{
+ jpeg_create_compress(s);
+ e->error_exit = jpeg_error;
+ s->err = jpeg_std_error(e);
+
+ jpeg_stdio_dest(s, stdout);
+ s->image_width = w;
+ s->image_height = h;
+ s->input_components = 3; /* color components per pixel */
+ s->in_color_space = JCS_RGB; /* output color space */
+ jpeg_set_defaults(s);
+
+ if (opt) {
+ s->optimize_coding = 1;
+ }
+ jpeg_set_quality(s, quality, 1);
+
+ jpeg_start_compress(s, 1);
+}
+
+static void
usage(void)
{
fprintf(stderr, "usage: %s [-b #rrggbb] [-o] [-q quality]\n", argv0);
@@ -31,44 +54,27 @@ usage(void)
int
main(int argc, char *argv[])
{
- JSAMPROW row_pointer[1]; /* pointer to a single row */
- struct jpeg_compress_struct cinfo;
+ struct jpeg_compress_struct jcomp;
struct jpeg_error_mgr jerr;
size_t rowlen;
uint64_t a;
uint32_t width, height, i, j, k, l;
uint16_t *row, mask[3] = { 0xffff, 0xffff, 0xffff };
uint8_t *rowout;
- char *color, colfmt[] = "%#x%#x%#x";
- unsigned int collen, col[3], colfac, quality = 85, optimize = 0;
+ int optimize = 0, quality = 85;
- argv0 = argv[0];
+ /* arguments */
ARGBEGIN {
case 'b':
- color = EARGF(usage());
- if (color[0] == '#') {
- color++;
- }
- collen = strlen(color);
- if (collen != 3 && collen != 6 && collen != 12) {
+ if (parse_mask(EARGF(usage()), mask)) {
usage();
}
- colfmt[1] = colfmt[4] = colfmt[7] = ((collen / 3) + '0');
- if (sscanf(color, colfmt, col, col + 1, col + 2) != 3) {
- usage();
- }
- /* UINT16_MAX / 255 = 257; UINT16_MAX / 15 = 4369 */
- colfac = (collen == 3) ? 4369 : (collen == 6) ? 257 : 1;
- for (i = 0; i < 3; i++) {
- mask[i] = col[i] * colfac;
- }
break;
case 'o':
optimize = 1;
break;
case 'q':
- if ((quality = atoi(EARGF(usage()))) > 100)
- usage();
+ quality = estrtonum(EARGF(usage()), 0, 100);
break;
default:
usage();
@@ -78,43 +84,24 @@ main(int argc, char *argv[])
usage();
}
- read_ff_header(&width, &height);
-
- if (width > SIZE_MAX / ((sizeof("RGBA") - 1) * sizeof(uint16_t))) {
- fprintf(stderr, "%s: row length integer overflow\n", argv0);
- return 1;
- }
+ /* prepare */
+ ff_read_header(&width, &height);
+ jpeg_setup_writer(&jcomp, &jerr, width, height, quality, optimize);
+ row = ereallocarray(NULL, width, (sizeof("RGBA") - 1) * sizeof(uint16_t));
rowlen = width * (sizeof("RGBA") - 1);
- if (!(row = malloc(rowlen * sizeof(uint16_t)))) {
- fprintf(stderr, "%s: malloc: %s\n", argv0, strerror(errno));
- return 1;
- }
- if (!(rowout = malloc(width * (sizeof("RGB") - 1) * sizeof(uint8_t)))) {
- fprintf(stderr, "%s: malloc: %s\n", argv0, strerror(errno));
- return 1;
- }
- row_pointer[0] = rowout;
-
- jerr.error_exit = jpeg_error;
-
- jpeg_create_compress(&cinfo);
- cinfo.err = jpeg_std_error(&jerr);
- jpeg_stdio_dest(&cinfo, stdout);
- cinfo.image_width = width;
- cinfo.image_height = height;
- cinfo.input_components = 3; /* color components per pixel */
- cinfo.in_color_space = JCS_RGB; /* output color space */
- jpeg_set_defaults(&cinfo);
- if (optimize)
- cinfo.optimize_coding = TRUE;
- jpeg_set_quality(&cinfo, quality, TRUE);
-
- jpeg_start_compress(&cinfo, TRUE);
+ rowout = ereallocarray(NULL, width, (sizeof("RGB") - 1) * sizeof(uint8_t));
/* write rows */
for (i = 0; i < height; ++i) {
if (fread(row, sizeof(uint16_t), rowlen, stdin) != rowlen) {
- goto readerr;
+ if (ferror(stdin)) {
+ fprintf(stderr, "%s: fread: %s\n", argv0,
+ strerror(errno));
+ } else {
+ fprintf(stderr, "%s: unexpected end of file\n",
+ argv0);
+ }
+ return 1;
}
for (j = 0, k = 0; j < rowlen; j += 4, k += 3) {
a = ntohs(row[j + 3]);
@@ -124,19 +111,12 @@ main(int argc, char *argv[])
(257 * 65535);
}
}
- jpeg_write_scanlines(&cinfo, row_pointer, 1);
+ jpeg_write_scanlines(&jcomp, &rowout, 1);
}
- jpeg_finish_compress(&cinfo);
- jpeg_destroy_compress(&cinfo);
+ /* clean up */
+ jpeg_finish_compress(&jcomp);
+ jpeg_destroy_compress(&jcomp);
return 0;
-readerr:
- if (ferror(stdin)) {
- fprintf(stderr, "%s: fread: %s\n", argv0, strerror(errno));
- } else {
- fprintf(stderr, "%s: unexpected end of file\n", argv0);
- }
-
- return 1;
}
diff --git a/jpg2ff.c b/jpg2ff.c
index 85c935d..8d51fb6 100644
--- a/jpg2ff.c
+++ b/jpg2ff.c
@@ -5,12 +5,13 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <jpeglib.h>
#include "util.h"
-METHODDEF(void)
+static void
jpeg_error(j_common_ptr js)
{
fprintf(stderr, "%s: libjpeg: ", argv0);
@@ -18,6 +19,31 @@ jpeg_error(j_common_ptr js)
exit(1);
}
+static void
+jpeg_setup_reader(struct jpeg_decompress_struct *s, struct jpeg_error_mgr *e,
+ uint32_t *w, uint32_t *h)
+{
+ jpeg_create_decompress(s);
+ e->error_exit = jpeg_error;
+ s->err = jpeg_std_error(e);
+
+ jpeg_stdio_src(s, stdin);
+ jpeg_read_header(s, 1);
+ *w = s->image_width;
+ *h = s->image_height;
+ s->output_components = 3; /* color components per pixel */
+ s->out_color_space = JCS_RGB; /* input color space */
+
+ jpeg_start_decompress(s);
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s\n", argv0);
+ exit(1);
+}
+
int
main(int argc, char *argv[])
{
@@ -25,72 +51,44 @@ main(int argc, char *argv[])
struct jpeg_error_mgr jerr;
uint32_t width, height;
uint16_t *row;
+ uint8_t *rowin;
size_t rowlen, i;
- JSAMPARRAY jpgrow;
+ /* arguments */
argv0 = argv[0], argc--, argv++;
if (argc) {
- fprintf(stderr, "usage: %s\n", argv0);
- return 1;
+ usage();
}
- /* load jpg */
- js.err = jpeg_std_error(&jerr);
- jerr.error_exit = jpeg_error;
-
- jpeg_create_decompress(&js);
-
- jpeg_stdio_src(&js, stdin);
-
- jpeg_read_header(&js, 1);
- width = js.image_width;
- height = js.image_height;
-
- /* set output format */
- js.output_components = 3; /* color components per pixel */
- js.out_color_space = JCS_RGB; /* input color space */
-
- jpeg_start_decompress(&js);
-
- /* create output buffers */
- jpgrow = (*js.mem->alloc_sarray)((j_common_ptr)&js,
- JPOOL_IMAGE, width *
- js.output_components, 1);
+ /* prepare */
+ jpeg_setup_reader(&js, &jerr, &width, &height);
+ row = ereallocarray(NULL, width, (sizeof("RGBA") - 1) * sizeof(uint16_t));
rowlen = width * (sizeof("RGBA") - 1);
- if(!(row = malloc(rowlen * sizeof(uint16_t)))) {
- fprintf(stderr, "%s: malloc: out of memory\n", argv0);
- return 1;
- }
+ rowin = ereallocarray(NULL, width, (sizeof("RGB") - 1) * sizeof(uint8_t));
/* write data */
- write_ff_header(width, height);
+ ff_write_header(width, height);
while (js.output_scanline < js.output_height) {
- /* 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. */
- jpeg_read_scanlines(&js, jpgrow, 1);
+ jpeg_read_scanlines(&js, &rowin, 1);
for (i = 0; i < width; ++i) {
- row[4*i + 0] = htons(jpgrow[0][3*i + 0] * 257);
- row[4*i + 1] = htons(jpgrow[0][3*i + 1] * 257);
- row[4*i + 2] = htons(jpgrow[0][3*i + 2] * 257);
- row[4*i + 3] = htons(65535);
+ row[4 * i + 0] = htons(rowin[3 * i + 0] * 257);
+ row[4 * i + 1] = htons(rowin[3 * i + 1] * 257);
+ row[4 * i + 2] = htons(rowin[3 * i + 2] * 257);
+ row[4 * i + 3] = htons(65535);
}
- if (fwrite(row, sizeof(uint16_t), rowlen, stdout) != rowlen)
- goto writerr;
+ if (fwrite(row, sizeof(uint16_t), rowlen, stdout) != rowlen) {
+ fprintf(stderr, "%s: fwrite: %s\n", argv0, strerror(errno));
+ return 1;
+ }
}
+
+ /* clean up */
jpeg_finish_decompress(&js);
jpeg_destroy_decompress(&js);
return 0;
-writerr:
- fprintf(stderr, "%s: fwrite: ", argv0);
- perror(NULL);
-
- return 1;
}