diff --git a/pkgs/misc/drivers/utsushi/default.nix b/pkgs/misc/drivers/utsushi/default.nix new file mode 100644 index 000000000000..328e8ce45625 --- /dev/null +++ b/pkgs/misc/drivers/utsushi/default.nix @@ -0,0 +1,154 @@ +{ stdenv, fetchurl, autoreconfHook, boost, gtkmm2 +, pkg-config, libtool, udev, libjpeg, file, texlive +, libusb, libtiff, imagemagick, sane-backends, tesseract }: + +/* +Alternatively, this package could use the "community source" at +https://gitlab.com/utsushi/utsushi/ +Epson provides proprietary plugins for networking, ocr and some more +scanner models. Those are not (yet ?) packaged here. +*/ + +stdenv.mkDerivation rec { + pname = "utsushi"; + version = "3.57.0"; + + src = fetchurl { + url = "http://support.epson.net/linux/src/scanner/imagescanv3/common/imagescan_${version}.orig.tar.gz"; + sha256 = "0qy6n6nbisbvy0q3idj7hpmj9i85cd0a18klfd8nsqsa2nkg57ny"; + }; + + nativeBuildInputs = [ + pkg-config + autoreconfHook + libtool + ]; + + buildInputs = [ + boost + libusb + libtiff + libjpeg + udev + imagemagick + sane-backends + gtkmm2 + file + tesseract + ]; + + patches = [ + ./patches/absolute-path-to-convert.patch + ./patches/print-errors.patch + ./patches/absolute_path_for_tesseract.patch + ]; + + postPatch = '' + # remove vendored dependencies + rm -r upstream/boost + # create fake udev and sane config + mkdir -p $out/etc/{sane.d,udev/rules.d} + touch $out/etc/sane.d/dll.conf + ''; + + configureFlags = [ + "--with-boost-libdir=${boost}/lib" + "--with-sane-confdir=${placeholder "out"}/etc/sane.d" + "--with-udev-confdir=${placeholder "out"}/etc/udev" + "--with-sane" + "--with-gtkmm" + "--with-jpeg" + "--with-magick" + "--with-sane" + "--with-tiff" + ]; + + installFlags = [ "SANE_BACKENDDIR=${placeholder "out"}/lib/sane" ]; + + enableParallelBuilding = true; + + meta = { + description = "SANE utsushi backend for some Epson scanners"; + longDescription = '' + ImageScanV3 (aka utsushi) scanner driver. + Non-free plugins are not included so no network support. + To use the SANE backend, in /etc/nixos/configuration.nix: + + hardware.sane = { + enable = true; + extraBackends = [ pkgs.utsushi ]; + }; + services.udev.packages = [ pkgs.utsushi ]; + + Supported hardware: + - DS-40 + - DS-70 + - DS-80W + - DS-410 + - DS-510 + - DS-520 + - DS-530 + - DS-535 + - DS-535H + - DS-560 + - DS-575W + - DS-760 + - DS-775 + - DS-780N + - DS-860 + - DS-1630 + - DS-5500 + - DS-6500 + - DS-7500 + - DS-50000 + - DS-60000 + - DS-70000 + - EP-10VA Series + - EP-808A Series + - EP-978A3 Series + - ES-50 + - ES-55R + - ES-60W + - ES-65WR + - ES-300WR + - ES-400 + - ES-500WR + - ES-8500 + - ET-2500 Series + - ET-2550 Series + - ET-4500 Series + - ET-4550 Series + - Expression 1640XL + - FF-680W + - L220/L360 Series + - L365/L366 Series + - L380 Series + - L455 Series + - L565/L566 Series + - L655 Series + - PX-M840FX + - PX-M860F + - PX-M884F + - PX-M7050 Series + - PX-M7050FX Series + - WF-4720 + - WF-6530 Series + - WF-6590 Series + - WF-8510/8590 Series + - WF-R8590 Series + - XP-220 Series + - XP-230 Series + - XP-235 Series + - XP-332 335 Series + - XP-430 Series + - XP-432 435 Series + - XP-530 Series + - XP-540 + - XP-630 Series + - XP-640 + - XP-830 Series + - XP-960 Series + ''; + license = stdenv.lib.licenses.gpl3Plus; + }; +} diff --git a/pkgs/misc/drivers/utsushi/patches/absolute-path-to-convert.patch b/pkgs/misc/drivers/utsushi/patches/absolute-path-to-convert.patch new file mode 100644 index 000000000000..2bc9422b061e --- /dev/null +++ b/pkgs/misc/drivers/utsushi/patches/absolute-path-to-convert.patch @@ -0,0 +1,166 @@ +Index: utsushi-0.57.0/configure.ac +=================================================================== +--- utsushi-0.57.0.orig/configure.ac ++++ utsushi-0.57.0/configure.ac +@@ -221,6 +221,9 @@ AS_IF([test xno != x$enable_code_coverag + [AC_MSG_ERROR([code coverage support requires a GNU C/C++ compiler])]) + ]) + AM_PROG_AR ++AC_PATH_PROG([AWK],[awk]) ++AC_DEFINE_UNQUOTED([AWK], ["$AWK"], ++ [Path to awk.]) + + PKG_PROG_PKG_CONFIG + +@@ -379,27 +382,31 @@ AM_CONDITIONAL([have_libmagick_pp], [tes + AS_IF([test xno != "x$with_magick"], + AS_CASE("x$with_magick", + [xGraphicsMagick], +- [AC_CHECK_PROGS([MAGICK_CONVERT], [gm]) +- AS_IF([test xgm != x$MAGICK_CONVERT], ++ [[AC_PATH_PROG(MAGICK_CONVERT, gm)] ++ AS_IF([test x == x$MAGICK_CONVERT], + [AC_MSG_ERROR([$with_magick requested but not found])]) + AC_DEFINE([HAVE_GRAPHICS_MAGICK], [1]) +- MAGICK_CONVERT="gm convert" ++ HAVE_MAGICK=1 ++ MAGICK_CONVERT="$MAGICK_CONVERT convert" + ], + [xImageMagick], +- [AC_CHECK_PROGS([MAGICK_CONVERT], [convert]) +- AS_IF([test xconvert != x$MAGICK_CONVERT], ++ [[AC_PATH_PROG(MAGICK_CONVERT, convert)] ++ AS_IF([test x == x$MAGICK_CONVERT], + [AC_MSG_ERROR([$with_magick requested but not found])]) + AC_DEFINE([HAVE_IMAGE_MAGICK], [1]) ++ HAVE_MAGICK=1 + ], + [xyes|xcheck], +- [AC_CHECK_PROGS([MAGICK_CONVERT], [gm convert]) ++ [[AC_PATH_PROGS([MAGICK_CONVERT], [gm convert])] + AS_CASE(x$MAGICK_CONVERT, +- [xgm], ++ [x*gm], + [AC_DEFINE([HAVE_GRAPHICS_MAGICK], [1]) +- MAGICK_CONVERT="gm convert" ++ HAVE_MAGICK=1 ++ MAGICK_CONVERT="$MAGICK_CONVERT convert" + ], +- [xconvert], ++ [x*convert], + [AC_DEFINE([HAVE_IMAGE_MAGICK], [1]) ++ HAVE_MAGICK=1 + ], + [dnl default case + AS_IF([test xcheck != "x$with_magick"], +@@ -410,7 +417,7 @@ AS_IF([test xno != "x$with_magick"], + AC_MSG_ERROR([unknown value: --with-magick=$with_magick]) + ])) + AC_DEFINE_UNQUOTED([MAGICK_CONVERT], ["$MAGICK_CONVERT"]) +-AM_CONDITIONAL([have_magick], [test x != "x$MAGICK_CONVERT"]) ++AM_CONDITIONAL([have_magick], [test x != "x$HAVE_MAGICK"]) + + AS_IF([test xno != "x$with_gtkmm"], + [PKG_CHECK_MODULES([LIBGTKMM], [gtkmm-2.4 >= 2.20], +Index: utsushi-0.57.0/filters/magick.cpp +=================================================================== +--- utsushi-0.57.0.orig/filters/magick.cpp ++++ utsushi-0.57.0/filters/magick.cpp +@@ -81,19 +81,18 @@ chomp (char *str) + } + + bool +-magick_version_before_(const char *magick, const char *cutoff) ++magick_version_before_(const char *cutoff) + { + FILE *fp = NULL; + int errc = 0; + +- if (0 == strcmp ("GraphicsMagick", magick)) +- fp = popen ("gm convert -version" +- "| awk '/^GraphicsMagick/{print $2}'", "r"); +- if (fp) errc = errno; +- +- if (0 == strcmp ("ImageMagick", magick)) +- fp = popen ("convert -version" +- "| awk '/^Version:/{print $3}'", "r"); ++#if HAVE_GRAPHICS_MAGICK ++ fp = popen (MAGICK_CONVERT " -version" ++ "| " AWK " '/^GraphicsMagick/{print $2}'", "r"); ++#elif HAVE_IMAGE_MAGICK ++ fp = popen (MAGICK_CONVERT " -version" ++ "| " AWK " '/^Version:/{print $3}'", "r"); ++#endif + if (fp) errc = errno; + + if (fp) +@@ -106,42 +105,32 @@ magick_version_before_(const char *magic + + if (version) + { +- log::debug ("found %1%-%2%") % magick % version; ++ log::debug ("found " MAGICK_CONVERT "version %1%") % version; + return (0 > strverscmp (version, cutoff)); + } + } + + if (errc) +- log::alert ("failure checking %1% version: %2%") +- % magick ++ log::alert ("failure checking " MAGICK_CONVERT " version: %1%") + % strerror (errc); + + return false; + } + + bool +-graphics_magick_version_before_(const char *cutoff) +-{ +- return magick_version_before_("GraphicsMagick", cutoff); +-} +- +-bool +-image_magick_version_before_(const char *cutoff) +-{ +- return magick_version_before_("ImageMagick", cutoff); +-} +- +-bool + auto_orient_is_usable () + { + static int usable = -1; + + if (-1 == usable) + { +- if (HAVE_GRAPHICS_MAGICK) // version -auto-orient was added +- usable = !graphics_magick_version_before_("1.3.18"); +- if (HAVE_IMAGE_MAGICK) // version known to work +- usable = !image_magick_version_before_("6.7.8-9"); ++#if HAVE_GRAPHICS_MAGICK ++ // version -auto-orient was added ++ usable = !magick_version_before_("1.3.18"); ++#elif HAVE_IMAGE_MAGICK ++ // version known to work ++ usable = !magick_version_before_("6.7.8-9"); ++#endif + if (-1 == usable) + usable = false; + usable = (usable ? 1 : 0); +@@ -392,7 +381,7 @@ magick::arguments (const context& ctx) + if (color_correction_) + { + if (HAVE_IMAGE_MAGICK +- && !image_magick_version_before_("6.6.1-0")) ++ && !magick_version_before_("6.6.1-0")) + argv += " -color-matrix"; + else + argv += " -recolor"; +@@ -416,7 +405,7 @@ magick::arguments (const context& ctx) + size_t mat_size = ((HAVE_IMAGE_MAGICK) ? 6 : 5); + + if (HAVE_IMAGE_MAGICK +- && !image_magick_version_before_("6.6.1-0")) ++ && !magick_version_before_("6.6.1-0")) + argv += " -color-matrix"; + else + argv += " -recolor"; diff --git a/pkgs/misc/drivers/utsushi/patches/absolute_path_for_tesseract.patch b/pkgs/misc/drivers/utsushi/patches/absolute_path_for_tesseract.patch new file mode 100644 index 000000000000..d4d444979210 --- /dev/null +++ b/pkgs/misc/drivers/utsushi/patches/absolute_path_for_tesseract.patch @@ -0,0 +1,56 @@ +Index: utsushi-0.57.0/filters/reorient.cpp +=================================================================== +--- utsushi-0.57.0.orig/filters/reorient.cpp ++++ utsushi-0.57.0/filters/reorient.cpp +@@ -96,8 +96,8 @@ chomp (char *str) + bool + tesseract_version_before_(const char *cutoff) + { +- FILE *fp = popen ("tesseract --version 2>&1" +- "| awk '/^tesseract/{ print $2 }'", "r"); ++ FILE *fp = popen (TESSERACT " --version 2>&1" ++ "| " AWK " '/^tesseract/{ print $2 }'", "r"); + int errc = errno; + + if (fp) +@@ -126,7 +126,7 @@ tesseract_version_before_(const char *cu + bool + have_tesseract_language_pack_(const char *lang) + { +- std::string cmd("tesseract --list-langs 2>&1" ++ std::string cmd(TESSERACT " --list-langs 2>&1" + "| sed -n '/^"); + cmd += lang; + cmd += "$/p'"; +@@ -291,7 +291,7 @@ reorient::reorient () + + if (found) + { +- if (have_tesseract_()) engine_ = "tesseract"; ++ if (have_tesseract_()) engine_ = TESSERACT; + if (have_ocr_engine_()) engine_ = abs_path_name; + } + freeze_options (); // initializes option tracking member variables +Index: utsushi-0.57.0/configure.ac +=================================================================== +--- utsushi-0.57.0.orig/configure.ac ++++ utsushi-0.57.0/configure.ac +@@ -196,6 +196,8 @@ AC_DEFINE([HAVE_IMAGE_MAGICK_PP], + [0], [Define to 1 if ImageMagick's C++ API is usable]) + AC_DEFINE([MAGICK_CONVERT], + [], [Define to an appropriate command-line invocation for convert]) ++AC_DEFINE([TESSERACT], ++ [], [Define to an appropriate command-line invocation for tesseract]) + AC_DEFINE([WITH_INCLUDED_BOOST], + [0], [Define to 1 if using the included Boost sources]) + +@@ -419,6 +421,9 @@ AS_IF([test xno != "x$with_magick"], + AC_DEFINE_UNQUOTED([MAGICK_CONVERT], ["$MAGICK_CONVERT"]) + AM_CONDITIONAL([have_magick], [test x != "x$HAVE_MAGICK"]) + ++AC_PATH_PROG([TESSERACT], [tesseract], [tesseract]) ++AC_DEFINE_UNQUOTED([TESSERACT], ["$TESSERACT"]) ++ + AS_IF([test xno != "x$with_gtkmm"], + [PKG_CHECK_MODULES([LIBGTKMM], [gtkmm-2.4 >= 2.20], + [AC_DEFINE([HAVE_LIBGTKMM], [1])], diff --git a/pkgs/misc/drivers/utsushi/patches/print-errors.patch b/pkgs/misc/drivers/utsushi/patches/print-errors.patch new file mode 100644 index 000000000000..06660ebde988 --- /dev/null +++ b/pkgs/misc/drivers/utsushi/patches/print-errors.patch @@ -0,0 +1,15 @@ +Index: utsushi-0.57.0/lib/log.cpp +=================================================================== +--- utsushi-0.57.0.orig/lib/log.cpp ++++ utsushi-0.57.0/lib/log.cpp +@@ -26,8 +26,8 @@ + + namespace utsushi { + +-log::priority log::threshold = log::FATAL; +-log::category log::matching = log::NOTHING; ++log::priority log::threshold = log::ERROR; ++log::category log::matching = log::ALL; + + template<> + std::basic_ostream< char >& diff --git a/pkgs/misc/drivers/utsushi/patches/series b/pkgs/misc/drivers/utsushi/patches/series new file mode 100644 index 000000000000..de0964c758b1 --- /dev/null +++ b/pkgs/misc/drivers/utsushi/patches/series @@ -0,0 +1,3 @@ +absolute-path-to-convert.patch +print-errors.patch +absolute_path_for_tesseract.patch diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 117e2a6acdd8..c560fa67271b 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -23714,6 +23714,8 @@ in epkowa = callPackage ../misc/drivers/epkowa { }; + utsushi = callPackage ../misc/drivers/utsushi { }; + idsk = callPackage ../tools/filesystems/idsk { }; igraph = callPackage ../development/libraries/igraph { };