#include "exif.h"
#include "metadata.h"
#include "histogram.h"
+#include "history_list.h"
#include "image-load.h"
#include "image-overlay.h"
#include "layout.h"
static GList *image_list = NULL;
-static void image_update_title(ImageWindow *imd);
+void image_update_title(ImageWindow *imd);
static void image_read_ahead_start(ImageWindow *imd);
static void image_cache_set(ImageWindow *imd, FileData *fd);
*-------------------------------------------------------------------
*/
-static void image_update_title(ImageWindow *imd)
+void image_update_title(ImageWindow *imd)
{
gchar *title = NULL;
gchar *zoom = NULL;
ImageWindow *imd = (ImageWindow *)data;
if (imd->cm) color_man_correct_region(imd->cm, *pixbuf, x, y, w, h);
if (imd->desaturate) pixbuf_desaturate_rect(*pixbuf, x, y, w, h);
-
+ if (imd->overunderexposed) pixbuf_highlight_overunderexposed(*pixbuf, x, y, w, h);
}
void image_alter_orientation(ImageWindow *imd, FileData *fd_n, AlterType type)
else
if (options->metadata.write_orientation)
{
- orientation = metadata_read_int(fd_n, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT);
+ if (g_strcmp0(imd->image_fd->format_name, "heif") == 0)
+ {
+ orientation = EXIF_ORIENTATION_TOP_LEFT;
+ }
+ else
+ {
+ orientation = metadata_read_int(fd_n, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT);
+ }
}
}
if (orientation != (fd_n->exif_orientation ? fd_n->exif_orientation : 1))
{
- if (!options->metadata.write_orientation)
+ if (g_strcmp0(fd_n->format_name, "heif") != 0)
+ {
+ if (!options->metadata.write_orientation)
+ {
+ /* user_orientation does not work together with options->metadata.write_orientation,
+ use either one or the other.
+ we must however handle switching metadata.write_orientation on and off, therefore
+ we just disable referencing new fd's, not unreferencing the old ones
+ */
+ if (fd_n->user_orientation == 0) file_data_ref(fd_n);
+ fd_n->user_orientation = orientation;
+ }
+ }
+ else
{
- /* user_orientation does not work together with options->metadata.write_orientation,
- use either one or the other.
- we must however handle switching metadata.write_orientation on and off, therefore
- we just disable referencing new fd's, not unreferencing the old ones
- */
if (fd_n->user_orientation == 0) file_data_ref(fd_n);
fd_n->user_orientation = orientation;
}
fd_n->user_orientation = 0;
}
- if (options->metadata.write_orientation)
+ if (g_strcmp0(fd_n->format_name, "heif") != 0)
{
- if (type == ALTER_NONE)
- {
- metadata_write_revert(fd_n, ORIENTATION_KEY);
- }
- else
+ if (options->metadata.write_orientation)
{
- metadata_write_int(fd_n, ORIENTATION_KEY, orientation);
+ if (type == ALTER_NONE)
+ {
+ metadata_write_revert(fd_n, ORIENTATION_KEY);
+ }
+ else
+ {
+ metadata_write_int(fd_n, ORIENTATION_KEY, orientation);
+ }
}
}
void image_set_desaturate(ImageWindow *imd, gboolean desaturate)
{
imd->desaturate = desaturate;
- if (imd->cm || imd->desaturate)
+ if (imd->cm || imd->desaturate || imd->overunderexposed)
pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, image_post_process_tile_color_cb, (gpointer) imd, (imd->cm != NULL) );
else
pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, NULL, NULL, TRUE);
return imd->desaturate;
}
+void image_set_overunderexposed(ImageWindow *imd, gboolean overunderexposed)
+{
+ imd->overunderexposed = overunderexposed;
+ if (imd->cm || imd->desaturate || imd->overunderexposed)
+ pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, image_post_process_tile_color_cb, (gpointer) imd, (imd->cm != NULL) );
+ else
+ pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, NULL, NULL, TRUE);
+ pixbuf_renderer_set_orientation((PixbufRenderer *)imd->pr, imd->orientation);
+}
+
+gboolean image_get_overunderexposed(ImageWindow *imd)
+{
+ return imd->overunderexposed;
+}
+
+void image_set_ignore_alpha(ImageWindow *imd, gboolean ignore_alpha)
+{
+ pixbuf_renderer_set_ignore_alpha((PixbufRenderer *)imd->pr, ignore_alpha);
+}
+
/*
*-------------------------------------------------------------------
* read ahead (prebuffer)
break;
case FORMAT_CLASS_VIDEO:
pixbuf = pixbuf_inline(PIXBUF_INLINE_VIDEO);
+ break;
case FORMAT_CLASS_COLLECTION:
pixbuf = pixbuf_inline(PIXBUF_INLINE_COLLECTION);
break;
- case FORMAT_CLASS_PDF:
+ case FORMAT_CLASS_DOCUMENT:
pixbuf = pixbuf_inline(PIXBUF_INLINE_ICON_PDF);
break;
+ case FORMAT_CLASS_ARCHIVE:
+ pixbuf = pixbuf_inline(PIXBUF_INLINE_ARCHIVE);
+ break;
default:
pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN);
}
pr = PIXBUF_RENDERER(imd->pr);
pr->zoom = zoom; /* store the zoom, needed by the loader */
+ /* Disable 2-pass for GIFs. Animated GIFs can flicker when enabled
+ * Reduce quality to worst but fastest to avoid dropped frames */
+ if (g_ascii_strcasecmp(imd->image_fd->extension, ".GIF") == 0)
+ {
+ g_object_set(G_OBJECT(imd->pr), "zoom_2pass", FALSE, NULL);
+ g_object_set(G_OBJECT(imd->pr), "zoom_quality", GDK_INTERP_NEAREST, NULL);
+ }
+
+
if (image_load_begin(imd, imd->image_fd))
{
imd->unknown = FALSE;
static gboolean image_scroll_cb(GtkWidget *widget, GdkEventScroll *event, gpointer data)
{
ImageWindow *imd = data;
+ gboolean in_lw = FALSE;
+ gint i = 0;
+ LayoutWindow *lw = NULL;
- if (imd->func_scroll &&
- event && event->type == GDK_SCROLL)
+ if (imd->func_scroll && event && event->type == GDK_SCROLL)
{
- imd->func_scroll(imd, event, imd->data_scroll);
- return TRUE;
+ layout_valid(&lw);
+ /* check if the image is in a layout window */
+ for (i = 0; i < MAX_SPLIT_IMAGES; i++)
+ {
+ if (imd == lw->split_images[i])
+ {
+ in_lw = TRUE;
+ break;
+ }
+ }
+
+ if (in_lw)
+ {
+ if (lw->options.split_pane_sync)
+ {
+ for (i = 0; i < MAX_SPLIT_IMAGES; i++)
+ {
+ if (lw->split_images[i])
+ {
+ layout_image_activate(lw, i, FALSE);
+ imd->func_scroll(lw->split_images[i], event, lw->split_images[i]->data_scroll);
+ }
+ }
+ }
+ else
+ {
+ imd->func_scroll(imd, event, imd->data_scroll);
+ }
+ return TRUE;
+ }
+ else
+ {
+ imd->func_scroll(imd, event, imd->data_scroll);
+ return TRUE;
+ }
}
return FALSE;
lw = layout_find_by_image(imd);
- if (!(options->image.fit_window_to_image && lw && lw->options.tools_float)) window = NULL;
+ if (!(options->image.fit_window_to_image && lw && (lw->options.tools_float || lw->options.tools_hidden))) window = NULL;
pixbuf_renderer_set_parent((PixbufRenderer *)imd->pr, (GtkWindow *)window);
void image_change_pixbuf(ImageWindow *imd, GdkPixbuf *pixbuf, gdouble zoom, gboolean lazy)
{
+ LayoutWindow *lw;
StereoPixbufData stereo_data = STEREO_PIXBUF_DEFAULT;
/* read_exif and similar functions can actually notice that the file has changed and trigger
a notification that removes the pixbuf from cache and unrefs it. Therefore we must ref it
}
else if (options->image.exif_rotate_enable)
{
- imd->orientation = metadata_read_int(imd->image_fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT);
- imd->image_fd->exif_orientation = imd->orientation;
+ if (g_strcmp0(imd->image_fd->format_name, "heif") == 0)
+ {
+ imd->orientation = EXIF_ORIENTATION_TOP_LEFT;
+ imd->image_fd->exif_orientation = imd->orientation;
+ }
+ else
+ {
+ imd->orientation = metadata_read_int(imd->image_fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT);
+ imd->image_fd->exif_orientation = imd->orientation;
+ }
}
}
if (pixbuf) g_object_unref(pixbuf);
- if (imd->color_profile_enable)
+ /* Color correction takes too much time for an animated gif */
+ lw = layout_find_by_image(imd);
+ if (imd->color_profile_enable && lw && !lw->animation)
{
- image_post_process_color(imd, 0, FALSE); /* TODO: error handling */
+ image_post_process_color(imd, 0, FALSE); /** @todo error handling */
}
- if (imd->cm || imd->desaturate)
+ if (imd->cm || imd->desaturate || imd->overunderexposed)
pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, image_post_process_tile_color_cb, (gpointer) imd, (imd->cm != NULL) );
image_state_set(imd, IMAGE_STATE_IMAGE);
collection_table_unselect_all(cw->table);
collection_table_select(cw->table,info);
}
+
+ if (info->fd)
+ {
+ image_chain_append_end(info->fd->path);
+ }
}
CollectionData *image_get_collection(ImageWindow *imd, CollectInfo **info)
pixbuf_renderer_move(PIXBUF_RENDERER(imd->pr), PIXBUF_RENDERER(source->pr));
- if (imd->cm || imd->desaturate)
+ if (imd->cm || imd->desaturate || imd->overunderexposed)
pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, image_post_process_tile_color_cb, (gpointer) imd, (imd->cm != NULL) );
else
pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, NULL, NULL, TRUE);
pixbuf_renderer_copy(PIXBUF_RENDERER(imd->pr), PIXBUF_RENDERER(source->pr));
- if (imd->cm || imd->desaturate)
+ if (imd->cm || imd->desaturate || imd->overunderexposed)
pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, image_post_process_tile_color_cb, (gpointer) imd, (imd->cm != NULL) );
else
pixbuf_renderer_set_post_process_func((PixbufRenderer *)imd->pr, NULL, NULL, TRUE);
if ((type & NOTIFY_REREAD) && fd == imd->image_fd)
{
/* there is no need to reload on NOTIFY_CHANGE,
- modified files should be detacted anyway and NOTIFY_REREAD should be recieved
+ modified files should be detacted anyway and NOTIFY_REREAD should be received
or they are removed from the filelist completely on "move" and "delete"
*/
DEBUG_1("Notify image: %s %04x", fd->path, type);
void image_background_set_color_from_options(ImageWindow *imd, gboolean fullscreen)
{
GdkColor *color = NULL;
+#if GTK_CHECK_VERSION(3,0,0)
+ GdkColor theme_color;
+ GdkRGBA bg_color;
+ GtkStyleContext *style_context;
+ LayoutWindow *lw = NULL;
+#endif
if ((options->image.use_custom_border_color && !fullscreen) ||
(options->image.use_custom_border_color_in_fullscreen && fullscreen))
color = &options->image.border_color;
}
+#if GTK_CHECK_VERSION(3,0,0)
+ else
+ {
+ if (!layout_valid(&lw)) return;
+
+ style_context = gtk_widget_get_style_context(lw->window);
+ gtk_style_context_get_background_color(style_context, GTK_STATE_FLAG_NORMAL, &bg_color);
+
+ theme_color.red = bg_color.red * 65535;
+ theme_color.green = bg_color.green * 65535;
+ theme_color.blue = bg_color.blue * 65535;
+
+ color = &theme_color;
+ }
+#endif
+
image_background_set_color(imd, color);
}
if (frame)
{
imd->frame = gtk_frame_new(NULL);
+ DEBUG_NAME(imd->frame);
g_object_ref(imd->pr);
if (imd->has_frame != -1) gtk_container_remove(GTK_CONTAINER(imd->widget), imd->pr);
gtk_container_add(GTK_CONTAINER(imd->frame), imd->pr);
imd->orientation = 1;
imd->pr = GTK_WIDGET(pixbuf_renderer_new());
+ DEBUG_NAME(imd->pr);
image_options_set(imd);
imd->widget = gtk_vbox_new(0, 0);
+ DEBUG_NAME(imd->widget);
image_set_frame(imd, frame);