[hackers] [farbfeld] Refactor tools and increase performance by ~70% || FRIGN

From: <git_AT_suckless.org>
Date: Mon, 1 Feb 2016 13:40:35 +0100 (CET)

commit de61085a0413f2f7570a89df345eb875d1a0298c
Author: FRIGN <dev_AT_frign.de>
AuthorDate: Mon Feb 1 13:36:55 2016 +0100
Commit: FRIGN <dev_AT_frign.de>
CommitDate: Mon Feb 1 13:36:55 2016 +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.

diff --git a/ff2png.c b/ff2png.c
index 46c71a8..52bdc58 100644
--- a/ff2png.c
+++ b/ff2png.c
_AT_@ -9,7 +9,7 @@
 
 #include <png.h>
 
-#define HEADER "farbfeld########"
+#define HDR "farbfeld########"
 
 static char *argv0;
 
_AT_@ -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++;
_AT_@ -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;
         }
_AT_@ -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
index 7a25f03..3140908 100644
--- a/jpg2ff.c
+++ b/jpg2ff.c
_AT_@ -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++;
 
_AT_@ -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 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(&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
index 6fefd4e..99757be 100644
--- a/png2ff.c
+++ b/png2ff.c
_AT_@ -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++;
 
_AT_@ -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);
_AT_@ -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;
                         }
                 }
Received on Mon Feb 01 2016 - 13:40:35 CET

This archive was generated by hypermail 2.3.0 : Mon Feb 01 2016 - 13:48:14 CET