Introduction
Introduction Statistics Contact Development Disclaimer Help
add ff2jpg tool, convert farbfeld images to RGB JPEG - farbfeld - suckless imag…
git clone git://git.suckless.org/farbfeld
Log
Files
Refs
README
LICENSE
---
commit 34e9cba51f5149da0670b32101e23b4d76e20d61
parent 7f295f8c100a504c305d537bd3fde6492f15ef7a
Author: Hiltjo Posthuma <[email protected]>
Date: Thu, 24 Mar 2016 19:17:48 +0100
add ff2jpg tool, convert farbfeld images to RGB JPEG
Diffstat:
M LICENSE | 2 +-
M Makefile | 4 ++--
A ff2jpg.1 | 56 +++++++++++++++++++++++++++++…
A ff2jpg.c | 151 +++++++++++++++++++++++++++++…
4 files changed, 210 insertions(+), 3 deletions(-)
---
diff --git a/LICENSE b/LICENSE
@@ -15,5 +15,5 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARIS…
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
(c) 2014-2015 Dimitris Papastamos <[email protected]>
-(c) 2014-2015 Hiltjo Posthuma <[email protected]>
+(c) 2014-2016 Hiltjo Posthuma <[email protected]>
(c) 2015 Willy Goiffon <[email protected]>
diff --git a/Makefile b/Makefile
@@ -2,7 +2,7 @@
# See LICENSE file for copyright and license details
include config.mk
-BIN = png2ff ff2png jpg2ff ff2ppm
+BIN = png2ff ff2png jpg2ff ff2jpg ff2ppm
SRC = ${BIN:=.c}
HDR = arg.h
MAN1 = 2ff.1 ${BIN:=.1}
@@ -15,7 +15,7 @@ png2ff ff2png:
@${CC} -o $@ ${CFLAGS} ${CPPFLAGS} -L${PNGLIB} -lpng -I${PNGINC} \
${LDFLAGS} [email protected]
-jpg2ff:
+jpg2ff ff2jpg:
@echo CC $@
@${CC} -o $@ ${CFLAGS} ${CPPFLAGS} -L${JPGLIB} -ljpeg -I${JPGINC} \
${LDFLAGS} [email protected]
diff --git a/ff2jpg.1 b/ff2jpg.1
@@ -0,0 +1,56 @@
+.Dd 2016-03-23
+.Dt FF2JPG 1
+.Os suckless.org
+.Sh NAME
+.Nm ff2jpg
+.Nd convert farbfeld to JPEG
+.Sh SYNOPSIS
+.Nm
+.Op Fl b Ar color
+.Op Fl o
+.Op Fl q Ar quality
+.Sh DESCRIPTION
+.Nm
+reads a
+.Xr farbfeld 5
+image from stdin, converts it to a JPEG image (RGB) and writes the result to
+stdout.
+.Pp
+In case of an error
+.Nm
+writes a diagnostic message to stderr.
+.Sh OPTIONS
+.Bl -tag -width Ds
+.It Fl b Ar color
+.Ar color
+to mix with the background alpha channel, the default is white.
+.Pp
+The following formats are supported:
+"#rrggbb", "#rrrrggggbbbb" and the short-form "#rgb" which expands to "#rrggbb…
+.It Fl o
+Optimize Huffman table (smaller file, but slow compression).
+.It Fl q Ar quality
+set JPEG output
+.Ar quality
+(range 0-100), the default is 85.
+.El
+.Sh EXIT STATUS
+.Bl -tag -width Ds
+.It 0
+Image processed successfully.
+.It 1
+An error occurred.
+.El
+.Sh EXAMPLES
+$
+png2ff < test.png |
+.Nm
+-b '#00ff00' -q 85 > test.jpg
+.Sh SEE ALSO
+.Xr 2ff 1 ,
+.Xr bunzip2 1 ,
+.Xr bzip2 1 ,
+.Xr png2ff 1 ,
+.Xr farbfeld 5
+.Sh AUTHORS
+.An Hiltjo Posthuma Aq Mt [email protected]
diff --git a/ff2jpg.c b/ff2jpg.c
@@ -0,0 +1,151 @@
+/* See LICENSE file for copyright and license details. */
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <jpeglib.h>
+
+#include "arg.h"
+
+char *argv0;
+
+METHODDEF(void)
+jpeg_error(j_common_ptr js)
+{
+ fprintf(stderr, "%s: libjpeg: ", argv0);
+ (*js->err->output_message)(js);
+ exit(1);
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s [-b #rrggbb] [-o] [-q quality]\n", argv0);
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ JSAMPROW row_pointer[1]; /* pointer to a single row */
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ size_t rowlen;
+ uint64_t a;
+ uint32_t hdr[4], 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;
+
+ argv0 = argv[0];
+ ARGBEGIN {
+ case 'b':
+ color = EARGF(usage());
+ if (color[0] == '#') {
+ color++;
+ }
+ collen = strlen(color);
+ if (collen != 3 && collen != 6 && collen != 12) {
+ 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();
+ break;
+ default:
+ usage();
+ } ARGEND
+
+ if (argc)
+ usage();
+
+ /* header */
+ if (fread(hdr, sizeof(*hdr), 4, stdin) != 4) {
+ fprintf(stderr, "%s: fread: %s\n", argv0, strerror(errno));
+ return 1;
+ }
+ if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1)) {
+ fprintf(stderr, "%s: invalid magic value\n", argv0);
+ return 1;
+ }
+ if (!(width = ntohl(hdr[2]))) {
+ fprintf(stderr, "%s: invalid width: zero\n", argv0);
+ return 1;
+ }
+ if (!(height = ntohl(hdr[3]))) {
+ fprintf(stderr, "%s: invalid height: zero\n", argv0);
+ return 1;
+ }
+
+ if (width > SIZE_MAX / ((sizeof("RGBA") - 1) * sizeof(uint16_t))) {
+ fprintf(stderr, "%s: row length integer overflow\n", argv0);
+ return 1;
+ }
+ 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);
+
+ /* write rows */
+ for (i = 0; i < height; ++i) {
+ if (fread(row, sizeof(uint16_t), rowlen, stdin) != rowlen) {
+ fprintf(stderr, "%s: fread: %s\n", argv0, strerror(err…
+ return 1;
+ }
+ for (j = 0, k = 0; j < rowlen; j += 4, k += 3) {
+ a = ntohs(row[j + 3]);
+ for (l = 0; l < 3; l++) {
+ rowout[k + l] = (a * ntohs(row[j + l]) +
+ (65535 - a) * mask[l]) /
+ (257 * 65535);
+ }
+ }
+ jpeg_write_scanlines(&cinfo, row_pointer, 1);
+ }
+
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+
+ return 0;
+}
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.