summaryrefslogtreecommitdiff
path: root/ff2jpg.c
diff options
context:
space:
mode:
Diffstat (limited to 'ff2jpg.c')
-rw-r--r--ff2jpg.c112
1 files changed, 46 insertions, 66 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;
}