diff --git a/DefineOptions.cmake b/DefineOptions.cmake
index 9fb7080d43ba..0b0e3d9de54c 100644
--- a/DefineOptions.cmake
+++ b/DefineOptions.cmake
@@ -23,6 +23,7 @@ option(USE_AVIF "Enable AVIF support" ON)
option(USE_HEIF "Enable HEIF/HEIC support" ON)
option(USE_XCF "Enable XCF support" ON)
option(USE_ISOBMFF "Enable ISOBMFF support" ON)
+option(USE_LIBRAW "Enable LibRAW support" ON)
option(BUILD_CMSTEST "Build a test program to check your system's color management setup" ON)
option(USE_OPENEXR "Enable OpenEXR support" ON)
option(BUILD_PRINT "Build the print module" ON)
diff --git a/cmake/modules/Findlibraw.cmake b/cmake/modules/Findlibraw.cmake
new file mode 100644
index 000000000000..e767485e3947
--- /dev/null
+++ b/cmake/modules/Findlibraw.cmake
@@ -0,0 +1,51 @@
+#.rst:
+# Findlibraw
+# -------
+#
+# Try to find libraw on a Unix system.
+#
+# This will define the following variables:
+#
+# ``libraw_FOUND``
+# True if (the requested version of) libraw is available
+# ``libraw_VERSION``
+# The version of libraw
+# ``libraw_LIBRARIES``
+# This should be passed to target_compile_options() if the target is not
+# used for linking
+# ``libraw_INCLUDE_DIRS``
+# This should be passed to target_include_directories() if the target is not
+# used for linking
+# ``libraw_DEFINITIONS``
+# This should be passed to target_compile_options() if the target is not
+# used for linking
+
+find_package(PkgConfig)
+pkg_check_modules(PKG_libraw QUIET raw)
+
+set(libraw_VERSION ${PKG_libraw_VERSION})
+set(libraw_DEFINITIONS ${PKG_libraw_CFLAGS_OTHER})
+
+find_path(libraw_INCLUDE_DIR
+ NAMES libraw/libraw.h
+ HINTS ${PKG_libraw_INCLUDE_DIRS}
+)
+
+find_library(libraw_LIBRARY
+ NAMES raw
+ HINTS ${PKG_libraw_LIBRARY_DIRS}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(libraw
+ FOUND_VAR libraw_FOUND
+ REQUIRED_VARS libraw_LIBRARY
+ libraw_INCLUDE_DIR
+ VERSION_VAR libraw_VERSION
+)
+
+set(libraw_INCLUDE_DIRS ${libraw_INCLUDE_DIR})
+set(libraw_LIBRARIES ${libraw_LIBRARY})
+
+mark_as_advanced(libraw_INCLUDE_DIR)
+mark_as_advanced(libraw_LIBRARY)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 72e534700dee..450bf25b497c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -382,6 +382,16 @@ if(USE_HEIF)
endif()
endif()
+if (USE_LIBRAW)
+ find_package(libraw 0.20.2)
+ if (libraw_FOUND)
+ list(APPEND LIBS ${libraw_LIBRARY})
+ add_definitions(-DHAVE_LIBRAW=1)
+ list(APPEND SOURCES "common/imageio_libraw.c")
+ set(DT_SUPPORTED_EXTENSIONS ${DT_SUPPORTED_EXTENSIONS} libraw CACHE INTERNAL "")
+ endif()
+endif()
+
if(USE_LENSFUN)
find_package(LensFun)
if(LensFun_FOUND)
diff --git a/src/common/image.h b/src/common/image.h
index 98ce363a8c7f..705e40326ed0 100644
--- a/src/common/image.h
+++ b/src/common/image.h
@@ -155,7 +155,8 @@ typedef enum dt_image_loader_t
LOADER_AVIF = 11,
LOADER_IM = 12,
LOADER_HEIF = 13,
- LOADER_COUNT = 14, // keep last
+ LOADER_LIBRAW = 14,
+ LOADER_COUNT = 15, // keep last
} dt_image_loader_t;
static const struct
diff --git a/src/common/imageio.c b/src/common/imageio.c
index e6b18b61f01e..f14b579bd619 100644
--- a/src/common/imageio.c
+++ b/src/common/imageio.c
@@ -48,6 +48,7 @@
#ifdef HAVE_LIBHEIF
#include "common/imageio_heif.h"
#endif
+#include "common/imageio_libraw.h"
#include "common/mipmap_cache.h"
#include "common/styles.h"
#include "control/conf.h"
@@ -1219,6 +1220,10 @@ dt_imageio_retval_t dt_imageio_open(dt_image_t *img, // non-const
ret = dt_imageio_open_rawspeed(img, filename, buf);
}
+ /* fallback that tries to open file via LibRAW to support Canon CR3 */
+ if(ret != DT_IMAGEIO_OK && ret != DT_IMAGEIO_CACHE_FULL)
+ ret = dt_imageio_open_libraw(img, filename, buf);
+
/* fallback that tries to open file via GraphicsMagick */
if(ret != DT_IMAGEIO_OK && ret != DT_IMAGEIO_CACHE_FULL)
ret = dt_imageio_open_exotic(img, filename, buf);
diff --git a/src/common/imageio_libraw.c b/src/common/imageio_libraw.c
new file mode 100644
index 000000000000..fceb445fbf71
--- /dev/null
+++ b/src/common/imageio_libraw.c
@@ -0,0 +1,87 @@
+/*
+ This file is part of darktable,
+ Copyright (C) 2021 darktable developers.
+
+ darktable 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 3 of the License, or
+ (at your option) any later version.
+
+ darktable 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 darktable. If not, see .
+*/
+
+#ifdef HAVE_LIBRAW
+#include "common/darktable.h"
+#include "imageio.h"
+#include "imageio_gm.h"
+#include "develop/develop.h"
+#include "common/exif.h"
+#include "common/colorspaces.h"
+#include "control/conf.h"
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+
+/* LibRAW is expected to read only new canon CR3 files */
+
+static gboolean _supported_image(const gchar *filename)
+{
+ const char *extensions_whitelist[] = { "cr3", NULL };
+ gboolean supported = FALSE;
+ char *ext = g_strrstr(filename, ".");
+ if(!ext) return FALSE;
+ ext++;
+ for(const char **i = extensions_whitelist; *i != NULL; i++)
+ if(!g_ascii_strncasecmp(ext, *i, strlen(*i)))
+ {
+ supported = TRUE;
+ break;
+ }
+ return supported;
+}
+
+
+dt_imageio_retval_t dt_imageio_open_libraw(dt_image_t *img, const char *filename, dt_mipmap_buffer_t *mbuf)
+{
+ int err = DT_IMAGEIO_FILE_CORRUPTED;
+
+ if(!_supported_image(filename)) return DT_IMAGEIO_FILE_CORRUPTED;
+
+ if(!img->exif_inited) (void)dt_exif_read(img, filename);
+
+ libraw_data_t *raw_data = libraw_init(0);
+
+ if(!libraw_open_file(raw_data, filename))
+ goto error;
+
+ img->buf_dsc.cst = iop_cs_RAW;
+ img->flags |= DT_IMAGE_4BAYER;
+ img->flags &= ~DT_IMAGE_LDR;
+ img->flags |= DT_IMAGE_RAW;
+ img->loader = LOADER_LIBRAW;
+
+ libraw_close(raw_data);
+
+ return DT_IMAGEIO_OK;
+
+error:
+ libraw_close(raw_data);
+ return err;
+}
+#endif
+
+// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
+// vim: shiftwidth=2 expandtab tabstop=2 cindent
+// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
diff --git a/src/common/imageio_libraw.h b/src/common/imageio_libraw.h
new file mode 100644
index 000000000000..f50dabd7b634
--- /dev/null
+++ b/src/common/imageio_libraw.h
@@ -0,0 +1,38 @@
+/*
+ This file is part of darktable,
+ Copyright (C) 2021 darktable developers.
+
+ darktable 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 3 of the License, or
+ (at your option) any later version.
+
+ darktable 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 darktable. If not, see .
+*/
+
+#ifndef DT_IMAGEIO_LIBRAW_H
+#define DT_IMAGEIO_LIBRAW_H
+
+#include "common/image.h"
+#include "common/mipmap_cache.h"
+
+#ifdef HAVE_LIBRAW
+dt_imageio_retval_t dt_imageio_open_libraw(dt_image_t *img, const char *filename, dt_mipmap_buffer_t *buf);
+#else
+inline dt_imageio_retval_t dt_imageio_open_libraw(dt_image_t *img, const char *filename,
+ dt_mipmap_buffer_t *buf)
+{
+ return DT_IMAGEIO_FILE_NOT_FOUND;
+}
+#endif
+
+#endif
+// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
+// vim: shiftwidth=2 expandtab tabstop=2 cindent
+// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;