diff --git a/dulcepan.cfg b/dulcepan.cfg index 682c5b0..7afa8e0 100644 --- a/dulcepan.cfg +++ b/dulcepan.cfg @@ -11,3 +11,6 @@ border-size = 2 # If true, dulcepan will save immediately when interactive selection is stopped # or when a whole output is selected with a mouse button. quick-select = false + +# PNG (zlib) compression level, 0-9 +png-compression = 6 diff --git a/src/config.c b/src/config.c index 8116677..0470f4d 100644 --- a/src/config.c +++ b/src/config.c @@ -76,6 +76,7 @@ void dp_config_load(struct dp_config *config, const char *user_path) { *config = (struct dp_config){ .border_size = 2, + .png_compression = 6, .quick_select = false, }; bytes_to_color((uint32_t[]){0xff, 0xff, 0xff, 0x40}, &config->unselected_color); @@ -168,6 +169,12 @@ void dp_config_load(struct dp_config *config, const char *user_path) { load_color(value, line_idx, &config->border_color); } else if (strcmp(key, "border-size") == 0) { load_int(value, line_idx, &config->border_size); + } else if (strcmp(key, "png-compression") == 0) { + load_int(value, line_idx, &config->png_compression); + if (config->png_compression > 9) { + dp_log_fatal( + "Config: invalid value %d for png-compression", config->png_compression); + } } else if (strcmp(key, "quick-select") == 0) { load_bool(value, line_idx, &config->quick_select); } else { diff --git a/src/dulcepan.h b/src/dulcepan.h index 78ca80e..532c4e4 100644 --- a/src/dulcepan.h +++ b/src/dulcepan.h @@ -105,6 +105,7 @@ struct dp_config { pixman_color_t selected_color; pixman_color_t border_color; int border_size; // 0 if disabled + int png_compression; bool quick_select; }; diff --git a/src/save.c b/src/save.c index 1563639..81fb7ec 100644 --- a/src/save.c +++ b/src/save.c @@ -61,7 +61,7 @@ static pixman_format_code_t shm_to_pixman(enum wl_shm_format shm_format) { return 0; // Unreachable, actually } -static void write_png(FILE *fp, pixman_image_t *image, int width, int height) { +static void write_png(FILE *fp, pixman_image_t *image, int width, int height, int level) { void *data = pixman_image_get_data(image); size_t size = (size_t)(width * height * 4); @@ -75,6 +75,7 @@ static void write_png(FILE *fp, pixman_image_t *image, int width, int height) { spng_set_ihdr(spng_ctx, &ihdr); spng_set_png_file(spng_ctx, fp); + spng_set_option(spng_ctx, SPNG_IMG_COMPRESSION_LEVEL, level); int err = spng_encode_image(spng_ctx, data, size, SPNG_FMT_PNG, SPNG_ENCODE_FINALIZE); if (err != 0) { @@ -158,7 +159,8 @@ void dp_save(struct dp_state *state) { case DP_FILE_UNKNOWN: abort(); // Unreachable case DP_FILE_PNG: - write_png(fp, out_image, selection->width, selection->height); + write_png( + fp, out_image, selection->width, selection->height, state->config.png_compression); break; case DP_FILE_PPM: write_ppm(fp, out_image, selection->width, selection->height);