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, ...],
|
os_window_ids: Tuple[int, ...],
|
||||||
configured: bool = True,
|
configured: bool = True,
|
||||||
layout_name: Optional[str] = None,
|
layout_name: Optional[str] = None,
|
||||||
|
png_data: bytes = b''
|
||||||
) -> None:
|
) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@ -297,41 +297,34 @@ add_trim_predicate(Image *img) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
png_path_to_bitmap(const char* path, uint8_t** data, unsigned int* width, unsigned int* height, size_t* sz) {
|
png_from_file_pointer(FILE *fp, const char *path_for_error_messages, 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;
|
|
||||||
}
|
|
||||||
size_t capacity = 16*1024, pos = 0;
|
size_t capacity = 16*1024, pos = 0;
|
||||||
unsigned char *buf = malloc(capacity);
|
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)) {
|
while (!feof(fp)) {
|
||||||
if (capacity - pos < 1024) {
|
if (capacity - pos < 1024) {
|
||||||
capacity *= 2;
|
capacity *= 2;
|
||||||
unsigned char *new_buf = realloc(buf, capacity);
|
unsigned char *new_buf = realloc(buf, capacity);
|
||||||
if (!new_buf) {
|
if (!new_buf) {
|
||||||
free(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;
|
buf = new_buf;
|
||||||
}
|
}
|
||||||
pos += fread(buf + pos, sizeof(char), capacity - pos, fp);
|
pos += fread(buf + pos, sizeof(char), capacity - pos, fp);
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
if (ferror(fp) && saved_errno != EINTR) {
|
if (ferror(fp) && saved_errno != EINTR) {
|
||||||
log_error("Failed while reading from file: %s with error: %s", path, strerror(saved_errno));
|
log_error("Failed while reading from file: %s with error: %s", path_for_error_messages, strerror(saved_errno));
|
||||||
fclose(fp);
|
|
||||||
free(buf);
|
free(buf);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fp); fp = NULL;
|
|
||||||
png_read_data d = {0};
|
png_read_data d = {0};
|
||||||
inflate_png_inner(&d, buf, pos);
|
inflate_png_inner(&d, buf, pos);
|
||||||
free(buf);
|
free(buf);
|
||||||
if (!d.ok) {
|
if (!d.ok) {
|
||||||
free(d.decompressed); free(d.row_pointers);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
*data = d.decompressed;
|
*data = d.decompressed;
|
||||||
@ -341,6 +334,18 @@ png_path_to_bitmap(const char* path, uint8_t** data, unsigned int* width, unsign
|
|||||||
return true;
|
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*
|
static Image*
|
||||||
find_or_create_image(GraphicsManager *self, uint32_t id, bool *existing) {
|
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 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_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);
|
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 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);
|
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 *layout_name = NULL;
|
||||||
PyObject *os_window_ids;
|
PyObject *os_window_ids;
|
||||||
int configured = 0;
|
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;
|
size_t size;
|
||||||
BackgroundImageLayout layout = PyUnicode_Check(layout_name) ? bglayout(layout_name) : OPT(background_image_layout);
|
BackgroundImageLayout layout = PyUnicode_Check(layout_name) ? bglayout(layout_name) : OPT(background_image_layout);
|
||||||
BackgroundImage *bgimage = NULL;
|
BackgroundImage *bgimage = NULL;
|
||||||
if (path) {
|
if (path) {
|
||||||
bgimage = calloc(1, sizeof(BackgroundImage));
|
bgimage = calloc(1, sizeof(BackgroundImage));
|
||||||
if (!bgimage) return PyErr_NoMemory();
|
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);
|
PyErr_Format(PyExc_ValueError, "Failed to load image from: %s", path);
|
||||||
free(bgimage);
|
free(bgimage);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user