Check wide thumbnail metadata
This commit is contained in:
parent
c49e58a0ba
commit
0110e0a5d2
|
@ -15,6 +15,8 @@
|
||||||
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include <spng.h>
|
#include <spng.h>
|
||||||
#include <webp/encode.h>
|
#include <webp/encode.h>
|
||||||
#include <webp/mux.h>
|
#include <webp/mux.h>
|
||||||
|
@ -73,6 +75,14 @@ FivThumbnailSizeInfo
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
#define THUMB_URI "Thumb::URI"
|
||||||
|
#define THUMB_MTIME "Thumb::MTime"
|
||||||
|
#define THUMB_SIZE "Thumb::Size"
|
||||||
|
#define THUMB_IMAGE_WIDTH "Thumb::Image::Width"
|
||||||
|
#define THUMB_IMAGE_HEIGHT "Thumb::Image::Height"
|
||||||
|
#define THUMB_COLORSPACE "Thumb::ColorSpace"
|
||||||
|
#define THUMB_COLORSPACE_SRGB "sRGB"
|
||||||
|
|
||||||
cairo_user_data_key_t fiv_thumbnail_key_lq;
|
cairo_user_data_key_t fiv_thumbnail_key_lq;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -250,20 +260,20 @@ fiv_thumbnail_produce(GFile *target, FivThumbnailSize max_size, GError **error)
|
||||||
|
|
||||||
GString *thum = g_string_new("");
|
GString *thum = g_string_new("");
|
||||||
g_string_append_printf(
|
g_string_append_printf(
|
||||||
thum, "%s%c%s%c", "Thumb::URI", 0, uri, 0);
|
thum, "%s%c%s%c", THUMB_URI, 0, uri, 0);
|
||||||
g_string_append_printf(
|
g_string_append_printf(
|
||||||
thum, "%s%c%ld%c", "Thumb::Mtime", 0, (long) st.st_mtim.tv_sec, 0);
|
thum, "%s%c%ld%c", THUMB_MTIME, 0, (long) st.st_mtim.tv_sec, 0);
|
||||||
g_string_append_printf(
|
g_string_append_printf(
|
||||||
thum, "%s%c%ld%c", "Thumb::Size", 0, (long) filesize, 0);
|
thum, "%s%c%ld%c", THUMB_SIZE, 0, (long) filesize, 0);
|
||||||
g_string_append_printf(thum, "%s%c%d%c", "Thumb::Image::Width", 0,
|
g_string_append_printf(thum, "%s%c%d%c", THUMB_IMAGE_WIDTH, 0,
|
||||||
cairo_image_surface_get_width(surface), 0);
|
cairo_image_surface_get_width(surface), 0);
|
||||||
g_string_append_printf(thum, "%s%c%d%c", "Thumb::Image::Height", 0,
|
g_string_append_printf(thum, "%s%c%d%c", THUMB_IMAGE_HEIGHT, 0,
|
||||||
cairo_image_surface_get_height(surface), 0);
|
cairo_image_surface_get_height(surface), 0);
|
||||||
|
|
||||||
// Without a CMM, no conversion is attempted.
|
// Without a CMM, no conversion is attempted.
|
||||||
if (sRGB) {
|
if (sRGB) {
|
||||||
g_string_append_printf(
|
g_string_append_printf(
|
||||||
thum, "%s%c%s%c", "Thumb::ColorSpace", 0, "sRGB", 0);
|
thum, "%s%c%s%c", THUMB_COLORSPACE, 0, THUMB_COLORSPACE_SRGB, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int use = max_size; use >= FIV_THUMBNAIL_SIZE_MIN; use--) {
|
for (int use = max_size; use >= FIV_THUMBNAIL_SIZE_MIN; use--) {
|
||||||
|
@ -285,14 +295,62 @@ fiv_thumbnail_produce(GFile *target, FivThumbnailSize max_size, GError **error)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
check_wide_thumbnail_texts(GBytes *thum, const gchar *target, time_t mtime,
|
||||||
|
bool *sRGB)
|
||||||
|
{
|
||||||
|
gsize len = 0;
|
||||||
|
const gchar *s = g_bytes_get_data(thum, &len), *end = s + len;
|
||||||
|
|
||||||
|
// Similar to PNG below, but we're following our own specification.
|
||||||
|
const gchar *key = NULL, *nul = NULL;
|
||||||
|
bool have_uri = false, have_mtime = false;
|
||||||
|
for (; (nul = memchr(s, '\0', end - s)); s = ++nul) {
|
||||||
|
if (!key) {
|
||||||
|
key = s;
|
||||||
|
continue;
|
||||||
|
} else if (!strcmp(key, THUMB_URI)) {
|
||||||
|
have_uri = true;
|
||||||
|
if (strcmp(target, s))
|
||||||
|
return false;
|
||||||
|
} else if (!strcmp(key, THUMB_MTIME)) {
|
||||||
|
have_mtime = true;
|
||||||
|
if (atol(s) != mtime)
|
||||||
|
return false;
|
||||||
|
} else if (!strcmp(key, THUMB_COLORSPACE))
|
||||||
|
*sRGB = !strcmp(s, THUMB_COLORSPACE_SRGB);
|
||||||
|
|
||||||
|
key = NULL;
|
||||||
|
}
|
||||||
|
return have_uri && have_mtime;
|
||||||
|
}
|
||||||
|
|
||||||
static cairo_surface_t *
|
static cairo_surface_t *
|
||||||
read_wide_thumbnail(
|
read_wide_thumbnail(
|
||||||
const gchar *path, const gchar *uri, time_t mtime, GError **error)
|
const gchar *path, const gchar *uri, time_t mtime, GError **error)
|
||||||
{
|
{
|
||||||
// TODO(p): Validate fiv_io_key_thum.
|
cairo_surface_t *surface = fiv_io_open(path, NULL, FALSE, error);
|
||||||
(void) uri;
|
if (!surface)
|
||||||
(void) mtime;
|
return NULL;
|
||||||
return fiv_io_open(path, NULL, FALSE, error);
|
|
||||||
|
bool sRGB = false;
|
||||||
|
GBytes *thum = cairo_surface_get_user_data(surface, &fiv_io_key_thum);
|
||||||
|
if (!thum) {
|
||||||
|
set_error(error, "not a thumbnail");
|
||||||
|
} else if (!check_wide_thumbnail_texts(thum, uri, mtime, &sRGB)) {
|
||||||
|
set_error(error, "mismatch");
|
||||||
|
} else {
|
||||||
|
// TODO(p): Add a function or a non-valueless define to check
|
||||||
|
// for CMM presence, then remove this ifdef.
|
||||||
|
#ifdef HAVE_LCMS2
|
||||||
|
if (!sRGB)
|
||||||
|
mark_thumbnail_lq(surface);
|
||||||
|
#endif // HAVE_LCMS2
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_surface_destroy(surface);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -306,12 +364,12 @@ check_spng_thumbnail_texts(struct spng_text *texts, uint32_t texts_len,
|
||||||
bool need_uri = true, need_mtime = true;
|
bool need_uri = true, need_mtime = true;
|
||||||
for (uint32_t i = 0; i < texts_len; i++) {
|
for (uint32_t i = 0; i < texts_len; i++) {
|
||||||
struct spng_text *text = texts + i;
|
struct spng_text *text = texts + i;
|
||||||
if (!strcmp(text->keyword, "Thumb::URI")) {
|
if (!strcmp(text->keyword, THUMB_URI)) {
|
||||||
need_uri = false;
|
need_uri = false;
|
||||||
if (strcmp(target, text->text))
|
if (strcmp(target, text->text))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!strcmp(text->keyword, "Thumb::MTime")) {
|
if (!strcmp(text->keyword, THUMB_MTIME)) {
|
||||||
need_mtime = false;
|
need_mtime = false;
|
||||||
if (atol(text->text) != mtime)
|
if (atol(text->text) != mtime)
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in New Issue