Introduction
Introduction Statistics Contact Development Disclaimer Help
Refactor tools and increase performance by ~70% - farbfeld - suckless image for…
git clone git://git.suckless.org/farbfeld
Log
Files
Refs
README
LICENSE
---
commit de61085a0413f2f7570a89df345eb875d1a0298c
parent 7b03f52a130a12355d87bc05f028db31963112cc
Author: FRIGN <[email protected]>
Date: Mon, 1 Feb 2016 13:36:55 +0100
Refactor tools and increase performance by ~70%
Instead of calling fwrite on each channel, we write one big chunk
of a line.
This increases performance by around 70% compared to version 1 and
the farbfeld tools are now roughly fast as imagemagick's convert.
I also refactored the code, removed unnecessary variables and unified
the variable naming and error reporting a bit.
Inside jpg2ff, the loop didn't need 3 variables.
Diffstat:
M ff2png.c | 32 ++++++++++++++++-------------…
M jpg2ff.c | 80 ++++++++++++++++-------------…
M png2ff.c | 30 ++++++++++++------------------
3 files changed, 69 insertions(+), 73 deletions(-)
---
diff --git a/ff2png.c b/ff2png.c
@@ -9,7 +9,7 @@
#include <png.h>
-#define HEADER "farbfeld########"
+#define HDR "farbfeld########"
static char *argv0;
@@ -25,9 +25,9 @@ main(int argc, char *argv[])
{
png_structp pngs;
png_infop pngi;
- size_t png_row_len, j;
+ size_t rowlen;
uint32_t width, height, i;
- uint16_t tmp16, *png_row;
+ uint16_t *row;
uint8_t hdr[16];
argv0 = argv[0], argc--, argv++;
@@ -38,11 +38,10 @@ main(int argc, char *argv[])
}
/* header */
- if (fread(hdr, 1, strlen(HEADER), stdin) != strlen(HEADER)) {
- fprintf(stderr, "%s: incomplete header\n", argv0);
- return 1;
+ if (fread(hdr, 1, sizeof(HDR) - 1, stdin) != sizeof(HDR) - 1) {
+ goto readerr;
}
- if (memcmp("farbfeld", hdr, strlen("farbfeld"))) {
+ if (memcmp("farbfeld", hdr, sizeof("farbfeld") - 1)) {
fprintf(stderr, "%s: invalid magic value\n", argv0);
return 1;
}
@@ -65,23 +64,24 @@ main(int argc, char *argv[])
png_write_info(pngs, pngi);
/* write rows */
- png_row_len = strlen("RGBA") * width * sizeof(uint16_t);
- if (!(png_row = malloc(png_row_len))) {
+ rowlen = (sizeof("RGBA") - 1) * width;
+ if (!(row = malloc(rowlen * sizeof(uint16_t)))) {
fprintf(stderr, "%s: malloc: out of memory\n", argv0);
return 1;
}
for (i = 0; i < height; ++i) {
- for (j = 0; j < png_row_len / sizeof(uint16_t); ++j) {
- if (fread(&tmp16, sizeof(uint16_t), 1, stdin) != 1) {
- fprintf(stderr, "%s: unexpected EOF\n", argv0);
- return 1;
- }
- png_row[j] = tmp16;
+ if (fread(row, sizeof(uint16_t), rowlen, stdin) != rowlen) {
+ goto readerr;
}
- png_write_row(pngs, (uint8_t *)png_row);
+ png_write_row(pngs, (uint8_t *)row);
}
png_write_end(pngs, NULL);
png_destroy_write_struct(&pngs, NULL);
return 0;
+readerr:
+ fprintf(stderr, "%s: fread: ", argv0);
+ perror(NULL);
+
+ return 1;
}
diff --git a/jpg2ff.c b/jpg2ff.c
@@ -12,22 +12,22 @@
static char *argv0;
METHODDEF(void)
-jpeg_error(j_common_ptr cinfo)
+jpeg_error(j_common_ptr js)
{
fprintf(stderr, "%s: libjpeg: ", argv0);
- (*cinfo->err->output_message)(cinfo);
+ (*js->err->output_message)(js);
exit(1);
}
int
main(int argc, char *argv[])
{
- struct jpeg_decompress_struct cinfo;
+ struct jpeg_decompress_struct js;
struct jpeg_error_mgr jerr;
- uint32_t width, height, val_be;
- uint16_t *ff_row;
- size_t jpeg_row_len, ff_row_len, i, dx, sx;
- JSAMPARRAY buffer; /* output row buffer */
+ uint32_t width, height, tmp32;
+ uint16_t *row;
+ size_t rowlen, i;
+ JSAMPARRAY jpgrow;
argv0 = argv[0], argc--, argv++;
@@ -37,61 +37,63 @@ main(int argc, char *argv[])
}
/* load jpg */
- cinfo.err = jpeg_std_error(&jerr);
+ js.err = jpeg_std_error(&jerr);
jerr.error_exit = jpeg_error;
- jpeg_create_decompress(&cinfo);
+ jpeg_create_decompress(&js);
- jpeg_stdio_src(&cinfo, stdin);
+ jpeg_stdio_src(&js, stdin);
- jpeg_read_header(&cinfo, TRUE);
- width = cinfo.image_width;
- height = cinfo.image_height;
+ jpeg_read_header(&js, 1);
+ width = js.image_width;
+ height = js.image_height;
/* set output format */
- cinfo.output_components = 3; /* color components per pixel */
- cinfo.out_color_space = JCS_RGB; /* input color space */
+ js.output_components = 3; /* color components per pixel */
+ js.out_color_space = JCS_RGB; /* input color space */
- jpeg_start_decompress(&cinfo);
- jpeg_row_len = width * cinfo.output_components;
+ jpeg_start_decompress(&js);
/* create output buffers */
- buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo,
- JPOOL_IMAGE, jpeg_row_len, 1);
- ff_row_len = strlen("RGBA") * width;
- if(!(ff_row = malloc(ff_row_len * sizeof(uint16_t)))) {
+ jpgrow = (*js.mem->alloc_sarray)((j_common_ptr)&js,
+ JPOOL_IMAGE, width *
+ js.output_components, 1);
+ rowlen = strlen("RGBA") * width;
+ if(!(row = malloc(rowlen * sizeof(uint16_t)))) {
fprintf(stderr, "%s: malloc: out of memory\n", argv0);
return 1;
}
/* write header */
fprintf(stdout, "farbfeld");
- val_be = htonl(width);
- if (fwrite(&val_be, sizeof(uint32_t), 1, stdout) != 1)
+ tmp32 = htonl(width);
+ if (fwrite(&tmp32, sizeof(uint32_t), 1, stdout) != 1)
goto writerr;
- val_be = htonl(height);
- if (fwrite(&val_be, sizeof(uint32_t), 1, stdout) != 1)
+ tmp32 = htonl(height);
+ if (fwrite(&tmp32, sizeof(uint32_t), 1, stdout) != 1)
goto writerr;
- while (cinfo.output_scanline < cinfo.output_height) {
- /* jpeg_read_scanlines expects an array of pointers to scanlin…
- * Here the array is only one element long, but you could ask …
- * more than one scanline at a time if that's more convenient.…
- 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);
- ff_row[dx+1] = htons(buffer[0][sx+1] * 257);
- ff_row[dx+2] = htons(buffer[0][sx+2] * 257);
- ff_row[dx+3] = htons(65535);
+ 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);
+
+ 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);
}
/* write data */
- if (fwrite(ff_row, 2, ff_row_len, stdout) != ff_row_len)
+ if (fwrite(row, 2, rowlen, stdout) != rowlen)
goto writerr;
}
- jpeg_finish_decompress(&cinfo);
- jpeg_destroy_decompress(&cinfo);
+ jpeg_finish_decompress(&js);
+ jpeg_destroy_decompress(&js);
return 0;
writerr:
diff --git a/png2ff.c b/png2ff.c
@@ -23,9 +23,9 @@ main(int argc, char *argv[])
{
png_structp pngs;
png_infop pngi;
- uint32_t width, height, outrowlen, tmp32, r, i;
- uint16_t *outrow;
- uint8_t **png_row_p;
+ uint32_t width, height, rowlen, tmp32, r, i;
+ uint16_t *row;
+ uint8_t **pngrows;
argv0 = argv[0], argc--, argv++;
@@ -54,15 +54,13 @@ main(int argc, char *argv[])
PNG_TRANSFORM_EXPAND, NULL);
width = png_get_image_width(pngs, pngi);
height = png_get_image_height(pngs, pngi);
- png_row_p = png_get_rows(pngs, pngi);
-
+ pngrows = png_get_rows(pngs, pngi);
/* allocate output row buffer */
- outrowlen = width * strlen("RGBA");
- if (!(outrow = malloc(outrowlen * sizeof(uint16_t)))) {
+ rowlen = width * strlen("RGBA");
+ if (!(row = malloc(rowlen * sizeof(uint16_t)))) {
fprintf(stderr, "%s: malloc: out of memory\n", argv0);
return 1;
}
-
/* write header */
fputs("farbfeld", stdout);
tmp32 = htonl(width);
@@ -71,27 +69,23 @@ main(int argc, char *argv[])
tmp32 = htonl(height);
if (fwrite(&tmp32, sizeof(uint32_t), 1, stdout) != 1)
goto writerr;
-
/* write data */
switch(png_get_bit_depth(pngs, pngi)) {
case 8:
for (r = 0; r < height; ++r) {
- for (i = 0; i < outrowlen; i++) {
- outrow[i] = htons(257 * png_row_p[r][i]);
+ for (i = 0; i < rowlen; i++) {
+ row[i] = htons(257 * pngrows[r][i]);
}
- if (fwrite(outrow, sizeof(uint16_t), outrowlen,
- stdout) != outrowlen) {
+ if (fwrite(row, sizeof(uint16_t), rowlen,
+ stdout) != rowlen) {
goto writerr;
}
}
break;
case 16:
for (r = 0; r < height; ++r) {
- for (i = 0; i < outrowlen; ++i) {
- outrow[i] = ((uint16_t *)png_row_p[r])[i];
- }
- if (fwrite(outrow, sizeof(uint16_t), outrowlen,
- stdout) != outrowlen) {
+ if (fwrite(pngrows[r], sizeof(uint16_t),
+ rowlen, stdout) != rowlen) {
goto writerr;
}
}
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.