{ lib, stdenv, autoPatchelfHook, boost186, cmake, copyDesktopItems, imagemagick, fetchpatch, fetchzip, killall, libjpeg, libpng, libtiff, libtool, libusb1, makeDesktopItem, qtbase, wrapQtAppsHook, withGui ? true, withNonFreePlugins ? false, }: let pname = "epsonscan2"; description = "Epson Scan 2 scanner driver for many modern Epson scanners and multifunction printers"; # Epson updates projects without changing their version numbers. # There can be multiple different packages identified by the same #version, so we also tag them with the month and year shown in # the Epson download page. version = "6.7.70.0-01-2025"; system = stdenv.hostPlatform.system; src = fetchzip { url = "https://download3.ebz.epson.net/dsc/f/03/00/16/60/70/c7fc14e41ec84255008c6125b63bcac40f55e11c/epsonscan2-6.7.70.0-1.src.tar.gz"; hash = "sha256-WvNBy5hAxNJfwgjBR5VGaXuyTCK2YEiD3i7SMDl3U/U="; }; bundle = { "x86_64-linux" = fetchzip { name = "${pname}-bundle"; url = "https://download3.ebz.epson.net/dsc/f/03/00/16/14/38/7b1780ace96e2c6033bbb667c7f3ed281e4e9f38/epsonscan2-bundle-6.7.70.0.x86_64.deb.tar.gz"; hash = "sha256-fPNNFgW/VU/YG+jjmSvPZ0WsHibsXY1TNp164GxLHKw="; }; } ."${system}" or (throw "Unsupported system: ${system}"); in stdenv.mkDerivation { inherit pname src version; patches = [ ./build.patch ./gcc14.patch (fetchpatch { url = "https://raw.githubusercontent.com/flathub/net.epson.epsonscan2/a489ac2f8cbd03afeda86673930cc17663c31a53/patches/0002-Fix-crash.patch"; hash = "sha256-rNsFnHq//CJcIZl0M6RLRkIY3YhnJZbikO8SeeC2ktg="; }) (fetchpatch { url = "https://raw.githubusercontent.com/flathub/net.epson.epsonscan2/a489ac2f8cbd03afeda86673930cc17663c31a53/patches/0004-Fix-a-crash-on-an-OOB-container-access.patch"; hash = "sha256-WmA8pmPSJ1xUdeBbE8Jzi6w9p96aIOm0erF3T4EQ6VA="; }) (fetchpatch { url = "https://raw.githubusercontent.com/flathub/net.epson.epsonscan2/a489ac2f8cbd03afeda86673930cc17663c31a53/patches/0003-Use-XDG-open-to-open-the-directory.patch"; hash = "sha256-H3lle1SXkkpbBkozYEwiX0z9oTUubTpB+l91utxH03M="; }) ]; postPatch = '' substituteInPlace src/Controller/Src/Scanner/Engine.cpp \ --replace-fail '@KILLALL@' ${killall}/bin/killall substituteInPlace src/Controller/Src/Filter/GetOrientation.cpp \ --replace-fail '@OCR_ENGINE_GETROTATE@' $out/libexec/epsonscan2-ocr/ocr-engine-getrotate ''; nativeBuildInputs = [ cmake ] ++ lib.optionals withGui [ imagemagick # to make icons wrapQtAppsHook ] ++ lib.optionals withNonFreePlugins [ autoPatchelfHook ]; buildInputs = [ boost186 # uses Boost.Optional but epsonscan2 is pre-C++11. libjpeg libpng libtiff libusb1 ] ++ lib.optionals withGui [ copyDesktopItems qtbase ] ++ lib.optionals withNonFreePlugins [ libtool.lib ]; cmakeFlags = [ # The non-free (Debian) packages uses this directory structure so do the same when compiling # from source so we can easily merge them. "-DCMAKE_INSTALL_LIBDIR=lib/${system}-gnu" ] ++ lib.optionals (!withGui) [ "-DNO_GUI=ON" ]; postInstall = '' # But when we put all the libraries in lib/${system}-gnu, then SANE can't find the # required libraries so create a symlink to where it expects them to be. mkdir -p $out/lib/sane for file in $out/lib/${system}-gnu/sane/*.so.*; do ln -s $file $out/lib/sane/ done '' + lib.optionalString withGui '' # The icon file extension is .ico but it's actually a png! mkdir -p $out/share/icons/hicolor/{48x48,128x128}/apps magick $src/Resources/Icons/escan2_app.ico -resize 48x48 -delete 1,2,3 $out/share/icons/hicolor/48x48/apps/epsonscan2.png magick $src/Resources/Icons/escan2_app.ico -resize 128x128 -delete 1,2,3 $out/share/icons/hicolor/128x128/apps/epsonscan2.png '' + lib.optionalString withNonFreePlugins '' ar xf ${bundle}/plugins/epsonscan2-non-free-plugin_*.deb tar Jxf data.tar.xz cp -r usr/* $out ''; desktopItems = lib.optionals withGui [ (makeDesktopItem { name = pname; exec = "epsonscan2"; icon = "epsonscan2"; desktopName = "Epson Scan 2"; genericName = "Epson Scan 2"; comment = description; categories = [ "Graphics" "Scanning" ]; }) ]; meta = { inherit description; mainProgram = "epsonscan2"; longDescription = '' Epson Scan 2 scanner driver including optional non-free plugins such as OCR and network scanning. To use the SANE backend: hardware.sane.extraBackends = [ pkgs.epsonscan2 ]; Overrides can be used to customise this package. For example, to enable non-free plugins and disable the Epson GUI: pkgs.epsonscan2.override { withNonFreePlugins = true; withGui = false; } ''; homepage = "https://support.epson.net/linux/en/epsonscan2.php"; platforms = [ "x86_64-linux" ]; sourceProvenance = with lib.sourceTypes; [ fromSource ] ++ lib.optionals withNonFreePlugins [ binaryNativeCode ]; license = with lib.licenses; if withNonFreePlugins then unfree else lgpl21Plus; maintainers = with lib.maintainers; [ james-atkins ]; }; }