libopenjp2
For displaying JP2 images
+ libraw 0.20
+ For displaying CR3 images
+
yelp-tools
For creating the Help files
AC_SUBST(TIFF_CFLAGS)
AC_SUBST(TIFF_LIBS)
+# libraw support
+# ----------------------------------------------------------------------
+
+AC_ARG_ENABLE([raw],
+ AC_HELP_STRING([--disable-raw], [disable LibRaw support]),
+ [libraw=$enableval], [libraw=auto])
+
+if test "x${libraw}" != "xno"; then
+ PKG_CHECK_MODULES(RAW, [libraw >= 0.20],
+ [
+ HAVE_RAW=yes
+ AC_DEFINE(HAVE_RAW, 1, [define to enable libraw support])
+ ],
+ [
+ HAVE_RAW=no
+ AC_MSG_WARN([$RAW_PKG_ERRORS])
+ ])
+else
+ HAVE_RAW=disabled
+fi
+
+AM_CONDITIONAL(HAVE_RAW, [test "x$HAVE_RAW" = xyes])
+AC_SUBST(RAW_CFLAGS)
+AC_SUBST(RAW_LIBS)
+
# libffmpegthumbnailer support
# ----------------------------------------------------------------------
Gtk: $GTK_CFLAGS
Glib: $GLIB_CFLAGS
Thread: $GTHREAD_LIBS
- Others: $JPEG_LIBS $TIFF_LIBS $LCMS_LIBS $EXIV2_LIBS $CLUTTER_LIBS $CLUTTER_GTK_LIBS $LIBCHAMPLAIN_LIBS $LIBCHAMPLAIN_GTK_LIBS $LUA_LIBS
+ Others: $JPEG_LIBS $TIFF_LIBS $LCMS_LIBS $EXIV2_LIBS $CLUTTER_LIBS $CLUTTER_GTK_LIBS $LIBCHAMPLAIN_LIBS $LIBCHAMPLAIN_GTK_LIBS $LUA_LIBS $RAW_LIBS
Localization:
NLS support: $USE_NLS
WebP: $HAVE_WEBP
DjVu: $HAVE_DJVU
J2K: $HAVE_J2K
+ LibRaw: $HAVE_RAW
Documentation:
Doxygen: $DX_DOXYGEN
HAVE_LIRC=1 \
HAVE_LUA=1 \
HAVE_PDF=1 \
+ HAVE_RAW=1 \
HAVE_TIFF=1 \
HAVE_WEBP=1
image_load_psd.h\
image_load_j2k.c\
image_load_j2k.h\
+ image_load_libraw.c\
+ image_load_libraw.h\
image_load_svgz.c\
image_load_svgz.h\
image_load_ffmpegthumbnailer.c\
zonedetect.c \
zonedetect.h
-geeqie_LDADD = $(GTK_LIBS) $(GLIB_LIBS) $(INTLLIBS) $(JPEG_LIBS) $(TIFF_LIBS) $(LCMS_LIBS) $(EXIV2_LIBS) $(LIBCHAMPLAIN_LIBS) $(LIBCHAMPLAIN_GTK_LIBS) $(LUA_LIBS) $(CLUTTER_LIBS) $(CLUTTER_GTK_LIBS) $(FFMPEGTHUMBNAILER_LIBS) $(PDF_LIBS) $(HEIF_LIBS) $(WEBP_LIBS) $(DJVU_LIBS) $(J2K_LIBS)
+geeqie_LDADD = $(GTK_LIBS) $(GLIB_LIBS) $(INTLLIBS) $(JPEG_LIBS) $(TIFF_LIBS) $(LCMS_LIBS) $(EXIV2_LIBS) $(LIBCHAMPLAIN_LIBS) $(LIBCHAMPLAIN_GTK_LIBS) $(LUA_LIBS) $(CLUTTER_LIBS) $(CLUTTER_GTK_LIBS) $(FFMPEGTHUMBNAILER_LIBS) $(PDF_LIBS) $(HEIF_LIBS) $(WEBP_LIBS) $(DJVU_LIBS) $(J2K_LIBS) $(RAW_LIBS)
EXTRA_DIST = \
$(extra_SLIK)
#include "image_load_collection.h"
#include "image_load_webp.h"
#include "image_load_j2k.h"
+#include "image_load_libraw.h"
#include "image_load_svgz.h"
#include "exif.h"
il->idle_read_loop_count = IMAGE_LOADER_IDLE_READ_LOOP_COUNT_DEFAULT;
il->read_buffer_size = IMAGE_LOADER_READ_BUFFER_SIZE_DEFAULT;
il->mapped_file = NULL;
+ il->preview = IMAGE_LOADER_PREVIEW_NONE;
il->requested_width = 0;
il->requested_height = 0;
DEBUG_1("Using custom jpeg loader");
image_loader_backend_set_jpeg(&il->backend);
}
+#ifndef HAVE_RAW
else
if (il->bytes_total >= 11 &&
(memcmp(il->mapped_file + 4, "ftypcrx", 7) == 0) &&
DEBUG_1("Using custom cr3 loader");
image_loader_backend_set_cr3(&il->backend);
}
+#endif
else
#endif
#ifdef HAVE_TIFF
ExifData *exif = exif_read_fd(il->fd);
if (options->thumbnails.use_exif)
+ {
il->mapped_file = exif_get_preview(exif, (guint *)&il->bytes_total, il->requested_width, il->requested_height);
+
+ if (il->mapped_file)
+ {
+ il->preview = IMAGE_LOADER_PREVIEW_EXIF;
+ }
+ }
else
+ {
il->mapped_file = exif_get_preview(exif, (guint *)&il->bytes_total, 0, 0); /* get the largest available preview image or NULL for normal images*/
+ if (il->mapped_file)
+ {
+ il->preview = IMAGE_LOADER_PREVIEW_EXIF;
+ }
+ }
+
+ /* If exiv2 does not find a thumbnail, try libraw (which may be slower) */
+ if (!il->mapped_file)
+ {
+ il->mapped_file = libraw_get_preview(il, (guint *)&il->bytes_total);
+
+ if (il->mapped_file)
+ {
+ il->preview = IMAGE_LOADER_PREVIEW_LIBRAW;
+ }
+ }
+
if (il->mapped_file)
{
- il->preview = TRUE;
DEBUG_1("Usable reduced size (preview) image loaded from file %s", il->fd->path);
}
exif_free_fd(il->fd, exif);
il->mapped_file = 0;
return FALSE;
}
- il->preview = FALSE;
+ il->preview = IMAGE_LOADER_PREVIEW_NONE;
}
return TRUE;
if (il->mapped_file)
{
- if (il->preview)
+ if (il->preview == IMAGE_LOADER_PREVIEW_EXIF)
{
exif_free_preview(il->mapped_file);
}
+ else if (il->preview == IMAGE_LOADER_PREVIEW_LIBRAW)
+ {
+ libraw_free_preview(il->mapped_file);
+ }
else
{
munmap(il->mapped_file, il->bytes_total);
ImageLoaderBackendFuncGetPageTotal get_page_total;
};
+typedef enum {
+ IMAGE_LOADER_PREVIEW_NONE = 0,
+ IMAGE_LOADER_PREVIEW_EXIF = 1,
+ IMAGE_LOADER_PREVIEW_LIBRAW = 2
+} ImageLoaderPreview;
+
//typedef struct _ImageLoader ImageLoader;
typedef struct _ImageLoaderClass ImageLoaderClass;
gsize bytes_read;
gsize bytes_total;
- gboolean preview;
+ ImageLoaderPreview preview;
gint requested_width;
gint requested_height;
--- /dev/null
+/*
+ * Copyright (C) 2021 The Geeqie Team
+ *
+ * Authors: Colin Clark
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/**
+ * @file
+ * This uses libraw to extract a thumbnail from a raw image. The exiv2 library
+ * does not (yet) extract thumbnails from .cr3 images.
+ * LibRaw seems to be slower than exiv2, so let exiv2 have priority.
+ */
+
+#include "main.h"
+
+#include "filefilter.h"
+#include "image-load.h"
+#include "image_load_libraw.h"
+
+#ifdef HAVE_RAW
+
+#include <libraw/libraw.h>
+#include <sys/mman.h>
+
+typedef struct _UnmapData UnmapData;
+struct _UnmapData
+{
+ guchar *ptr;
+ guchar *map_data;
+ size_t map_len;
+ libraw_data_t *lrdt;
+};
+
+static GList *libraw_unmap_list = 0;
+
+void libraw_free_preview(guchar *buf)
+{
+ GList *work = libraw_unmap_list;
+
+ while (work)
+ {
+ UnmapData *ud = (UnmapData *)work->data;
+ if (ud->ptr == buf)
+ {
+ munmap(ud->map_data, ud->map_len);
+ libraw_close(ud->lrdt);
+ libraw_unmap_list = g_list_remove_link(libraw_unmap_list, work);
+ g_free(ud);
+ return;
+ }
+ work = work->next;
+ }
+ g_assert_not_reached();
+}
+
+guchar *libraw_get_preview(ImageLoader *il, guint *data_len)
+{
+ libraw_data_t *lrdt;
+ int ret;
+ UnmapData *ud;
+ struct stat st;
+ guchar *map_data;
+ size_t map_len;
+ int fd;
+
+ if (!filter_file_class(il->fd->path, FORMAT_CLASS_RAWIMAGE)) return NULL;
+
+ fd = open(il->fd->path, O_RDONLY);
+ if (fd == -1)
+ {
+ return NULL;
+ }
+
+ if (fstat(fd, &st) == -1)
+ {
+ close(fd);
+ return NULL;
+ }
+
+ map_len = st.st_size;
+ map_data = (guchar *) mmap(0, map_len, PROT_READ, MAP_PRIVATE, fd, 0);
+ close(fd);
+
+ if (map_data == MAP_FAILED)
+ {
+ return NULL;
+ }
+
+ lrdt = libraw_init(0);
+ if (!lrdt)
+ {
+ log_printf("Warning: Cannot create libraw handle\n");
+ return NULL;
+ }
+
+ ret = libraw_open_buffer(lrdt, (void *)map_data, map_len);
+ if (ret == LIBRAW_SUCCESS)
+ {
+ ret = libraw_unpack_thumb(lrdt);
+ if (ret == LIBRAW_SUCCESS)
+ {
+ il->mapped_file = (guchar *)lrdt->thumbnail.thumb;
+ *data_len = lrdt->thumbnail.tlength;
+
+ ud = g_new(UnmapData, 1);
+ ud->ptr =(guchar *)lrdt->thumbnail.thumb;
+ ud->map_data = map_data;
+ ud->map_len = lrdt->thumbnail.tlength;
+ ud->lrdt = lrdt;
+
+ libraw_unmap_list = g_list_prepend(libraw_unmap_list, ud);
+
+ return (guchar *)lrdt->thumbnail.thumb;
+ }
+ }
+
+ libraw_close(lrdt);
+
+ return NULL;
+}
+
+#else /* !define HAVE_RAW */
+
+void libraw_free_preview(guchar *buf)
+{
+}
+
+guchar *libraw_get_preview(ImageLoader *il, guint *data_len)
+{
+ return NULL;
+}
+
+#endif
+
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
--- /dev/null
+/*
+ * Copyright (C) 2021 The Geeqie Team
+ *
+ * Author: Colin Clark
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef IMAGE_LOAD_RAW_H
+#define IMAGE_LOAD_RAW_H
+
+guchar *libraw_get_preview(ImageLoader *il, guint *data_len);
+void libraw_free_preview(guchar *buf);
+
+#endif
+
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
#!/bin/bash
-version="2019-12-30"
+version="2021-05-10"
description=$'
Geeqie is an image viewer.
This script will download, compile, and install Geeqie on Debian-based systems.
"libdjvulibre-dev"
"libopenjp2 (for JP2 images)"
"libopenjp2-7-dev"
+"libraw (for CR3 images)"
+"libraw-dev"
)
# Optional for GTK3 only