2023-08-04 22:34:07 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
|
/*
|
|
|
|
|
* Copyright (C) Johan Malm 2023
|
|
|
|
|
*/
|
|
|
|
|
#define _POSIX_C_SOURCE 200809L
|
|
|
|
|
#include <cairo.h>
|
|
|
|
|
#include <png.h>
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <wlr/util/log.h>
|
|
|
|
|
#include "buffer.h"
|
2024-09-06 17:00:40 +09:00
|
|
|
#include "img/img-png.h"
|
2024-01-19 19:06:07 +00:00
|
|
|
#include "common/string-helpers.h"
|
2023-08-04 22:34:07 +01:00
|
|
|
#include "labwc.h"
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* cairo_image_surface_create_from_png() does not gracefully handle non-png
|
|
|
|
|
* files, so we verify the header before trying to read the rest of the file.
|
|
|
|
|
*/
|
|
|
|
|
#define PNG_BYTES_TO_CHECK (4)
|
|
|
|
|
static bool
|
|
|
|
|
ispng(const char *filename)
|
|
|
|
|
{
|
|
|
|
|
unsigned char header[PNG_BYTES_TO_CHECK];
|
|
|
|
|
FILE *fp = fopen(filename, "rb");
|
|
|
|
|
if (!fp) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (fread(header, 1, PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK) {
|
|
|
|
|
fclose(fp);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (png_sig_cmp(header, (png_size_t)0, PNG_BYTES_TO_CHECK)) {
|
|
|
|
|
wlr_log(WLR_ERROR, "file '%s' is not a recognised png file", filename);
|
|
|
|
|
fclose(fp);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
fclose(fp);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#undef PNG_BYTES_TO_CHECK
|
|
|
|
|
|
|
|
|
|
void
|
2024-10-06 22:38:03 -04:00
|
|
|
img_png_load(const char *filename, struct lab_data_buffer **buffer, int size,
|
|
|
|
|
float scale)
|
2023-08-04 22:34:07 +01:00
|
|
|
{
|
|
|
|
|
if (*buffer) {
|
|
|
|
|
wlr_buffer_drop(&(*buffer)->base);
|
|
|
|
|
*buffer = NULL;
|
|
|
|
|
}
|
2024-09-06 17:00:40 +09:00
|
|
|
if (string_null_or_empty(filename)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!ispng(filename)) {
|
2024-01-17 21:50:53 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2023-08-04 22:34:07 +01:00
|
|
|
|
2024-09-06 17:00:40 +09:00
|
|
|
cairo_surface_t *image = cairo_image_surface_create_from_png(filename);
|
2023-08-04 22:34:07 +01:00
|
|
|
if (cairo_surface_status(image)) {
|
2024-09-06 17:00:40 +09:00
|
|
|
wlr_log(WLR_ERROR, "error reading png button '%s'", filename);
|
2023-08-04 22:34:07 +01:00
|
|
|
cairo_surface_destroy(image);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-06 22:38:03 -04:00
|
|
|
*buffer = buffer_convert_cairo_surface_for_icon(image, size, scale);
|
2023-08-04 22:34:07 +01:00
|
|
|
}
|