Allow loading window background images from memory
This commit is contained in:
parent
bf79940a13
commit
1bf180f354
@ -609,6 +609,7 @@ def set_background_image(
|
||||
os_window_ids: Tuple[int, ...],
|
||||
configured: bool = True,
|
||||
layout_name: Optional[str] = None,
|
||||
png_data: bytes = b''
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
|
||||
@ -297,41 +297,34 @@ add_trim_predicate(Image *img) {
|
||||
}
|
||||
|
||||
bool
|
||||
png_path_to_bitmap(const char* path, uint8_t** data, unsigned int* width, unsigned int* height, size_t* sz) {
|
||||
FILE* fp = fopen(path, "r");
|
||||
if (fp == NULL) {
|
||||
log_error("The PNG image: %s could not be opened with error: %s", path, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
png_from_file_pointer(FILE *fp, const char *path_for_error_messages, uint8_t** data, unsigned int* width, unsigned int* height, size_t* sz) {
|
||||
size_t capacity = 16*1024, pos = 0;
|
||||
unsigned char *buf = malloc(capacity);
|
||||
if (!buf) { log_error("Out of memory reading PNG file at: %s", path); fclose(fp); return false; }
|
||||
if (!buf) { log_error("Out of memory reading PNG file at: %s", path_for_error_messages); fclose(fp); return false; }
|
||||
while (!feof(fp)) {
|
||||
if (capacity - pos < 1024) {
|
||||
capacity *= 2;
|
||||
unsigned char *new_buf = realloc(buf, capacity);
|
||||
if (!new_buf) {
|
||||
free(buf);
|
||||
log_error("Out of memory reading PNG file at: %s", path); fclose(fp); return false;
|
||||
log_error("Out of memory reading PNG file at: %s", path_for_error_messages); fclose(fp); return false;
|
||||
}
|
||||
buf = new_buf;
|
||||
}
|
||||
pos += fread(buf + pos, sizeof(char), capacity - pos, fp);
|
||||
int saved_errno = errno;
|
||||
if (ferror(fp) && saved_errno != EINTR) {
|
||||
log_error("Failed while reading from file: %s with error: %s", path, strerror(saved_errno));
|
||||
fclose(fp);
|
||||
log_error("Failed while reading from file: %s with error: %s", path_for_error_messages, strerror(saved_errno));
|
||||
free(buf);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
fclose(fp); fp = NULL;
|
||||
png_read_data d = {0};
|
||||
inflate_png_inner(&d, buf, pos);
|
||||
free(buf);
|
||||
if (!d.ok) {
|
||||
free(d.decompressed); free(d.row_pointers);
|
||||
log_error("Failed to decode PNG image at: %s", path);
|
||||
log_error("Failed to decode PNG image at: %s", path_for_error_messages);
|
||||
return false;
|
||||
}
|
||||
*data = d.decompressed;
|
||||
@ -341,6 +334,18 @@ png_path_to_bitmap(const char* path, uint8_t** data, unsigned int* width, unsign
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
png_path_to_bitmap(const char* path, uint8_t** data, unsigned int* width, unsigned int* height, size_t* sz) {
|
||||
FILE* fp = fopen(path, "r");
|
||||
if (fp == NULL) {
|
||||
log_error("The PNG image: %s could not be opened with error: %s", path, strerror(errno));
|
||||
return false;
|
||||
}
|
||||
bool ret = png_from_file_pointer(fp, path, data, width, height, sz);
|
||||
fclose(fp); fp = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static Image*
|
||||
find_or_create_image(GraphicsManager *self, uint32_t id, bool *existing) {
|
||||
|
||||
@ -160,5 +160,6 @@ void grman_resize(GraphicsManager*, index_type, index_type, index_type, index_ty
|
||||
void grman_rescale(GraphicsManager *self, CellPixelSize fg);
|
||||
void gpu_data_for_image(ImageRenderData *ans, float left, float top, float right, float bottom);
|
||||
void gpu_data_for_centered_image(ImageRenderData *ans, unsigned int screen_width_px, unsigned int screen_height_px, unsigned int width, unsigned int height);
|
||||
bool png_from_file_pointer(FILE* fp, const char *path, uint8_t** data, unsigned int* width, unsigned int* height, size_t* sz);
|
||||
bool png_path_to_bitmap(const char *path, uint8_t** data, unsigned int* width, unsigned int* height, size_t* sz);
|
||||
bool scan_active_animations(GraphicsManager *self, const monotonic_t now, monotonic_t *minimum_gap, bool os_window_context_set);
|
||||
|
||||
@ -1152,14 +1152,27 @@ pyset_background_image(PyObject *self UNUSED, PyObject *args) {
|
||||
PyObject *layout_name = NULL;
|
||||
PyObject *os_window_ids;
|
||||
int configured = 0;
|
||||
PA("zO!|pO", &path, &PyTuple_Type, &os_window_ids, &configured, &layout_name);
|
||||
char *png_data = NULL; Py_ssize_t png_data_size = 0;
|
||||
PA("zO!|pOy#", &path, &PyTuple_Type, &os_window_ids, &configured, &layout_name, &png_data, png_data_size);
|
||||
size_t size;
|
||||
BackgroundImageLayout layout = PyUnicode_Check(layout_name) ? bglayout(layout_name) : OPT(background_image_layout);
|
||||
BackgroundImage *bgimage = NULL;
|
||||
if (path) {
|
||||
bgimage = calloc(1, sizeof(BackgroundImage));
|
||||
if (!bgimage) return PyErr_NoMemory();
|
||||
if (!png_path_to_bitmap(path, &bgimage->bitmap, &bgimage->width, &bgimage->height, &size)) {
|
||||
bool ok;
|
||||
if (png_data) {
|
||||
FILE *fp = fmemopen(png_data, png_data_size, "r");
|
||||
if (fp == NULL) {
|
||||
PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
|
||||
free(bgimage);
|
||||
return NULL;
|
||||
}
|
||||
ok = png_from_file_pointer(fp, path, &bgimage->bitmap, &bgimage->width, &bgimage->height, &size);
|
||||
} else {
|
||||
ok = png_path_to_bitmap(path, &bgimage->bitmap, &bgimage->width, &bgimage->height, &size);
|
||||
}
|
||||
if (!ok) {
|
||||
PyErr_Format(PyExc_ValueError, "Failed to load image from: %s", path);
|
||||
free(bgimage);
|
||||
return NULL;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user