aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.adoc4
-rw-r--r--fiv-io.c42
-rw-r--r--fiv-io.h2
-rw-r--r--fiv-view.c17
4 files changed, 50 insertions, 15 deletions
diff --git a/README.adoc b/README.adoc
index b364e4f..f133222 100644
--- a/README.adoc
+++ b/README.adoc
@@ -5,8 +5,8 @@ fastiv
raw photos, HEIC, AVIF, WebP, SVG, X11 cursors and TIFF, or whatever gdk-pixbuf
loads.
-Its development status can be summarized as '`beta`'. E.g., colour management
-is a bit incomplete, and certain GIFs animate wrong.
+Its development status can be summarized as '`beta`'.
+E.g., certain GIFs animate wrong.
Non-goals
---------
diff --git a/fiv-io.c b/fiv-io.c
index c08d121..2ab97f1 100644
--- a/fiv-io.c
+++ b/fiv-io.c
@@ -206,6 +206,24 @@ fiv_io_profile_new_from_bytes(GBytes *bytes)
return fiv_io_profile_new(p, len);
}
+static GBytes *
+fiv_io_profile_to_bytes(FivIoProfile profile)
+{
+#ifdef HAVE_LCMS2
+ cmsUInt32Number len = 0;
+ (void) cmsSaveProfileToMem(profile, NULL, &len);
+ gchar *data = g_malloc0(len);
+ if (!cmsSaveProfileToMem(profile, data, &len)) {
+ g_free(data);
+ return NULL;
+ }
+ return g_bytes_new_take(data, len);
+#else
+ (void) profile;
+ return NULL;
+#endif
+}
+
void
fiv_io_profile_free(FivIoProfile self)
{
@@ -2490,10 +2508,8 @@ encode_webp_animation(WebPMux *mux, cairo_surface_t *page)
}
static gboolean
-transfer_metadata(WebPMux *mux, const char *fourcc, cairo_surface_t *page,
- const cairo_user_data_key_t *kind)
+set_metadata(WebPMux *mux, const char *fourcc, GBytes *data)
{
- GBytes *data = cairo_surface_get_user_data(page, kind);
if (!data)
return TRUE;
@@ -2504,8 +2520,8 @@ transfer_metadata(WebPMux *mux, const char *fourcc, cairo_surface_t *page,
}
gboolean
-fiv_io_save(cairo_surface_t *page, cairo_surface_t *frame, const gchar *path,
- GError **error)
+fiv_io_save(cairo_surface_t *page, cairo_surface_t *frame, FivIoProfile target,
+ const gchar *path, GError **error)
{
g_return_val_if_fail(page != NULL, FALSE);
g_return_val_if_fail(path != NULL, FALSE);
@@ -2519,9 +2535,16 @@ fiv_io_save(cairo_surface_t *page, cairo_surface_t *frame, const gchar *path,
else
ok = encode_webp_animation(mux, page);
- ok = ok && transfer_metadata(mux, "EXIF", page, &fiv_io_key_exif);
- ok = ok && transfer_metadata(mux, "ICCP", page, &fiv_io_key_icc);
- ok = ok && transfer_metadata(mux, "XMP ", page, &fiv_io_key_xmp);
+ ok = ok && set_metadata(mux, "EXIF",
+ cairo_surface_get_user_data(page, &fiv_io_key_exif));
+ ok = ok && set_metadata(mux, "ICCP",
+ cairo_surface_get_user_data(page, &fiv_io_key_icc));
+ ok = ok && set_metadata(mux, "XMP ",
+ cairo_surface_get_user_data(page, &fiv_io_key_xmp));
+
+ GBytes *iccp = NULL;
+ if (ok && target && (iccp = fiv_io_profile_to_bytes(target)))
+ ok = set_metadata(mux, "ICCP", iccp);
WebPData assembled = {};
WebPDataInit(&assembled);
@@ -2531,6 +2554,9 @@ fiv_io_save(cairo_surface_t *page, cairo_surface_t *frame, const gchar *path,
ok = g_file_set_contents(
path, (const gchar *) assembled.bytes, assembled.size, error);
+ if (iccp)
+ g_bytes_unref(iccp);
+
WebPMuxDelete(mux);
WebPDataClear(&assembled);
return ok;
diff --git a/fiv-io.h b/fiv-io.h
index f2cfecd..69e3c90 100644
--- a/fiv-io.h
+++ b/fiv-io.h
@@ -79,7 +79,7 @@ int fiv_io_filecmp(GFile *f1, GFile *f2);
/// Requires libwebp.
/// If no exact frame is specified, this potentially creates an animation.
gboolean fiv_io_save(cairo_surface_t *page, cairo_surface_t *frame,
- const gchar *path, GError **error);
+ FivIoProfile target, const gchar *path, GError **error);
// --- Metadata ----------------------------------------------------------------
diff --git a/fiv-view.c b/fiv-view.c
index 3f6357f..d03e9ee 100644
--- a/fiv-view.c
+++ b/fiv-view.c
@@ -779,9 +779,18 @@ print(FivView *self)
}
static gboolean
-save_as(FivView *self, gboolean frame)
+save_as(FivView *self, cairo_surface_t *frame)
{
GtkWindow *window = get_toplevel(GTK_WIDGET(self));
+ FivIoProfile target = NULL;
+ if (self->enable_cms && (target = self->screen_cms_profile)) {
+ GtkWidget *dialog = gtk_message_dialog_new(window, GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, "%s",
+ "Color management overrides attached color profiles.");
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+ }
+
GtkWidget *dialog = gtk_file_chooser_dialog_new(
frame ? "Save frame as" : "Save page as",
window, GTK_FILE_CHOOSER_ACTION_SAVE,
@@ -834,7 +843,7 @@ save_as(FivView *self, gboolean frame)
GError *error = NULL;
#ifdef HAVE_LIBWEBP
if (gtk_file_chooser_get_filter(chooser) == webp_filter)
- fiv_io_save(self->page, frame ? self->frame : NULL, path, &error);
+ fiv_io_save(self->page, frame, target, path, &error);
else
#endif // HAVE_LIBWEBP
fiv_io_save_metadata(self->page, path, &error);
@@ -1027,7 +1036,7 @@ fiv_view_key_press_event(GtkWidget *widget, GdkEventKey *event)
case GDK_KEY_s:
return command(self, FIV_VIEW_COMMAND_SAVE_PAGE);
case GDK_KEY_S:
- return save_as(self, TRUE);
+ return save_as(self, self->frame);
}
}
if (state == GDK_MOD1_MASK) {
@@ -1320,7 +1329,7 @@ fiv_view_command(FivView *self, FivViewCommand command)
break; case FIV_VIEW_COMMAND_PRINT:
print(self);
break; case FIV_VIEW_COMMAND_SAVE_PAGE:
- save_as(self, FALSE);
+ save_as(self, NULL);
break; case FIV_VIEW_COMMAND_INFO:
info(self);