mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-07-03 11:12:30 +08:00
Function to save 24bit RGB data as PNG
This commit is contained in:
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user