diff --git a/kitty/gl.c b/kitty/gl.c index 61c26c1da..7ced321f9 100644 --- a/kitty/gl.c +++ b/kitty/gl.c @@ -215,7 +215,7 @@ save_texture_as_png(uint32_t texture_id, const char *filename) { data[i] = (r << 0) | (g << 8) | (b << 16) | (a << 24); } - const char *png = png_from_32bit_rgba(data, width, height, &sz, true); + const char *png = png_from_32bit_rgba((char*)data, width, height, &sz, true); if (!sz) fatal("Failed to save PNG to %s with error: %s", filename, png); free(data); FILE* file = fopen(filename, "wb"); diff --git a/kitty/png-reader.c b/kitty/png-reader.c index 4fcd2c6d4..c666d59be 100644 --- a/kitty/png-reader.c +++ b/kitty/png-reader.c @@ -163,8 +163,8 @@ png_write_to_memory(png_structp png_ptr, png_bytep data, png_size_t length) { } static void png_flush_memory(png_structp png_ptr) { (void)png_ptr; } -const char* -png_from_32bit_rgba(uint32_t *data, size_t width, size_t height, size_t *out_size, bool flip_vertically) { +static const char* +create_png_from_data(char *data, size_t width, size_t height, size_t stride, size_t *out_size, bool flip_vertically, int color_type) { *out_size = 0; png_memory_write_state state = {.capacity=width*height * sizeof(uint32_t)}; state.buffer = malloc(state.capacity); @@ -181,7 +181,7 @@ png_from_32bit_rgba(uint32_t *data, size_t width, size_t height, size_t *out_siz return("Error during PNG creation\n"); } png_set_write_fn(png_ptr, &state, png_write_to_memory, png_flush_memory); - png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGBA, + png_set_IHDR(png_ptr, info_ptr, width, height, 8, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); // Allocate memory for row pointers png_bytep *row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height); @@ -190,8 +190,8 @@ png_from_32bit_rgba(uint32_t *data, size_t width, size_t height, size_t *out_siz free(state.buffer); return ("Failed to allocate memory for row pointers"); } - if (flip_vertically) for (size_t y = 0; y < height; y++) row_pointers[height - 1 - y] = (png_byte*)&data[y * width]; - else for (size_t y = 0; y < height; y++) row_pointers[y] = (png_byte*)&data[y * width]; + if (flip_vertically) for (size_t y = 0; y < height; y++) row_pointers[height - 1 - y] = (png_byte*)&data[y * stride]; + else for (size_t y = 0; y < height; y++) row_pointers[y] = (png_byte*)&data[y * stride]; png_write_info(png_ptr, info_ptr); png_write_image(png_ptr, row_pointers); png_write_end(png_ptr, NULL); @@ -201,6 +201,17 @@ png_from_32bit_rgba(uint32_t *data, size_t width, size_t height, size_t *out_siz return (char*)state.buffer; } +const char* +png_from_32bit_rgba(char *data, size_t width, size_t height, size_t *out_size, bool flip_vertically) { + return create_png_from_data(data, width, height, 4 * width, out_size, flip_vertically, PNG_COLOR_TYPE_RGBA); +} + +const char* +png_from_24bit_rgb(char *data, size_t width, size_t height, size_t *out_size, bool flip_vertically) { + return create_png_from_data(data, width, height, 3 * width, out_size, flip_vertically, PNG_COLOR_TYPE_RGB); +} + + static void png_error_handler(png_read_data *d UNUSED, const char *code, const char *msg) { if (!PyErr_Occurred()) PyErr_Format(PyExc_ValueError, "[%s] %s", code, msg); diff --git a/kitty/png-reader.h b/kitty/png-reader.h index b0eeeb72d..41fdbe05c 100644 --- a/kitty/png-reader.h +++ b/kitty/png-reader.h @@ -28,4 +28,5 @@ typedef struct png_read_data { } png_read_data; void inflate_png_inner(png_read_data *d, const uint8_t *buf, size_t bufsz, int max_image_dimension); -const char* png_from_32bit_rgba(uint32_t *data, size_t width, size_t height, size_t *out_size, bool flip_vertically); +const char* png_from_32bit_rgba(char *data, size_t width, size_t height, size_t *out_size, bool flip_vertically); +const char* png_from_24bit_rgb(char *data, size_t width, size_t height, size_t *out_size, bool flip_vertically);